From a166203a06c3e74096a9bc39000c4ee1615f85b8 Mon Sep 17 00:00:00 2001 From: Aztec Bot <49558828+AztecBot@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:33:14 -0400 Subject: [PATCH] feat: Sync from noir (#9332) Automated pull of development from the [noir](https://github.com/noir-lang/noir) programming language, a dependency of Aztec. BEGIN_COMMIT_OVERRIDE feat(ssa): Various mem2reg reverts to reduce memory and compilation time (https://github.com/noir-lang/noir/pull/6307) chore: update `noir-edwards` repo to point at `noir-lang` org (https://github.com/noir-lang/noir/pull/6323) feat: Sha256 refactoring and benchmark with longer input (https://github.com/noir-lang/noir/pull/6318) chore: Release Noir(0.36.0) (https://github.com/noir-lang/noir/pull/6213) chore: remove usage of slices in pedersen hash (https://github.com/noir-lang/noir/pull/6295) chore: remove dead function (https://github.com/noir-lang/noir/pull/6308) feat: new formatter (https://github.com/noir-lang/noir/pull/6300) feat: Sync from aztec-packages (https://github.com/noir-lang/noir/pull/6301) fix: Allow array map on empty arrays (https://github.com/noir-lang/noir/pull/6305) fix: Display function name and body when inlining recursion limit hit (https://github.com/noir-lang/noir/pull/6291) feat(interpreter): Comptime derive generators (https://github.com/noir-lang/noir/pull/6303) fix: enforce correctness of decompositions performed at compile time (https://github.com/noir-lang/noir/pull/6278) feat: Warn about private types leaking in public functions and struct fields (https://github.com/noir-lang/noir/pull/6296) chore(docs): refactoring guides and some other nits (https://github.com/noir-lang/noir/pull/6175) fix: Do not warn on unused self in traits (https://github.com/noir-lang/noir/pull/6298) fix: Reject invalid expression with in CLI parser (https://github.com/noir-lang/noir/pull/6287) END_COMMIT_OVERRIDE --------- Co-authored-by: Tom French --- .noir-sync-commit | 2 +- avm-transpiler/Cargo.lock | 20 +- .../aztec-nr/address-note/src/address_note.nr | 36 +- noir-projects/aztec-nr/authwit/src/account.nr | 13 +- noir-projects/aztec-nr/authwit/src/auth.nr | 120 +- .../aztec-nr/authwit/src/cheatcodes.nr | 29 +- .../aztec-nr/authwit/src/entrypoint/app.nr | 10 +- .../aztec-nr/authwit/src/entrypoint/fee.nr | 12 +- .../authwit/src/entrypoint/function_call.nr | 20 +- .../aztec/src/context/call_interfaces.nr | 160 +- .../aztec-nr/aztec/src/context/gas.nr | 4 +- .../context/inputs/private_context_inputs.nr | 9 +- .../aztec-nr/aztec/src/context/mod.nr | 6 +- .../aztec/src/context/packed_returns.nr | 11 +- .../aztec/src/context/private_context.nr | 205 +- .../aztec/src/context/public_context.nr | 58 +- .../src/context/unconstrained_context.nr | 13 +- noir-projects/aztec-nr/aztec/src/deploy.nr | 18 +- .../encrypted_event_emission.nr | 76 +- .../encrypted_logs/encrypted_note_emission.nr | 55 +- .../aztec/src/encrypted_logs/header.nr | 19 +- .../aztec/src/encrypted_logs/payload.nr | 145 +- .../aztec-nr/aztec/src/generators.nr | 36 +- noir-projects/aztec-nr/aztec/src/hash.nr | 39 +- .../aztec/src/history/contract_inclusion.nr | 8 +- .../aztec/src/history/note_inclusion.nr | 18 +- .../aztec/src/history/note_validity.nr | 17 +- .../aztec/src/history/nullifier_inclusion.nr | 43 +- .../src/history/nullifier_non_inclusion.nr | 37 +- .../aztec/src/history/public_storage.nr | 71 +- .../aztec-nr/aztec/src/initializer.nr | 25 +- .../aztec-nr/aztec/src/keys/constants.nr | 7 +- .../aztec-nr/aztec/src/keys/getters/mod.nr | 15 +- .../aztec-nr/aztec/src/keys/getters/test.nr | 4 +- .../aztec/src/keys/point_to_symmetric_key.nr | 14 +- .../aztec-nr/aztec/src/macros/dispatch/mod.nr | 51 +- .../aztec/src/macros/functions/interfaces.nr | 29 +- .../aztec/src/macros/functions/mod.nr | 44 +- .../aztec-nr/aztec/src/macros/mod.nr | 32 +- .../aztec-nr/aztec/src/macros/notes/mod.nr | 179 +- .../aztec-nr/aztec/src/macros/storage/mod.nr | 43 +- .../aztec-nr/aztec/src/macros/utils.nr | 84 +- noir-projects/aztec-nr/aztec/src/messaging.nr | 15 +- .../aztec-nr/aztec/src/note/lifecycle.nr | 36 +- .../aztec-nr/aztec/src/note/note_emission.nr | 2 +- .../aztec-nr/aztec/src/note/note_field.nr | 2 +- .../aztec/src/note/note_getter/mod.nr | 101 +- .../aztec/src/note/note_getter/test.nr | 55 +- .../aztec/src/note/note_getter_options.nr | 43 +- .../aztec-nr/aztec/src/note/note_header.nr | 12 +- .../aztec-nr/aztec/src/note/note_interface.nr | 2 +- .../aztec-nr/aztec/src/note/note_type_id.nr | 1 + .../aztec/src/note/note_viewer_options.nr | 14 +- .../aztec-nr/aztec/src/note/utils.nr | 43 +- .../aztec-nr/aztec/src/oracle/arguments.nr | 8 +- .../aztec/src/oracle/call_private_function.nr | 10 +- .../oracle/enqueue_public_function_call.nr | 18 +- .../aztec/src/oracle/get_contract_instance.nr | 23 +- .../oracle/get_l1_to_l2_membership_witness.nr | 11 +- .../src/oracle/get_membership_witness.nr | 12 +- .../get_nullifier_membership_witness.nr | 20 +- .../src/oracle/get_public_data_witness.nr | 21 +- .../aztec/src/oracle/get_sibling_path.nr | 8 +- .../aztec-nr/aztec/src/oracle/header.nr | 27 +- .../src/oracle/key_validation_request.nr | 10 +- .../aztec-nr/aztec/src/oracle/keys.nr | 18 +- .../aztec-nr/aztec/src/oracle/logs.nr | 44 +- .../aztec-nr/aztec/src/oracle/notes.nr | 49 +- .../aztec-nr/aztec/src/oracle/returns.nr | 4 +- .../aztec-nr/aztec/src/oracle/storage.nr | 18 +- noir-projects/aztec-nr/aztec/src/prelude.nr | 19 +- .../aztec-nr/aztec/src/state_vars/map.nr | 7 +- .../aztec/src/state_vars/private_immutable.nr | 26 +- .../aztec/src/state_vars/private_mutable.nr | 28 +- .../src/state_vars/private_mutable/test.nr | 13 +- .../aztec/src/state_vars/private_set.nr | 30 +- .../aztec/src/state_vars/public_immutable.nr | 16 +- .../aztec/src/state_vars/public_mutable.nr | 12 +- .../aztec/src/state_vars/shared_immutable.nr | 36 +- .../shared_mutable/scheduled_delay_change.nr | 11 +- .../scheduled_delay_change/test.nr | 86 +- .../shared_mutable/scheduled_value_change.nr | 25 +- .../scheduled_value_change/test.nr | 39 +- .../shared_mutable/shared_mutable.nr | 71 +- .../src/state_vars/shared_mutable/test.nr | 90 +- .../aztec-nr/aztec/src/state_vars/storage.nr | 5 +- .../aztec/src/test/helpers/cheatcodes.nr | 36 +- .../src/test/helpers/test_environment.nr | 46 +- .../aztec-nr/aztec/src/test/helpers/utils.nr | 80 +- .../aztec/src/test/mocks/mock_note.nr | 29 +- .../unencrypted_event_emission.nr | 28 +- .../aztec/src/utils/collapse_array.nr | 39 +- .../aztec-nr/aztec/src/utils/comparison.nr | 34 +- .../aztec-nr/aztec/src/utils/point.nr | 13 +- .../aztec-nr/aztec/src/utils/test.nr | 6 +- .../src/compressed_string.nr | 12 +- .../src/field_compressed_string.nr | 4 +- .../src/easy_private_uint.nr | 34 +- .../aztec-nr/uint-note/src/uint_note.nr | 20 +- .../aztec-nr/value-note/src/balance_utils.nr | 7 +- .../aztec-nr/value-note/src/filter.nr | 2 +- .../aztec-nr/value-note/src/utils.nr | 29 +- .../aztec-nr/value-note/src/value_note.nr | 38 +- .../crates/app-reader/src/main.nr | 4 +- .../mock-private-kernel-init/src/main.nr | 6 +- .../mock-private-kernel-inner/src/main.nr | 5 +- .../mock-private-kernel-reset/src/main.nr | 9 +- .../mock-private-kernel-tail/src/main.nr | 8 +- .../crates/mock-public-kernel/src/main.nr | 14 +- .../crates/mock-types/src/lib.nr | 17 +- .../src/dapp_payload.nr | 10 +- .../app_subscription_contract/src/main.nr | 46 +- .../src/subscription_note.nr | 34 +- .../contracts/auth_contract/src/main.nr | 5 +- .../contracts/auth_contract/src/test/main.nr | 21 +- .../contracts/auth_contract/src/test/utils.nr | 3 +- .../auth_registry_contract/src/main.nr | 23 +- .../auth_wit_test_contract/src/main.nr | 6 +- .../avm_initializer_test_contract/src/main.nr | 4 +- .../contracts/avm_test_contract/src/main.nr | 57 +- .../contracts/card_game_contract/src/cards.nr | 29 +- .../contracts/card_game_contract/src/game.nr | 14 +- .../contracts/card_game_contract/src/main.nr | 36 +- .../contracts/child_contract/src/main.nr | 11 +- .../contracts/claim_contract/src/main.nr | 17 +- .../src/capsule.nr | 2 +- .../src/events/class_registered.nr | 5 +- .../events/private_function_broadcasted.nr | 33 +- .../unconstrained_function_broadcasted.nr | 26 +- .../src/main.nr | 106 +- .../src/main.nr | 17 +- .../contracts/counter_contract/src/main.nr | 16 +- .../crowdfunding_contract/src/main.nr | 26 +- .../docs_example_contract/src/main.nr | 115 +- .../docs_example_contract/src/options.nr | 33 +- .../src/types/card_note.nr | 28 +- .../easy_private_token_contract/src/main.nr | 2 +- .../easy_private_voting_contract/src/main.nr | 6 +- .../ecdsa_k_account_contract/src/main.nr | 26 +- .../ecdsa_r_account_contract/src/main.nr | 26 +- .../contracts/escrow_contract/src/main.nr | 10 +- .../contracts/fee_juice_contract/src/main.nr | 11 +- .../contracts/fpc_contract/src/lib.nr | 5 +- .../contracts/fpc_contract/src/main.nr | 39 +- .../import_test_contract/src/main.nr | 34 +- .../inclusion_proofs_contract/src/main.nr | 44 +- .../contracts/lending_contract/src/asset.nr | 2 +- .../contracts/lending_contract/src/helpers.nr | 4 +- .../contracts/lending_contract/src/main.nr | 104 +- .../lending_contract/src/position.nr | 6 +- .../contracts/nft_contract/src/main.nr | 69 +- .../nft_contract/src/test/access_control.nr | 3 +- .../nft_contract/src/test/minting.nr | 5 +- .../src/test/transfer_in_private.nr | 66 +- .../src/test/transfer_in_public.nr | 57 +- .../src/test/transfer_to_private.nr | 59 +- .../src/test/transfer_to_public.nr | 63 +- .../contracts/nft_contract/src/test/utils.nr | 57 +- .../nft_contract/src/types/nft_note.nr | 30 +- .../contracts/parent_contract/src/main.nr | 174 +- .../pending_note_hashes_contract/src/main.nr | 163 +- .../private_fpc_contract/src/main.nr | 6 +- .../private_fpc_contract/src/settings.nr | 5 +- .../contracts/router_contract/src/main.nr | 8 +- .../contracts/router_contract/src/test.nr | 2 +- .../contracts/router_contract/src/utils.nr | 2 +- .../schnorr_account_contract/src/main.nr | 36 +- .../src/public_key_note.nr | 25 +- .../src/main.nr | 10 +- .../src/auth_oracle.nr | 6 +- .../src/main.nr | 6 +- .../src/util.nr | 2 +- .../contracts/spam_contract/src/main.nr | 46 +- .../spam_contract/src/types/balance_set.nr | 49 +- .../spam_contract/src/types/token_note.nr | 26 +- .../stateful_test_contract/src/main.nr | 10 +- .../static_child_contract/src/main.nr | 36 +- .../static_parent_contract/src/main.nr | 71 +- .../contracts/test_contract/src/main.nr | 185 +- .../contracts/test_contract/src/test_note.nr | 8 +- .../contracts/test_log_contract/src/main.nr | 68 +- .../token_blacklist_contract/src/main.nr | 68 +- .../src/types/balances_map.nr | 50 +- .../src/types/roles.nr | 6 +- .../src/types/token_note.nr | 31 +- .../src/types/transparent_note.nr | 13 +- .../token_bridge_contract/src/main.nr | 30 +- .../contracts/token_contract/src/main.nr | 160 +- .../token_contract/src/test/access_control.nr | 3 +- .../contracts/token_contract/src/test/burn.nr | 70 +- .../token_contract/src/test/minting.nr | 77 +- .../src/test/reading_constants.nr | 4 +- .../token_contract/src/test/refunds.nr | 50 +- .../token_contract/src/test/shielding.nr | 67 +- .../src/test/transfer_private.nr | 77 +- .../src/test/transfer_public.nr | 79 +- .../token_contract/src/test/unshielding.nr | 63 +- .../token_contract/src/test/utils.nr | 28 +- .../token_contract/src/types/balance_set.nr | 48 +- .../token_contract/src/types/token_note.nr | 26 +- .../src/types/transparent_note.nr | 16 +- .../contracts/uniswap_contract/src/main.nr | 108 +- .../contracts/uniswap_contract/src/util.nr | 27 +- .../parity-lib/src/base/base_parity_inputs.nr | 4 +- .../parity-lib/src/parity_public_inputs.nr | 8 +- .../parity-lib/src/root/root_parity_input.nr | 13 +- .../parity-lib/src/root/root_parity_inputs.nr | 47 +- .../src/root/root_rollup_parity_input.nr | 14 +- .../src/utils/sha256_merkle_tree.nr | 16 +- .../private-kernel-init-simulated/src/main.nr | 4 +- .../crates/private-kernel-init/src/main.nr | 4 +- .../src/main.nr | 4 +- .../crates/private-kernel-inner/src/main.nr | 4 +- .../components/previous_kernel_validator.nr | 102 +- .../previous_kernel_validator_hints.nr | 11 +- .../components/private_call_data_validator.nr | 196 +- .../find_first_revertible_item_index.nr | 11 +- .../validate_contract_address.nr | 21 +- .../validate_split_ranges.nr | 24 +- ...private_kernel_circuit_output_validator.nr | 146 +- ...e_kernel_circuit_public_inputs_composer.nr | 112 +- .../src/components/reset_output_composer.nr | 67 +- .../reset_output_hints.nr | 37 +- ...r_propagated_note_hash_indexes_for_logs.nr | 11 +- .../squash_transient_data.nr | 13 +- .../src/components/reset_output_validator.nr | 141 +- .../src/components/tail_output_composer.nr | 47 +- .../tail_output_composer/meter_gas_used.nr | 12 +- .../src/components/tail_output_validator.nr | 45 +- .../tail_output_hints.nr | 18 +- .../tail_to_public_output_composer.nr | 20 +- .../meter_gas_used.nr | 16 +- .../split_to_public.nr | 8 +- .../tail_to_public_output_validator.nr | 70 +- .../tail_to_public_output_hints.nr | 26 +- .../src/private_kernel_empty.nr | 13 +- .../src/private_kernel_init.nr | 49 +- .../src/private_kernel_inner.nr | 82 +- .../src/private_kernel_reset.nr | 218 +- .../src/private_kernel_tail.nr | 112 +- .../src/private_kernel_tail_to_public.nr | 152 +- .../previous_kernel_validator_builder/mod.nr | 2 +- .../mod.nr | 11 +- .../validate_against_previous_kernel.nr | 13 +- .../validate_arrays.nr | 4 +- .../validate_call_requests.nr | 6 +- .../validate_contract_address.nr | 9 +- .../validate_counters.nr | 21 +- .../validate_private_call_requests.nr | 9 +- .../mod.nr | 37 +- .../validate_propagated_from_private_call.nr | 15 +- .../mod.nr | 23 +- ..._from_previous_kernel_with_private_call.nr | 22 +- .../new_from_tx_request.nr | 7 +- .../propagate_from_private_call.nr | 12 +- .../reset_output_validator_builder/mod.nr | 35 +- .../validate_sorted_siloed_note_hashes.nr | 3 +- .../validate_sorted_siloed_nullifiers.nr | 3 +- .../meter_gas_used.nr | 13 +- .../tests/tail_output_composer_builder/mod.nr | 5 +- .../tail_output_validator_builder/mod.nr | 6 +- .../validate_propagated_values.nr | 6 +- .../meter_gas_used.nr | 31 +- .../mod.nr | 2 +- .../split_to_public.nr | 8 +- .../tail_to_public_output_composer.nr | 41 +- ...tail_to_public_output_validator_builder.nr | 4 +- .../src/main.nr | 21 +- .../crates/private-kernel-reset/src/main.nr | 21 +- .../private-kernel-tail-simulated/src/main.nr | 5 +- .../src/main.nr | 7 +- .../private-kernel-tail-to-public/src/main.nr | 7 +- .../crates/private-kernel-tail/src/main.nr | 5 +- .../enqueued_call_data_validator.nr | 68 +- .../components/previous_kernel_validator.nr | 29 +- .../public_kernel_output_composer.nr | 34 +- .../propagate_accumulated_data.nr | 15 +- .../public_kernel_output_validator.nr | 132 +- .../components/public_tail_output_composer.nr | 35 +- .../combine_data.nr | 61 +- .../generate_output_hints.nr | 63 +- ...generate_overridable_public_data_writes.nr | 14 +- .../generate_public_data_leaves.nr | 29 +- .../public_tail_output_validator.nr | 94 +- .../validate_linked_public_data_writes.nr | 142 +- .../validate_public_data_leaf_memberships.nr | 9 +- .../validate_unique_leaf_slots.nr | 16 +- .../components/vm_circuit_output_composer.nr | 58 +- .../propagate_accumulated_data.nr | 49 +- .../src/public_kernel_inner.nr | 12 +- .../src/public_kernel_merge.nr | 96 +- .../src/public_kernel_phase.nr | 7 +- .../src/public_kernel_tail.nr | 272 +- .../public-kernel-merge-simulated/src/main.nr | 4 +- .../public-kernel-tail-simulated/src/main.nr | 4 +- .../crates/reset-kernel-lib/src/lib.nr | 2 +- .../src/note_hash_read_request_reset.nr | 90 +- ...llifier_non_existent_read_request_reset.nr | 5 +- .../src/nullifier_read_request_reset.nr | 114 +- .../private_validation_request_processor.nr | 49 +- .../src/public_data_read_request_hints.nr | 21 +- .../public_validation_request_processor.nr | 70 +- .../src/reset/key_validation_hint.nr | 43 +- .../src/reset/mutable_data_read_request.nr | 176 +- .../src/reset/non_existent_read_request.nr | 116 +- .../src/reset/read_request.nr | 159 +- .../src/reset/transient_data.nr | 140 +- .../src/reset/tree_leaf_read_request.nr | 8 +- .../note_hash_read_request_hints_builder.nr | 24 +- ...non_existent_read_request_hints_builder.nr | 35 +- .../nullifier_read_request_hints_builder.nr | 24 +- .../base_or_merge_rollup_public_inputs.nr | 22 +- ...block_root_or_block_merge_public_inputs.nr | 47 +- .../src/abis/constant_rollup_data.nr | 6 +- .../src/abis/previous_rollup_block_data.nr | 22 +- .../src/abis/previous_rollup_data.nr | 31 +- .../rollup-lib/src/base/base_rollup_inputs.nr | 806 ++-- .../rollup-lib/src/base/state_diff_hints.nr | 10 +- .../block_merge/block_merge_rollup_inputs.nr | 79 +- .../block_root/block_root_rollup_inputs.nr | 47 +- .../empty_block_root_rollup_inputs.nr | 6 +- .../crates/rollup-lib/src/block_root/mod.nr | 18 +- .../crates/rollup-lib/src/components.nr | 177 +- .../src/merge/merge_rollup_inputs.nr | 83 +- .../crates/rollup-lib/src/root/mod.nr | 39 +- .../rollup-lib/src/root/root_rollup_inputs.nr | 19 +- .../src/tests/block_root_rollup_inputs.nr | 19 +- .../rollup-lib/src/tests/l1_to_l2_roots.nr | 7 +- .../src/tests/previous_rollup_block_data.nr | 53 +- .../src/tests/previous_rollup_data.nr | 95 +- .../combined_accumulated_data.nr | 48 +- .../private_accumulated_data.nr | 33 +- .../private_accumulated_data_builder.nr | 24 +- .../public_accumulated_data.nr | 59 +- .../public_accumulated_data_builder.nr | 24 +- .../src/abis/append_only_tree_snapshot.nr | 13 +- .../crates/types/src/abis/call_context.nr | 8 +- .../types/src/abis/combined_constant_data.nr | 8 +- .../contract_class_function_leaf_preimage.nr | 11 +- .../types/src/abis/enqueued_call_data.nr | 2 +- .../crates/types/src/abis/function_data.nr | 16 +- .../types/src/abis/function_selector.nr | 3 +- .../crates/types/src/abis/gas.nr | 2 +- .../crates/types/src/abis/gas_settings.nr | 13 +- .../crates/types/src/abis/global_variables.nr | 25 +- .../kernel_circuit_public_inputs.nr | 28 +- .../abis/kernel_circuit_public_inputs/mod.nr | 4 +- .../private_kernel_circuit_public_inputs.nr | 47 +- ...te_kernel_circuit_public_inputs_builder.nr | 17 +- .../public_kernel_circuit_public_inputs.nr | 20 +- ...ic_kernel_circuit_public_inputs_builder.nr | 17 +- .../vm_circuit_public_inputs.nr | 49 +- .../crates/types/src/abis/kernel_data.nr | 22 +- .../crates/types/src/abis/log_hash.nr | 54 +- .../crates/types/src/abis/max_block_number.nr | 6 +- .../crates/types/src/abis/note_hash.nr | 17 +- .../types/src/abis/note_hash_leaf_preimage.nr | 13 +- .../crates/types/src/abis/nullifier.nr | 29 +- .../types/src/abis/nullifier_leaf_preimage.nr | 17 +- .../types/src/abis/private_call_request.nr | 6 +- .../src/abis/private_circuit_public_inputs.nr | 117 +- .../abis/private_kernel/private_call_data.nr | 15 +- .../types/src/abis/private_kernel_data.nr | 16 +- .../types/src/abis/public_call_request.nr | 4 +- .../abis/public_call_stack_item_compressed.nr | 11 +- .../src/abis/public_circuit_public_inputs.nr | 75 +- .../crates/types/src/abis/public_data_read.nr | 9 +- .../src/abis/public_data_update_request.nr | 30 +- .../types/src/abis/public_data_write.nr | 15 +- .../src/abis/public_inner_call_request.nr | 7 +- .../types/src/abis/public_kernel_data.nr | 22 +- .../src/abis/public_kernel_inner_data.nr | 4 +- .../crates/types/src/abis/read_request.nr | 11 +- .../crates/types/src/abis/side_effect.nr | 12 +- .../key_validation_request.nr | 12 +- .../key_validation_request_and_generator.nr | 19 +- .../private_validation_requests.nr | 55 +- .../private_validation_requests_builder.nr | 29 +- .../public_validation_requests.nr | 71 +- .../public_validation_requests_builder.nr | 33 +- .../rollup_validation_requests.nr | 2 +- ...ed_key_validation_request_and_generator.nr | 13 +- .../crates/types/src/address/aztec_address.nr | 34 +- .../crates/types/src/address/eth_address.nr | 4 +- .../types/src/address/partial_address.nr | 23 +- .../types/src/address/public_keys_hash.nr | 2 +- .../src/address/salted_initialization_hash.nr | 20 +- .../crates/types/src/constants.nr | 279 +- .../crates/types/src/content_commitment.nr | 8 +- .../crates/types/src/contract_class_id.nr | 13 +- .../crates/types/src/contract_instance.nr | 30 +- .../crates/types/src/contrakt/storage_read.nr | 6 +- .../src/contrakt/storage_update_request.nr | 16 +- .../crates/types/src/data/hash.nr | 12 +- .../crates/types/src/data/public_data_hint.nr | 9 +- .../types/src/data/public_data_leaf_hint.nr | 7 +- .../types/src/data/public_data_tree_leaf.nr | 12 +- .../data/public_data_tree_leaf_preimage.nr | 13 +- .../crates/types/src/debug_log.nr | 9 +- .../crates/types/src/hash.nr | 136 +- .../crates/types/src/header.nr | 30 +- .../crates/types/src/lib.nr | 2 +- .../types/src/merkle_tree/append_only_tree.nr | 18 +- .../types/src/merkle_tree/indexed_tree.nr | 48 +- .../indexed_tree/check_valid_low_leaf.nr | 14 +- .../types/src/merkle_tree/membership.nr | 99 +- .../types/src/merkle_tree/merkle_tree.nr | 16 +- .../crates/types/src/merkle_tree/mod.nr | 2 +- .../crates/types/src/merkle_tree/root.nr | 2 +- .../src/merkle_tree/variable_merkle_tree.nr | 26 +- .../types/src/messaging/l2_to_l1_message.nr | 23 +- .../crates/types/src/meta/mod.nr | 72 +- .../types/src/partial_state_reference.nr | 10 +- .../crates/types/src/public_keys.nr | 64 +- .../crates/types/src/recursion/proof.nr | 2 +- .../crates/types/src/recursion/traits.nr | 2 +- .../types/src/recursion/verification_key.nr | 6 +- .../crates/types/src/state_reference.nr | 19 +- .../crates/types/src/storage/map.nr | 12 +- .../crates/types/src/tests/fixture_builder.nr | 455 +- .../src/tests/fixtures/contract_functions.nr | 21 +- .../types/src/tests/fixtures/contracts.nr | 73 +- .../tests/fixtures/protocol_contract_tree.nr | 2 +- .../types/src/tests/fixtures/vk_tree.nr | 55 +- .../types/src/tests/merkle_tree_utils.nr | 56 +- .../crates/types/src/tests/utils.nr | 5 +- .../crates/types/src/traits.nr | 12 +- .../types/src/transaction/tx_context.nr | 8 +- .../types/src/transaction/tx_request.nr | 25 +- .../crates/types/src/type_serialization.nr | 10 +- .../crates/types/src/utils/arrays.nr | 65 +- .../src/utils/arrays/assert_array_appended.nr | 47 +- .../utils/arrays/assert_array_prepended.nr | 9 +- .../src/utils/arrays/assert_combined_array.nr | 60 +- ...combined_sorted_transformed_value_array.nr | 154 +- .../get_combined_order_hints.nr | 130 +- .../assert_combined_transformed_array.nr | 59 +- .../src/utils/arrays/assert_deduped_array.nr | 33 +- ..._exposed_sorted_transformed_value_array.nr | 40 +- .../get_order_hints.nr | 56 +- .../src/utils/arrays/assert_sorted_array.nr | 7 +- .../assert_sorted_transformed_value_array.nr | 40 +- ...t_split_sorted_transformed_value_arrays.nr | 127 +- .../get_split_order_hints.nr | 84 +- .../assert_split_transformed_value_arrays.nr | 48 +- .../src/utils/arrays/get_sorted_result.nr | 22 +- .../src/utils/arrays/get_sorted_tuple.nr | 18 +- .../crates/types/src/utils/arrays/sort_by.nr | 19 +- .../types/src/utils/arrays/sort_by_counter.nr | 54 +- .../crates/types/src/utils/field.nr | 6 +- .../crates/types/src/utils/mod.nr | 12 +- .../crates/types/src/utils/reader.nr | 6 +- .../crates/types/src/utils/uint256.nr | 23 +- .../crates/types/src/validate.nr | 2 +- noir/bb-version | 2 +- noir/noir-repo/.github/workflows/docs-pr.yml | 2 +- .../.github/workflows/test-js-packages.yml | 2 +- noir/noir-repo/.release-please-manifest.json | 4 +- noir/noir-repo/CHANGELOG.md | 89 + noir/noir-repo/Cargo.lock | 64 +- noir/noir-repo/Cargo.toml | 16 +- noir/noir-repo/acvm-repo/CHANGELOG.md | 115 + noir/noir-repo/acvm-repo/acir/Cargo.toml | 2 +- .../noir-repo/acvm-repo/acir_field/Cargo.toml | 2 +- noir/noir-repo/acvm-repo/acvm/Cargo.toml | 2 +- noir/noir-repo/acvm-repo/acvm_js/Cargo.toml | 2 +- noir/noir-repo/acvm-repo/acvm_js/package.json | 2 +- .../acvm-repo/blackbox_solver/Cargo.toml | 2 +- .../bn254_blackbox_solver/Cargo.toml | 2 +- noir/noir-repo/acvm-repo/brillig/Cargo.toml | 2 +- .../noir-repo/acvm-repo/brillig_vm/Cargo.toml | 2 +- .../src/brillig/brillig_ir/entry_point.rs | 2 +- .../src/ssa/ir/instruction/call.rs | 32 +- .../noirc_evaluator/src/ssa/opt/inlining.rs | 29 +- .../noirc_evaluator/src/ssa/opt/mem2reg.rs | 991 +--- .../noirc_evaluator/src/ssa/opt/unrolling.rs | 29 - .../compiler/noirc_frontend/src/ast/mod.rs | 15 +- .../noirc_frontend/src/elaborator/mod.rs | 110 +- .../src/hir/comptime/display.rs | 1 + .../noirc_frontend/src/hir/comptime/errors.rs | 11 +- .../src/hir/comptime/hir_to_display_ast.rs | 8 +- .../src/hir/comptime/interpreter/builtin.rs | 56 + .../noirc_frontend/src/lexer/lexer.rs | 6 +- .../noirc_frontend/src/lexer/token.rs | 34 +- .../src/parser/parser/generics.rs | 2 + .../noirc_frontend/src/tests/unused_items.rs | 20 + .../noirc_frontend/src/tests/visibility.rs | 203 +- noir/noir-repo/compiler/wasm/package.json | 2 +- noir/noir-repo/cspell.json | 4 + noir/noir-repo/docs/.gitignore | 1 + noir/noir-repo/docs/.markdownlint.json | 3 - noir/noir-repo/docs/README.md | 8 +- .../docs/getting_started/backend/index.md | 31 - .../docs/getting_started/hello_noir/index.md | 157 - .../getting_started/installation/index.md | 46 - ...nstall_methods.md => noir_installation.md} | 10 +- .../{hello_noir => }/project_breakdown.md | 8 +- .../docs/docs/getting_started/quick_start.md | 124 + .../docs/docs/how_to/how-to-oracles.md | 2 +- .../docs/how_to/how-to-solidity-verifier.md | 8 +- .../docs/noir/concepts/data_types/arrays.md | 2 + .../docs/docs/reference/noir_codegen.md | 6 +- noir/noir-repo/docs/docs/tooling/debugger.md | 2 +- .../docs/docs/tutorials/noirjs_app.md | 12 +- noir/noir-repo/docs/docusaurus.config.ts | 6 +- noir/noir-repo/docs/package.json | 12 +- noir/noir-repo/docs/src/pages/index.jsx | 2 +- .../version-v0.36.0/explainers/cspell.json | 5 + .../explainers/explainer-oracle.md | 57 + .../explainers/explainer-recursion.md | 176 + .../explainers/explainer-writing-noir.md | 177 + .../getting_started/noir_installation.md | 102 + .../getting_started/project_breakdown.md | 159 + .../getting_started/quick_start.md | 124 + .../how_to/debugger/_category_.json | 6 + .../debugger/debugging_with_the_repl.md | 164 + .../how_to/debugger/debugging_with_vs_code.md | 68 + .../version-v0.36.0/how_to/how-to-oracles.md | 273 ++ .../how_to/how-to-recursion.md | 180 + .../how_to/how-to-solidity-verifier.md | 259 ++ .../version-v0.36.0/how_to/merkle-proof.mdx | 48 + .../how_to/using-devcontainers.mdx | 110 + .../versioned_docs/version-v0.36.0/index.mdx | 67 + .../version-v0.36.0/migration_notes.md | 105 + .../noir/concepts}/_category_.json | 4 +- .../version-v0.36.0/noir/concepts/assert.md | 78 + .../version-v0.36.0/noir/concepts/comments.md | 33 + .../version-v0.36.0/noir/concepts/comptime.md | 445 ++ .../noir/concepts/control_flow.md | 79 + .../noir/concepts/data_bus.mdx | 23 + .../noir/concepts/data_types/arrays.md | 276 ++ .../noir/concepts/data_types/booleans.md | 28 + .../noir/concepts/data_types/fields.md | 246 + .../concepts/data_types/function_types.md | 26 + .../noir/concepts/data_types/index.md | 126 + .../noir/concepts/data_types/integers.md | 156 + .../noir/concepts/data_types/references.md | 23 + .../noir/concepts/data_types/slices.mdx | 358 ++ .../noir/concepts/data_types/strings.md | 79 + .../noir/concepts/data_types/structs.md | 96 + .../noir/concepts/data_types/tuples.md | 48 + .../noir/concepts/functions.md | 226 + .../version-v0.36.0/noir/concepts/generics.md | 251 + .../version-v0.36.0/noir/concepts/globals.md | 82 + .../version-v0.36.0/noir/concepts/lambdas.md | 81 + .../noir/concepts/mutability.md | 121 + .../version-v0.36.0/noir/concepts/ops.md | 98 + .../version-v0.36.0/noir/concepts/oracles.mdx | 29 + .../noir/concepts/shadowing.md | 44 + .../version-v0.36.0/noir/concepts/traits.md | 501 ++ .../noir/concepts/unconstrained.md | 104 + .../modules_packages_crates}/_category_.json | 1 + .../crates_and_packages.md | 43 + .../modules_packages_crates/dependencies.md | 124 + .../noir/modules_packages_crates/modules.md | 221 + .../modules_packages_crates/workspaces.md | 42 + .../noir/standard_library/bigint.md | 127 + .../noir/standard_library/black_box_fns.md | 32 + .../noir/standard_library/bn254.md | 46 + .../standard_library/containers/boundedvec.md | 419 ++ .../standard_library/containers/hashmap.md | 587 +++ .../noir/standard_library/containers/index.md | 5 + .../noir/standard_library/containers/vec.mdx | 170 + .../cryptographic_primitives/ciphers.mdx | 32 + .../cryptographic_primitives/ec_primitives.md | 102 + .../ecdsa_sig_verification.mdx | 98 + .../cryptographic_primitives/eddsa.mdx | 37 + .../embedded_curve_ops.mdx | 95 + .../cryptographic_primitives/hashes.mdx | 253 + .../cryptographic_primitives/index.md | 14 + .../cryptographic_primitives/schnorr.mdx | 64 + .../noir/standard_library/fmtstr.md | 17 + .../noir/standard_library/is_unconstrained.md | 69 + .../noir/standard_library/logging.md | 78 + .../noir/standard_library/mem.md | 52 + .../noir/standard_library/merkle_trees.md | 58 + .../noir/standard_library/meta/ctstring.md | 100 + .../noir/standard_library/meta/expr.md | 380 ++ .../standard_library/meta/function_def.md | 166 + .../noir/standard_library/meta/index.md | 224 + .../noir/standard_library/meta/module.md | 82 + .../noir/standard_library/meta/op.md | 244 + .../noir/standard_library/meta/quoted.md | 141 + .../noir/standard_library/meta/struct_def.md | 177 + .../standard_library/meta/trait_constraint.md | 17 + .../noir/standard_library/meta/trait_def.md | 26 + .../noir/standard_library/meta/trait_impl.md | 60 + .../noir/standard_library/meta/typ.md | 264 ++ .../noir/standard_library/meta/typed_expr.md | 27 + .../standard_library/meta/unresolved_type.md | 57 + .../noir/standard_library/options.md | 101 + .../noir/standard_library/recursion.mdx | 85 + .../noir/standard_library/traits.md | 628 +++ .../NoirJS/backend_barretenberg/.nojekyll | 1 + .../classes/BarretenbergBackend.md | 138 + .../classes/BarretenbergVerifier.md | 58 + .../classes/UltraHonkBackend.md | 114 + .../classes/UltraHonkVerifier.md | 58 + .../NoirJS/backend_barretenberg/index.md | 42 + .../type-aliases/BackendOptions.md | 19 + .../backend_barretenberg/typedoc-sidebar.cjs | 4 + .../reference/NoirJS/noir_js/.nojekyll | 1 + .../reference/NoirJS/noir_js/classes/Noir.md | 52 + .../reference/NoirJS/noir_js/functions/and.md | 22 + .../NoirJS/noir_js/functions/blake2s256.md | 21 + .../functions/ecdsa_secp256k1_verify.md | 28 + .../functions/ecdsa_secp256r1_verify.md | 28 + .../reference/NoirJS/noir_js/functions/xor.md | 22 + .../reference/NoirJS/noir_js/index.md | 47 + .../noir_js/type-aliases/ErrorWithPayload.md | 15 + .../type-aliases/ForeignCallHandler.md | 24 + .../noir_js/type-aliases/ForeignCallInput.md | 9 + .../noir_js/type-aliases/ForeignCallOutput.md | 9 + .../NoirJS/noir_js/type-aliases/WitnessMap.md | 9 + .../NoirJS/noir_js/typedoc-sidebar.cjs | 4 + .../reference/NoirJS/noir_wasm/.nojekyll | 1 + .../NoirJS/noir_wasm/functions/compile.md | 51 + .../noir_wasm/functions/compile_contract.md | 51 + .../noir_wasm/functions/createFileManager.md | 21 + .../functions/inflateDebugSymbols.md | 21 + .../reference/NoirJS/noir_wasm/index.md | 49 + .../NoirJS/noir_wasm/typedoc-sidebar.cjs | 4 + .../reference}/_category_.json | 2 +- .../reference/debugger}/_category_.json | 2 +- .../debugger/debugger_known_limitations.md | 59 + .../reference/debugger/debugger_repl.md | 360 ++ .../reference/debugger/debugger_vscode.md | 82 + .../reference/nargo_commands.md | 297 ++ .../version-v0.36.0/reference/noir_codegen.md | 116 + .../version-v0.36.0/tooling/debugger.md | 26 + .../tooling/language_server.md | 43 + .../version-v0.36.0/tooling/testing.md | 79 + .../version-v0.36.0/tutorials/noirjs_app.md | 366 ++ .../version-v0.36.0-sidebars.json | 93 + .../noir_stdlib/src/array/check_shuffle.nr | 18 +- noir/noir-repo/noir_stdlib/src/array/mod.nr | 80 +- .../noir_stdlib/src/array/quicksort.nr | 14 +- noir/noir-repo/noir_stdlib/src/bigint.nr | 46 +- noir/noir-repo/noir_stdlib/src/cmp.nr | 111 +- .../src/collections/bounded_vec.nr | 144 +- .../noir_stdlib/src/collections/map.nr | 226 +- .../noir_stdlib/src/collections/umap.nr | 91 +- .../noir_stdlib/src/collections/vec.nr | 6 +- noir/noir-repo/noir_stdlib/src/compat.nr | 6 +- noir/noir-repo/noir_stdlib/src/convert.nr | 5 +- noir/noir-repo/noir_stdlib/src/default.nr | 35 +- .../noir-repo/noir_stdlib/src/ec/consts/te.nr | 8 +- noir/noir-repo/noir_stdlib/src/ec/mod.nr | 14 +- .../noir-repo/noir_stdlib/src/ec/montcurve.nr | 45 +- noir/noir-repo/noir_stdlib/src/ec/swcurve.nr | 64 +- noir/noir-repo/noir_stdlib/src/ec/tecurve.nr | 53 +- .../noir_stdlib/src/ecdsa_secp256k1.nr | 4 +- .../noir_stdlib/src/ecdsa_secp256r1.nr | 4 +- noir/noir-repo/noir_stdlib/src/eddsa.nr | 12 +- .../noir_stdlib/src/embedded_curve_ops.nr | 54 +- noir/noir-repo/noir_stdlib/src/field/bn254.nr | 4 +- noir/noir-repo/noir_stdlib/src/field/mod.nr | 16 +- noir/noir-repo/noir_stdlib/src/hash/keccak.nr | 21 +- noir/noir-repo/noir_stdlib/src/hash/mimc.nr | 186 +- noir/noir-repo/noir_stdlib/src/hash/mod.nr | 347 +- .../noir_stdlib/src/hash/poseidon/bn254.nr | 32 +- .../src/hash/poseidon/bn254/consts.nr | 1 - .../src/hash/poseidon/bn254/perm.nr | 64 +- .../noir_stdlib/src/hash/poseidon/mod.nr | 190 +- .../noir_stdlib/src/hash/poseidon2.nr | 19 +- noir/noir-repo/noir_stdlib/src/hash/sha256.nr | 440 +- noir/noir-repo/noir_stdlib/src/hash/sha512.nr | 12 +- noir/noir-repo/noir_stdlib/src/lib.nr | 10 +- .../noir_stdlib/src/meta/ctstring.nr | 8 +- noir/noir-repo/noir_stdlib/src/meta/expr.nr | 238 +- .../noir_stdlib/src/meta/format_string.nr | 2 +- .../noir_stdlib/src/meta/function_def.nr | 5 +- noir/noir-repo/noir_stdlib/src/meta/mod.nr | 33 +- noir/noir-repo/noir_stdlib/src/meta/module.nr | 5 +- noir/noir-repo/noir_stdlib/src/meta/op.nr | 14 +- noir/noir-repo/noir_stdlib/src/meta/quoted.nr | 5 +- .../noir_stdlib/src/meta/struct_def.nr | 5 +- .../noir_stdlib/src/meta/trait_constraint.nr | 5 +- .../noir_stdlib/src/meta/trait_def.nr | 5 +- noir/noir-repo/noir_stdlib/src/meta/typ.nr | 49 +- noir/noir-repo/noir_stdlib/src/option.nr | 44 +- noir/noir-repo/noir_stdlib/src/schnorr.nr | 27 +- noir/noir-repo/noir_stdlib/src/sha256.nr | 1 - noir/noir-repo/noir_stdlib/src/sha512.nr | 1 - noir/noir-repo/noir_stdlib/src/slice.nr | 13 +- noir/noir-repo/noir_stdlib/src/uint128.nr | 104 +- noir/noir-repo/scripts/install_bb.sh | 2 +- .../benchmarks/bench_sha256_long/Prover.toml | 191 + .../benchmarks/bench_sha256_long/src/main.nr | 7 + .../arithmetic_generics/src/main.nr | 12 +- .../src/main.nr | 9 +- .../assert_constant/src/main.nr | 2 +- .../attributes_struct/src/main.nr | 6 +- .../brillig_cast/src/main.nr | 2 +- .../brillig_modulo/src/main.nr | 2 +- .../brillig_slice_input/src/main.nr | 22 +- .../checked_transmute/src/main.nr | 4 +- .../comptime_array_len/src/main.nr | 3 +- .../comptime_as_slice/src/main.nr | 3 +- .../src/main.nr | 3 +- .../comptime_closures/src/main.nr | 13 +- .../comptime_derive_generators/Nargo.toml | 7 + .../comptime_derive_generators/src/main.nr | 67 + .../comptime_function_definition/src/main.nr | 13 +- .../comptime_globals_regression/src/main.nr | 10 +- .../comptime_keccak/src/main.nr | 9 +- .../comptime_module/src/main.nr | 10 +- .../comptime_mut_global/src/main.nr | 6 +- .../src/main.nr | 15 +- .../comptime_slice_methods/src/main.nr | 3 +- .../comptime_str_as_bytes/src/main.nr | 6 +- .../comptime_struct_definition/src/main.nr | 5 +- .../comptime_to_radix/src/main.nr | 3 +- .../comptime_trait_constraint/src/main.nr | 3 +- .../comptime_trait_impl/src/main.nr | 7 +- .../comptime_traits/src/main.nr | 6 +- .../comptime_type/src/main.nr | 40 +- .../comptime_typed_expr/src/main.nr | 3 +- .../comptime_unresolved_type/src/main.nr | 3 +- .../conditional_regression_579/src/main.nr | 4 +- .../src/main.nr | 2 +- .../ctstring/src/main.nr | 3 +- .../derive_impl/src/main.nr | 4 +- .../ec_baby_jubjub/src/main.nr | 134 +- .../src/main.nr | 6 +- .../generators/src/main.nr | 2 +- .../impl_from_where_impl/src/main.nr | 5 +- .../impl_where_clause/src/main.nr | 5 +- .../inject_context_attribute/src/main.nr | 23 +- .../inner_outer_cl/src/main.nr | 4 +- .../macros_in_comptime/src/main.nr | 7 +- .../method_call_regression/src/main.nr | 5 +- .../no_duplicate_methods/src/main.nr | 4 +- .../numeric_generics/src/main.nr | 2 +- .../numeric_generics_explicit/src/main.nr | 9 +- .../regression_2099/src/main.nr | 8 +- .../regression_4635/src/main.nr | 10 +- .../regression_5065/src/main.nr | 5 +- .../regression_6077/src/main.nr | 6 +- .../ret_fn_ret_cl/src/main.nr | 4 +- .../schnorr_simplification/src/main.nr | 68 +- .../serialize/src/main.nr | 11 +- .../simple_program_no_body/src/main.nr | 2 +- .../simple_range/src/main.nr | 2 +- .../slice_join/src/main.nr | 5 +- .../static_assert/src/main.nr | 2 +- .../compile_success_empty/to_bits/src/main.nr | 4 +- .../src/main.nr | 24 +- .../src/main.nr | 3 +- .../trait_default_implementation/src/main.nr | 2 +- .../trait_function_calls/src/main.nr | 144 +- .../trait_generics/src/main.nr | 21 +- .../trait_impl_generics/src/main.nr | 6 +- .../trait_impl_with_where_clause/src/main.nr | 5 +- .../trait_method_mut_self/src/main.nr | 19 +- .../trait_multi_module_test/src/module1.nr | 3 +- .../trait_multi_module_test/src/module2.nr | 3 +- .../trait_multi_module_test/src/module4.nr | 3 +- .../trait_multi_module_test/src/module5.nr | 3 +- .../trait_override_implementation/src/main.nr | 16 +- .../trait_static_methods/src/main.nr | 4 +- .../trait_where_clause/src/main.nr | 33 +- .../src/main.nr | 7 +- .../type_path/src/main.nr | 3 +- .../unquote_struct/src/main.nr | 18 +- .../use_callers_scope/src/main.nr | 6 +- .../Nargo.toml | 7 + .../src/main.nr | 5 + .../Nargo.toml | 7 + .../src/main.nr | 4 + .../1327_concrete_in_generic/src/main.nr | 16 +- .../execution_success/4_sub/src/main.nr | 2 +- .../execution_success/5_over/src/main.nr | 2 +- .../execution_success/6/src/main.nr | 1 - .../execution_success/6_array/src/main.nr | 18 +- .../execution_success/7/src/main.nr | 1 - .../execution_success/7_function/src/main.nr | 4 +- .../aes128_encrypt/src/main.nr | 13 +- .../arithmetic_binary_operations/src/main.nr | 2 +- .../array_dynamic/src/main.nr | 2 +- .../src/main.nr | 1 - .../assert_statement/src/main.nr | 2 +- .../assert_statement_recursive/src/main.nr | 2 +- .../bench_ecdsa_secp256k1/src/main.nr | 3 +- .../execution_success/bigint/src/main.nr | 16 +- .../binary_operator_overloading/src/main.nr | 4 +- .../brillig_arrays/src/main.nr | 2 +- .../brillig_assert/src/main.nr | 2 +- .../brillig_blake2s/src/main.nr | 2 +- .../src/main.nr | 1 - .../brillig_calls/src/main.nr | 2 +- .../brillig_calls_array/src/main.nr | 2 +- .../brillig_calls_conditionals/src/main.nr | 2 +- .../brillig_conditional/src/main.nr | 8 +- .../src/main.nr | 6 +- .../execution_success/brillig_cow/src/main.nr | 7 +- .../brillig_cow_assign/src/main.nr | 1 - .../brillig_cow_regression/src/main.nr | 31 +- .../brillig_ecdsa_secp256k1/src/main.nr | 4 +- .../brillig_ecdsa_secp256r1/src/main.nr | 4 +- .../brillig_fns_as_values/src/main.nr | 2 +- .../brillig_hash_to_field/src/main.nr | 2 +- .../brillig_identity_function/src/main.nr | 2 +- .../brillig_keccak/src/main.nr | 2 +- .../brillig_loop/src/main.nr | 2 +- .../brillig_loop_size_regression/src/main.nr | 3 +- .../execution_success/brillig_not/src/main.nr | 2 +- .../brillig_oracle/src/main.nr | 8 +- .../brillig_pedersen/src/main.nr | 9 +- .../brillig_recursion/src/main.nr | 2 +- .../brillig_references/src/main.nr | 10 +- .../brillig_sha256/src/main.nr | 2 +- .../brillig_slices/src/main.nr | 6 +- .../check_large_field_bits/src/main.nr | 24 +- .../closures_mut_ref/src/main.nr | 8 +- .../comptime_slice_equality/src/main.nr | 3 +- .../conditional_1/src/main.nr | 6 +- .../conditional_regression_547/src/main.nr | 6 +- .../conditional_regression_661/src/main.nr | 2 +- .../databus_composite_calldata/src/main.nr | 2 +- .../databus_two_calldata/src/main.nr | 8 +- .../execution_success/debug_logs/src/main.nr | 17 +- .../execution_success/derive/src/main.nr | 18 +- .../double_verify_honk_proof/src/main.nr | 11 +- .../src/main.nr | 11 +- .../double_verify_nested_proof/src/main.nr | 11 +- .../double_verify_proof/src/main.nr | 5 +- .../double_verify_proof_recursive/src/main.nr | 5 +- .../ecdsa_secp256k1/src/main.nr | 5 +- .../ecdsa_secp256r1/src/main.nr | 3 +- .../ecdsa_secp256r1_3x/src/main.nr | 19 +- .../execution_success/eddsa/src/main.nr | 4 +- .../embedded_curve_ops/src/main.nr | 3 +- .../fold_complex_outputs/src/main.nr | 2 +- .../fold_numeric_generic_poseidon/src/main.nr | 2 +- .../global_consts/src/main.nr | 12 +- .../execution_success/hashmap/src/main.nr | 46 +- .../higher_order_functions/src/main.nr | 9 +- .../inline_never_basic/Prover.toml | 2 +- .../execution_success/keccak256/src/main.nr | 1 - .../execution_success/loop/src/main.nr | 2 +- .../merkle_insert/src/main.nr | 2 +- .../execution_success/modulus/src/main.nr | 2 +- .../nested_arrays_from_brillig/src/main.nr | 4 +- .../src/main.nr | 2 +- .../pedersen_commitment/src/main.nr | 1 - .../pedersen_hash/src/main.nr | 1 - .../ram_blowup_regression/Nargo.toml | 7 + .../ram_blowup_regression/Prover.toml | 1 + .../ram_blowup_regression/src/main.nr | 41 + .../reference_only_used_as_alias/src/main.nr | 28 +- .../execution_success/references/src/main.nr | 18 +- .../execution_success/regression/src/main.nr | 25 +- .../regression_3394/src/main.nr | 2 +- .../regression_3607/src/main.nr | 4 +- .../regression_3889/src/main.nr | 2 +- .../regression_4088/src/main.nr | 5 +- .../regression_4124/src/main.nr | 5 +- .../regression_4449/src/main.nr | 1 - .../regression_4709/src/main.nr | 4097 +++++++++++++++-- .../regression_5045/src/main.nr | 4 +- .../regression_5252/src/main.nr | 6 +- .../regression_5435/src/main.nr | 10 +- .../regression_5615/src/main.nr | 6 +- .../regression_capacity_tracker/src/main.nr | 8 +- .../src/main.nr | 6 +- .../src/main.nr | 4 +- .../execution_success/schnorr/src/main.nr | 10 +- .../execution_success/sha256/src/main.nr | 3 +- .../sha256_regression/src/main.nr | 4 +- .../execution_success/sha2_byte/src/main.nr | 1 - .../signed_arithmetic/src/main.nr | 2 +- .../signed_division/src/main.nr | 2 +- .../simple_add_and_ret_arr/src/main.nr | 2 +- .../simple_comparison/src/main.nr | 2 +- .../simple_print/src/main.nr | 1 - .../simple_shield/src/main.nr | 4 +- .../simple_shift_left_right/src/main.nr | 2 +- .../single_verify_proof/src/main.nr | 3 +- .../execution_success/slice_regex/src/main.nr | 54 +- .../execution_success/slices/src/main.nr | 6 +- .../execution_success/struct/src/main.nr | 2 +- .../to_bytes_consistent/src/main.nr | 4 +- .../trait_as_return_type/src/main.nr | 2 +- .../trait_impl_base_type/src/main.nr | 12 +- .../execution_success/u128/src/main.nr | 2 +- .../execution_success/uhashmap/src/main.nr | 58 +- .../unary_operator_overloading/src/main.nr | 2 +- .../verify_honk_proof/src/main.nr | 9 +- .../wildcard_type/src/main.nr | 2 +- .../tooling/nargo_cli/benches/criterion.rs | 106 +- .../tooling/nargo_cli/tests/stdlib-props.rs | 2 +- .../tooling/nargo_cli/tests/stdlib-tests.rs | 33 +- noir/noir-repo/tooling/nargo_fmt/Cargo.toml | 2 - noir/noir-repo/tooling/nargo_fmt/build.rs | 19 +- .../noir-repo/tooling/nargo_fmt/src/chunks.rs | 973 ++++ .../noir-repo/tooling/nargo_fmt/src/config.rs | 1 - .../tooling/nargo_fmt/src/formatter.rs | 310 ++ .../tooling/nargo_fmt/src/formatter/alias.rs | 41 + .../nargo_fmt/src/formatter/attribute.rs | 30 + .../tooling/nargo_fmt/src/formatter/buffer.rs | 64 + .../src/formatter/comments_and_whitespace.rs | 859 ++++ .../nargo_fmt/src/formatter/doc_comments.rs | 72 + .../nargo_fmt/src/formatter/expression.rs | 2134 +++++++++ .../nargo_fmt/src/formatter/function.rs | 538 +++ .../nargo_fmt/src/formatter/generics.rs | 96 + .../tooling/nargo_fmt/src/formatter/global.rs | 102 + .../tooling/nargo_fmt/src/formatter/impls.rs | 123 + .../tooling/nargo_fmt/src/formatter/item.rs | 45 + .../tooling/nargo_fmt/src/formatter/lvalue.rs | 44 + .../tooling/nargo_fmt/src/formatter/module.rs | 142 + .../tooling/nargo_fmt/src/formatter/path.rs | 59 + .../nargo_fmt/src/formatter/pattern.rs | 162 + .../nargo_fmt/src/formatter/statement.rs | 682 +++ .../nargo_fmt/src/formatter/structs.rs | 200 + .../nargo_fmt/src/formatter/trait_impl.rs | 218 + .../tooling/nargo_fmt/src/formatter/traits.rs | 298 ++ .../src/formatter/type_expression.rs | 40 + .../tooling/nargo_fmt/src/formatter/types.rs | 355 ++ .../nargo_fmt/src/formatter/use_tree.rs | 204 + .../nargo_fmt/src/formatter/visibility.rs | 52 + .../nargo_fmt/src/formatter/where_clause.rs | 72 + noir/noir-repo/tooling/nargo_fmt/src/items.rs | 114 - noir/noir-repo/tooling/nargo_fmt/src/lib.rs | 98 +- .../tooling/nargo_fmt/src/rewrite.rs | 13 - .../tooling/nargo_fmt/src/rewrite/array.rs | 92 - .../tooling/nargo_fmt/src/rewrite/expr.rs | 258 -- .../tooling/nargo_fmt/src/rewrite/imports.rs | 135 - .../tooling/nargo_fmt/src/rewrite/infix.rs | 115 - .../nargo_fmt/src/rewrite/parenthesized.rs | 68 - .../tooling/nargo_fmt/src/rewrite/typ.rs | 78 - noir/noir-repo/tooling/nargo_fmt/src/utils.rs | 233 - .../tooling/nargo_fmt/src/visitor.rs | 303 -- .../tooling/nargo_fmt/src/visitor/expr.rs | 484 -- .../tooling/nargo_fmt/src/visitor/item.rs | 439 -- .../tooling/nargo_fmt/src/visitor/stmt.rs | 98 - .../tooling/nargo_fmt/tests/expected/array.nr | 34 +- .../tooling/nargo_fmt/tests/expected/call.nr | 22 +- .../nargo_fmt/tests/expected/contract.nr | 23 +- .../tooling/nargo_fmt/tests/expected/empty.nr | 1 + .../tooling/nargo_fmt/tests/expected/expr.nr | 28 +- .../tooling/nargo_fmt/tests/expected/fn.nr | 19 +- .../tooling/nargo_fmt/tests/expected/if.nr | 11 +- .../nargo_fmt/tests/expected/ignore.nr | 1 + .../tooling/nargo_fmt/tests/expected/impl.nr | 7 +- .../tests/expected/impl_trait_fn_parameter.nr | 5 +- .../tooling/nargo_fmt/tests/expected/index.nr | 6 +- .../tooling/nargo_fmt/tests/expected/infix.nr | 14 +- .../tooling/nargo_fmt/tests/expected/let.nr | 39 +- .../nargo_fmt/tests/expected/module.nr | 2 +- .../nargo_fmt/tests/expected/parens.nr | 20 +- .../nargo_fmt/tests/expected/struct.nr | 2 +- .../tooling/nargo_fmt/tests/expected/tuple.nr | 62 +- .../tests/expected/turbofish_call.nr | 2 +- .../tests/expected/turbofish_method_call.nr | 12 +- .../tooling/nargo_fmt/tests/expected/vec.nr | 6 +- .../tooling/nargo_fmt/tests/input/ignore.nr | 1 + .../tooling/nargo_fmt/tests/input/impl.nr | 2 - .../tooling/nargo_fmt/tests/input/tuple.nr | 1 - .../tooling/noir_codegen/package.json | 2 +- noir/noir-repo/tooling/noir_js/package.json | 2 +- .../tooling/noir_js_types/package.json | 2 +- .../tooling/noirc_abi_wasm/package.json | 2 +- noir/noir-repo/yarn.lock | 2526 +++++++++- yarn-project/yarn.lock | 16 +- 965 files changed, 42732 insertions(+), 13254 deletions(-) delete mode 100644 noir/noir-repo/docs/.markdownlint.json delete mode 100644 noir/noir-repo/docs/docs/getting_started/backend/index.md delete mode 100644 noir/noir-repo/docs/docs/getting_started/hello_noir/index.md delete mode 100644 noir/noir-repo/docs/docs/getting_started/installation/index.md rename noir/noir-repo/docs/docs/getting_started/{installation/other_install_methods.md => noir_installation.md} (93%) rename noir/noir-repo/docs/docs/getting_started/{hello_noir => }/project_breakdown.md (95%) create mode 100644 noir/noir-repo/docs/docs/getting_started/quick_start.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/cspell.json create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-oracle.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-recursion.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-writing-noir.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/noir_installation.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/project_breakdown.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/quick_start.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/_category_.json create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_the_repl.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_vs_code.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-oracles.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-recursion.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-solidity-verifier.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/merkle-proof.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/using-devcontainers.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/index.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/migration_notes.md rename noir/noir-repo/docs/{docs/getting_started/installation => versioned_docs/version-v0.36.0/noir/concepts}/_category_.json (68%) create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/assert.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comments.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comptime.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/control_flow.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_bus.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/arrays.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/booleans.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/fields.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/function_types.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/index.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/integers.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/references.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/slices.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/strings.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/structs.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/tuples.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/functions.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/generics.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/globals.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/lambdas.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/mutability.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/ops.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/oracles.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/shadowing.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/traits.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/unconstrained.md rename noir/noir-repo/docs/{docs/getting_started/hello_noir => versioned_docs/version-v0.36.0/noir/modules_packages_crates}/_category_.json (60%) create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/crates_and_packages.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/dependencies.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/modules.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/workspaces.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bigint.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/black_box_fns.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bn254.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/boundedvec.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/hashmap.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/index.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/vec.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ciphers.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ec_primitives.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/eddsa.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/hashes.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/index.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/schnorr.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/fmtstr.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/is_unconstrained.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/logging.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/mem.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/merkle_trees.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/ctstring.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/expr.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/function_def.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/index.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/module.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/op.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/quoted.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/struct_def.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_constraint.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_def.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_impl.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typ.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typed_expr.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/unresolved_type.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/options.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/recursion.mdx create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/traits.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/.nojekyll create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkBackend.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkVerifier.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/index.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/.nojekyll create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/classes/Noir.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/and.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/blake2s256.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/xor.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/index.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/.nojekyll create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile_contract.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/createFileManager.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/index.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs rename noir/noir-repo/docs/{docs/getting_started => versioned_docs/version-v0.36.0/reference}/_category_.json (72%) rename noir/noir-repo/docs/{docs/getting_started/backend => versioned_docs/version-v0.36.0/reference/debugger}/_category_.json (63%) create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_known_limitations.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_repl.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_vscode.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/nargo_commands.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/noir_codegen.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/debugger.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/language_server.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/testing.md create mode 100644 noir/noir-repo/docs/versioned_docs/version-v0.36.0/tutorials/noirjs_app.md create mode 100644 noir/noir-repo/docs/versioned_sidebars/version-v0.36.0-sidebars.json create mode 100644 noir/noir-repo/test_programs/benchmarks/bench_sha256_long/Prover.toml create mode 100644 noir/noir-repo/test_programs/benchmarks/bench_sha256_long/src/main.nr create mode 100644 noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/Nargo.toml create mode 100644 noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/src/main.nr create mode 100644 noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/Nargo.toml create mode 100644 noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/src/main.nr create mode 100644 noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/Nargo.toml create mode 100644 noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/src/main.nr create mode 100644 noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Nargo.toml create mode 100644 noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Prover.toml create mode 100644 noir/noir-repo/test_programs/execution_success/ram_blowup_regression/src/main.nr create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/chunks.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/alias.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/attribute.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/buffer.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/doc_comments.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/function.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/generics.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/global.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/impls.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/item.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/lvalue.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/module.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/path.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/pattern.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/structs.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/trait_impl.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/traits.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/type_expression.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/types.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/visibility.rs create mode 100644 noir/noir-repo/tooling/nargo_fmt/src/formatter/where_clause.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/items.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/rewrite.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/rewrite/array.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/rewrite/expr.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/rewrite/imports.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/rewrite/infix.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/rewrite/parenthesized.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/utils.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/visitor.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/visitor/expr.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs delete mode 100644 noir/noir-repo/tooling/nargo_fmt/src/visitor/stmt.rs diff --git a/.noir-sync-commit b/.noir-sync-commit index d3b7e1db860..a646a9d9f7a 100644 --- a/.noir-sync-commit +++ b/.noir-sync-commit @@ -1 +1 @@ -ae87d287ab1fae0f999dfd0d1166fbddb927ba97 +b82032888819eac82b2bfce8300c2c8b66507c64 diff --git a/avm-transpiler/Cargo.lock b/avm-transpiler/Cargo.lock index 3690b1c405a..54d069e0a0a 100644 --- a/avm-transpiler/Cargo.lock +++ b/avm-transpiler/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "acir" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir_field", "base64 0.21.7", @@ -18,7 +18,7 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.51.0" +version = "0.52.0" dependencies = [ "ark-bn254", "ark-ff", @@ -30,7 +30,7 @@ dependencies = [ [[package]] name = "acvm" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -44,7 +44,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir", "blake2", @@ -370,7 +370,7 @@ dependencies = [ [[package]] name = "brillig" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir_field", "serde", @@ -378,7 +378,7 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -675,7 +675,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.35.0" +version = "0.36.0" dependencies = [ "codespan-reporting", "iter-extended", @@ -830,7 +830,7 @@ checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] name = "iter-extended" -version = "0.35.0" +version = "0.36.0" [[package]] name = "itertools" @@ -935,7 +935,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "base64 0.21.7", @@ -952,7 +952,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "iter-extended", diff --git a/noir-projects/aztec-nr/address-note/src/address_note.nr b/noir-projects/aztec-nr/address-note/src/address_note.nr index 38319830f53..62786dd4b0b 100644 --- a/noir-projects/aztec-nr/address-note/src/address_note.nr +++ b/noir-projects/aztec-nr/address-note/src/address_note.nr @@ -1,7 +1,13 @@ use dep::aztec::{ - protocol_types::{address::AztecAddress, constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - note::{note_header::NoteHeader, note_interface::NullifiableNote, utils::compute_note_hash_for_nullify}, - oracle::random::random, keys::getters::get_nsk_app, context::PrivateContext, macros::notes::note + protocol_types::{ + address::AztecAddress, constants::GENERATOR_INDEX__NOTE_NULLIFIER, + hash::poseidon2_hash_with_separator, + }, + note::{ + note_header::NoteHeader, note_interface::NullifiableNote, + utils::compute_note_hash_for_nullify, + }, oracle::random::random, keys::getters::get_nsk_app, context::PrivateContext, + macros::notes::note, }; // docs:start:address_note_def @@ -18,14 +24,15 @@ pub struct AddressNote { impl NullifiableNote for AddressNote { - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -33,11 +40,8 @@ impl NullifiableNote for AddressNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } @@ -48,9 +52,7 @@ impl AddressNote { // malicious sender could use non-random values to make the note less private. But they already know the full // note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can // therefore assume that the sender will cooperate in the random value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; AddressNote { address, npk_m_hash, randomness, header: NoteHeader::empty() } } // docs:end:address_note_def diff --git a/noir-projects/aztec-nr/authwit/src/account.nr b/noir-projects/aztec-nr/authwit/src/account.nr index e0adbb797e7..55f0e7918d8 100644 --- a/noir-projects/aztec-nr/authwit/src/account.nr +++ b/noir-projects/aztec-nr/authwit/src/account.nr @@ -1,15 +1,15 @@ use dep::aztec::{ context::PrivateContext, protocol_types::constants::{GENERATOR_INDEX__COMBINED_PAYLOAD, GENERATOR_INDEX__TX_NULLIFIER}, - hash::poseidon2_hash_with_separator + hash::poseidon2_hash_with_separator, }; use crate::entrypoint::{app::AppPayload, fee::FeePayload}; use crate::auth::{IS_VALID_SELECTOR, compute_authwit_message_hash}; pub struct AccountActions { - context: Context, - is_valid_impl: fn(&mut PrivateContext, Field) -> bool, + context: Context, + is_valid_impl: fn(&mut PrivateContext, Field) -> bool, } impl AccountActions { @@ -40,7 +40,7 @@ impl AccountActions<&mut PrivateContext> { let combined_payload_hash = poseidon2_hash_with_separator( [app_payload.hash(), fee_payload.hash()], - GENERATOR_INDEX__COMBINED_PAYLOAD + GENERATOR_INDEX__COMBINED_PAYLOAD, ); assert(valid_fn(self.context, combined_payload_hash)); @@ -48,7 +48,8 @@ impl AccountActions<&mut PrivateContext> { self.context.end_setup(); app_payload.execute_calls(self.context); if cancellable { - let tx_nullifier = poseidon2_hash_with_separator([app_payload.nonce], GENERATOR_INDEX__TX_NULLIFIER); + let tx_nullifier = + poseidon2_hash_with_separator([app_payload.nonce], GENERATOR_INDEX__TX_NULLIFIER); self.context.push_nullifier(tx_nullifier); } } @@ -73,7 +74,7 @@ impl AccountActions<&mut PrivateContext> { self.context.msg_sender(), self.context.chain_id(), self.context.version(), - inner_hash + inner_hash, ); let valid_fn = self.is_valid_impl; assert(valid_fn(self.context, message_hash) == true, "Message not authorized by account"); diff --git a/noir-projects/aztec-nr/authwit/src/auth.nr b/noir-projects/aztec-nr/authwit/src/auth.nr index 07212727082..88b8f3ea9b4 100644 --- a/noir-projects/aztec-nr/authwit/src/auth.nr +++ b/noir-projects/aztec-nr/authwit/src/auth.nr @@ -1,10 +1,9 @@ use dep::aztec::protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, constants::{ - GENERATOR_INDEX__AUTHWIT_INNER, GENERATOR_INDEX__AUTHWIT_OUTER, GENERATOR_INDEX__AUTHWIT_NULLIFIER, - CANONICAL_AUTH_REGISTRY_ADDRESS -}, - hash::poseidon2_hash_with_separator + GENERATOR_INDEX__AUTHWIT_INNER, GENERATOR_INDEX__AUTHWIT_OUTER, + GENERATOR_INDEX__AUTHWIT_NULLIFIER, CANONICAL_AUTH_REGISTRY_ADDRESS, + }, hash::poseidon2_hash_with_separator, }; use dep::aztec::{context::{PrivateContext, PublicContext, gas::GasOpts}, hash::hash_args_array}; @@ -201,7 +200,11 @@ global IS_VALID_SELECTOR = 0x47dacd73; // 4 last bytes of poseidon2_hash_bytes(" */ // docs:start:assert_current_call_valid_authwit pub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress) { - let inner_hash = compute_inner_authwit_hash([context.msg_sender().to_field(), context.selector().to_field(), context.args_hash]); + let inner_hash = compute_inner_authwit_hash([ + context.msg_sender().to_field(), + context.selector().to_field(), + context.args_hash, + ]); assert_inner_hash_valid_authwit(context, on_behalf_of, inner_hash); } // docs:end:assert_current_call_valid_authwit @@ -215,15 +218,19 @@ pub fn assert_current_call_valid_authwit(context: &mut PrivateContext, on_behalf * @param on_behalf_of The address that have authorized the current call * @param inner_hash The hash of the message to authorize */ -pub fn assert_inner_hash_valid_authwit(context: &mut PrivateContext, on_behalf_of: AztecAddress, inner_hash: Field) { +pub fn assert_inner_hash_valid_authwit( + context: &mut PrivateContext, + on_behalf_of: AztecAddress, + inner_hash: Field, +) { // We perform a static call here and not a standard one to ensure that the account contract cannot re-enter. - let result: Field = context.static_call_private_function( - on_behalf_of, - comptime { - FunctionSelector::from_signature("verify_private_authwit(Field)") - }, - [inner_hash] - ).unpack_into(); + let result: Field = context + .static_call_private_function( + on_behalf_of, + comptime { FunctionSelector::from_signature("verify_private_authwit(Field)") }, + [inner_hash], + ) + .unpack_into(); assert(result == IS_VALID_SELECTOR, "Message not authorized by account"); // Compute the nullifier, similar computation to the outer hash, but without the chain_id and version. // Those should already be handled in the verification, so we just need something to nullify, that allow same inner_hash for multiple actors. @@ -245,11 +252,13 @@ pub fn assert_inner_hash_valid_authwit(context: &mut PrivateContext, on_behalf_o // docs:start:assert_current_call_valid_authwit_public pub fn assert_current_call_valid_authwit_public( context: &mut PublicContext, - on_behalf_of: AztecAddress + on_behalf_of: AztecAddress, ) { - let inner_hash = compute_inner_authwit_hash( - [(*context).msg_sender().to_field(), (*context).selector().to_field(), (*context).get_args_hash()] - ); + let inner_hash = compute_inner_authwit_hash([ + (*context).msg_sender().to_field(), + (*context).selector().to_field(), + (*context).get_args_hash(), + ]); assert_inner_hash_valid_authwit_public(context, on_behalf_of, inner_hash); } // docs:end:assert_current_call_valid_authwit_public @@ -265,15 +274,19 @@ pub fn assert_current_call_valid_authwit_public( * * @param on_behalf_of The address that have authorized the `inner_hash` */ -pub fn assert_inner_hash_valid_authwit_public(context: &mut PublicContext, on_behalf_of: AztecAddress, inner_hash: Field) { - let result: Field = context.call_public_function( - CANONICAL_AUTH_REGISTRY_ADDRESS, - comptime { - FunctionSelector::from_signature("consume((Field),Field)") - }, - [on_behalf_of.to_field(), inner_hash].as_slice(), - GasOpts::default() - ).deserialize_into(); +pub fn assert_inner_hash_valid_authwit_public( + context: &mut PublicContext, + on_behalf_of: AztecAddress, + inner_hash: Field, +) { + let result: Field = context + .call_public_function( + CANONICAL_AUTH_REGISTRY_ADDRESS, + comptime { FunctionSelector::from_signature("consume((Field),Field)") }, + [on_behalf_of.to_field(), inner_hash].as_slice(), + GasOpts::default(), + ) + .deserialize_into(); assert(result == IS_VALID_SELECTOR, "Message not authorized by account"); } @@ -298,10 +311,11 @@ pub fn compute_authwit_message_hash_from_call( chain_id: Field, version: Field, selector: FunctionSelector, - args: [Field; N] + args: [Field; N], ) -> Field { let args_hash = hash_args_array(args); - let inner_hash = compute_inner_authwit_hash([caller.to_field(), selector.to_field(), args_hash]); + let inner_hash = + compute_inner_authwit_hash([caller.to_field(), selector.to_field(), args_hash]); compute_authwit_message_hash(consumer, chain_id, version, inner_hash) } // docs:end:compute_authwit_message_hash_from_call @@ -329,7 +343,7 @@ pub fn compute_inner_authwit_hash(args: [Field; N]) -> Field { pub fn compute_authwit_nullifier(on_behalf_of: AztecAddress, inner_hash: Field) -> Field { poseidon2_hash_with_separator( [on_behalf_of.to_field(), inner_hash], - GENERATOR_INDEX__AUTHWIT_NULLIFIER + GENERATOR_INDEX__AUTHWIT_NULLIFIER, ) } @@ -341,15 +355,15 @@ pub fn compute_authwit_nullifier(on_behalf_of: AztecAddress, inner_hash: Field) * @param version The version of the chain that the message is being consumed on * @param inner_hash The hash of the "inner" message that is being consumed */ -pub fn compute_authwit_message_hash(consumer: AztecAddress, chain_id: Field, version: Field, inner_hash: Field) -> Field { +pub fn compute_authwit_message_hash( + consumer: AztecAddress, + chain_id: Field, + version: Field, + inner_hash: Field, +) -> Field { poseidon2_hash_with_separator( - [ - consumer.to_field(), - chain_id, - version, - inner_hash - ], - GENERATOR_INDEX__AUTHWIT_OUTER + [consumer.to_field(), chain_id, version, inner_hash], + GENERATOR_INDEX__AUTHWIT_OUTER, ) } @@ -362,14 +376,14 @@ pub fn compute_authwit_message_hash(consumer: AztecAddress, chain_id: Field, ver * @param authorize True if the message should be authorized, false if it should be revoked */ pub fn set_authorized(context: &mut PublicContext, message_hash: Field, authorize: bool) { - context.call_public_function( - CANONICAL_AUTH_REGISTRY_ADDRESS, - comptime { - FunctionSelector::from_signature("set_authorized(Field,bool)") - }, - [message_hash, authorize as Field].as_slice(), - GasOpts::default() - ).assert_empty(); + context + .call_public_function( + CANONICAL_AUTH_REGISTRY_ADDRESS, + comptime { FunctionSelector::from_signature("set_authorized(Field,bool)") }, + [message_hash, authorize as Field].as_slice(), + GasOpts::default(), + ) + .assert_empty(); } /** @@ -380,12 +394,12 @@ pub fn set_authorized(context: &mut PublicContext, message_hash: Field, authoriz * @param reject True if all authwits should be rejected, false otherwise */ pub fn set_reject_all(context: &mut PublicContext, reject: bool) { - context.call_public_function( - CANONICAL_AUTH_REGISTRY_ADDRESS, - comptime { - FunctionSelector::from_signature("set_reject_all(bool)") - }, - [context.this_address().to_field(), reject as Field].as_slice(), - GasOpts::default() - ).assert_empty(); + context + .call_public_function( + CANONICAL_AUTH_REGISTRY_ADDRESS, + comptime { FunctionSelector::from_signature("set_reject_all(bool)") }, + [context.this_address().to_field(), reject as Field].as_slice(), + GasOpts::default(), + ) + .assert_empty(); } diff --git a/noir-projects/aztec-nr/authwit/src/cheatcodes.nr b/noir-projects/aztec-nr/authwit/src/cheatcodes.nr index 6cc8649d425..a61c1f24d5c 100644 --- a/noir-projects/aztec-nr/authwit/src/cheatcodes.nr +++ b/noir-projects/aztec-nr/authwit/src/cheatcodes.nr @@ -1,19 +1,28 @@ use dep::aztec::{ protocol_types::address::AztecAddress, - context::{public_context::PublicContext, call_interfaces::CallInterface}, test::helpers::cheatcodes, - oracle::execution::{get_block_number, get_contract_address}, hash::hash_args + context::{public_context::PublicContext, call_interfaces::CallInterface}, + test::helpers::cheatcodes, oracle::execution::{get_block_number, get_contract_address}, + hash::hash_args, }; use crate::auth::{compute_inner_authwit_hash, compute_authwit_message_hash, set_authorized}; -pub fn add_private_authwit_from_call_interface(on_behalf_of: AztecAddress, caller: AztecAddress, call_interface: C) where C: CallInterface { +pub fn add_private_authwit_from_call_interface( + on_behalf_of: AztecAddress, + caller: AztecAddress, + call_interface: C, +) +where + C: CallInterface, +{ let target = call_interface.get_contract_address(); let inputs = cheatcodes::get_private_context_inputs(get_block_number()); let chain_id = inputs.tx_context.chain_id; let version = inputs.tx_context.version; let args_hash = hash_args(call_interface.get_args()); let selector = call_interface.get_selector(); - let inner_hash = compute_inner_authwit_hash([caller.to_field(), selector.to_field(), args_hash]); + let inner_hash = + compute_inner_authwit_hash([caller.to_field(), selector.to_field(), args_hash]); let message_hash = compute_authwit_message_hash(target, chain_id, version, inner_hash); cheatcodes::add_authwit(on_behalf_of, message_hash); } @@ -21,8 +30,11 @@ pub fn add_private_authwit_from_call_interface(on_behalf_of: Azte pub fn add_public_authwit_from_call_interface( on_behalf_of: AztecAddress, caller: AztecAddress, - call_interface: C -) where C: CallInterface { + call_interface: C, +) +where + C: CallInterface, +{ let current_contract = get_contract_address(); cheatcodes::set_contract_address(on_behalf_of); let target = call_interface.get_contract_address(); @@ -31,9 +43,10 @@ pub fn add_public_authwit_from_call_interface( let version = inputs.tx_context.version; let args_hash = hash_args(call_interface.get_args()); let selector = call_interface.get_selector(); - let inner_hash = compute_inner_authwit_hash([caller.to_field(), selector.to_field(), args_hash]); + let inner_hash = + compute_inner_authwit_hash([caller.to_field(), selector.to_field(), args_hash]); let message_hash = compute_authwit_message_hash(target, chain_id, version, inner_hash); - let mut context = PublicContext::new(|| {panic( f"Provide args hash manually")}); + let mut context = PublicContext::new(|| { panic(f"Provide args hash manually") }); context.args_hash = Option::some(args_hash); set_authorized(&mut context, message_hash, true); cheatcodes::set_contract_address(current_contract); diff --git a/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr b/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr index 4cdee565695..1aac89e567f 100644 --- a/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr +++ b/noir-projects/aztec-nr/authwit/src/entrypoint/app.nr @@ -1,7 +1,7 @@ use dep::aztec::prelude::PrivateContext; use dep::aztec::protocol_types::{ constants::GENERATOR_INDEX__SIGNATURE_PAYLOAD, hash::poseidon2_hash_with_separator, - traits::{Hash, Serialize} + traits::{Hash, Serialize}, }; use crate::entrypoint::function_call::FunctionCall; @@ -16,8 +16,8 @@ global ACCOUNT_MAX_CALLS: u32 = 4; // Note: If you change the following struct you have to update default_entrypoint.ts // docs:start:app-payload-struct pub struct AppPayload { - function_calls: [FunctionCall; ACCOUNT_MAX_CALLS], - nonce: Field, + function_calls: [FunctionCall; ACCOUNT_MAX_CALLS], + nonce: Field, } // docs:end:app-payload-struct @@ -62,14 +62,14 @@ impl AppPayload { call.target_address, call.function_selector, call.args_hash, - call.is_static + call.is_static, ); } else { let _result = context.call_private_function_with_packed_args( call.target_address, call.function_selector, call.args_hash, - call.is_static + call.is_static, ); } } diff --git a/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr b/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr index 0c41e6a6cc4..7033b8e97d3 100644 --- a/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr +++ b/noir-projects/aztec-nr/authwit/src/entrypoint/fee.nr @@ -1,7 +1,7 @@ use dep::aztec::prelude::PrivateContext; use dep::aztec::protocol_types::{ constants::GENERATOR_INDEX__FEE_PAYLOAD, hash::poseidon2_hash_with_separator, - traits::{Hash, Serialize} + traits::{Hash, Serialize}, }; use crate::entrypoint::function_call::FunctionCall; @@ -15,9 +15,9 @@ global MAX_FEE_FUNCTION_CALLS: u32 = 2; // docs:start:fee-payload-struct pub struct FeePayload { - function_calls: [FunctionCall; MAX_FEE_FUNCTION_CALLS], - nonce: Field, - is_fee_payer: bool, + function_calls: [FunctionCall; MAX_FEE_FUNCTION_CALLS], + nonce: Field, + is_fee_payer: bool, } // docs:end:fee-payload-struct @@ -61,14 +61,14 @@ impl FeePayload { call.target_address, call.function_selector, call.args_hash, - call.is_static + call.is_static, ); } else { let _result = context.call_private_function_with_packed_args( call.target_address, call.function_selector, call.args_hash, - call.is_static + call.is_static, ); } } diff --git a/noir-projects/aztec-nr/authwit/src/entrypoint/function_call.nr b/noir-projects/aztec-nr/authwit/src/entrypoint/function_call.nr index 38e943f95f4..d146c8a488e 100644 --- a/noir-projects/aztec-nr/authwit/src/entrypoint/function_call.nr +++ b/noir-projects/aztec-nr/authwit/src/entrypoint/function_call.nr @@ -1,4 +1,6 @@ -use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress, traits::Serialize}; +use dep::aztec::protocol_types::{ + abis::function_selector::FunctionSelector, address::AztecAddress, traits::Serialize, +}; // 1 (ARGS_HASH) + 1 (FUNCTION_SELECTOR) + 1 (TARGET_ADDRESS) + 1 (IS_PUBLIC) + 1 (IS_STATIC) global FUNCTION_CALL_SIZE: u32 = 5; @@ -6,17 +8,21 @@ global FUNCTION_CALL_SIZE: u32 = 5; global FUNCTION_CALL_SIZE_IN_BYTES: u32 = 98; pub struct FunctionCall { - args_hash: Field, - function_selector: FunctionSelector, - target_address: AztecAddress, - is_public: bool, - is_static: bool, + args_hash: Field, + function_selector: FunctionSelector, + target_address: AztecAddress, + is_public: bool, + is_static: bool, } impl Serialize for FunctionCall { fn serialize(self) -> [Field; FUNCTION_CALL_SIZE] { [ - self.args_hash, self.function_selector.to_field(), self.target_address.to_field(), self.is_public as Field, self.is_static as Field + self.args_hash, + self.function_selector.to_field(), + self.target_address.to_field(), + self.is_public as Field, + self.is_static as Field, ] } } diff --git a/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr b/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr index 8b67fa2050e..c888c7b490a 100644 --- a/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr +++ b/noir-projects/aztec-nr/aztec/src/context/call_interfaces.nr @@ -1,8 +1,10 @@ -use dep::protocol_types::{abis::{function_selector::FunctionSelector}, address::AztecAddress, traits::Deserialize}; +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, address::AztecAddress, traits::Deserialize, +}; use crate::context::{ private_context::PrivateContext, public_context::PublicContext, gas::GasOpts, - inputs::PrivateContextInputs + inputs::PrivateContextInputs, }; use crate::oracle::arguments::pack_arguments; @@ -37,20 +39,36 @@ pub struct PrivateCallInterface { args_hash: Field, args: [Field], return_type: T, - is_static: bool + is_static: bool, } impl PrivateCallInterface { - pub fn call(self, context: &mut PrivateContext) -> T where T: Deserialize { + pub fn call(self, context: &mut PrivateContext) -> T + where + T: Deserialize, + { pack_arguments(self.args); - let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false); + let returns = context.call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + ); let unpacked: T = returns.unpack_into(); unpacked } - pub fn view(self, context: &mut PrivateContext) -> T where T: Deserialize { + pub fn view(self, context: &mut PrivateContext) -> T + where + T: Deserialize, + { pack_arguments(self.args); - let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true); + let returns = context.call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + true, + ); returns.unpack_into() } } @@ -64,18 +82,32 @@ pub struct PrivateVoidCallInterface { args_hash: Field, args: [Field], return_type: (), - is_static: bool + is_static: bool, } impl PrivateVoidCallInterface { pub fn call(self, context: &mut PrivateContext) { pack_arguments(self.args); - context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, false).assert_empty(); + context + .call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + false, + ) + .assert_empty(); } pub fn view(self, context: &mut PrivateContext) { pack_arguments(self.args); - context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true).assert_empty(); + context + .call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + true, + ) + .assert_empty(); } } @@ -88,13 +120,21 @@ pub struct PrivateStaticCallInterface { args_hash: Field, args: [Field], return_type: T, - is_static: bool + is_static: bool, } impl PrivateStaticCallInterface { - pub fn view(self, context: &mut PrivateContext) -> T where T: Deserialize { + pub fn view(self, context: &mut PrivateContext) -> T + where + T: Deserialize, + { pack_arguments(self.args); - let returns = context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true); + let returns = context.call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + true, + ); returns.unpack_into() } } @@ -108,13 +148,20 @@ pub struct PrivateStaticVoidCallInterface { args_hash: Field, args: [Field], return_type: (), - is_static: bool + is_static: bool, } impl PrivateStaticVoidCallInterface { pub fn view(self, context: &mut PrivateContext) { pack_arguments(self.args); - context.call_private_function_with_packed_args(self.target_contract, self.selector, self.args_hash, true).assert_empty(); + context + .call_private_function_with_packed_args( + self.target_contract, + self.selector, + self.args_hash, + true, + ) + .assert_empty(); } } @@ -127,7 +174,7 @@ pub struct PublicCallInterface { args: [Field], gas_opts: GasOpts, return_type: T, - is_static: bool + is_static: bool, } impl PublicCallInterface { @@ -136,13 +183,29 @@ impl PublicCallInterface { self } - pub fn call(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); + pub fn call(self, context: &mut PublicContext) -> T + where + T: Deserialize, + { + let returns = context.call_public_function( + self.target_contract, + self.selector, + self.args, + self.gas_opts, + ); returns.deserialize_into() } - pub fn view(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); + pub fn view(self, context: &mut PublicContext) -> T + where + T: Deserialize, + { + let returns = context.static_call_public_function( + self.target_contract, + self.selector, + self.args, + self.gas_opts, + ); returns.deserialize_into() } @@ -153,7 +216,8 @@ impl PublicCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ false + /*static=*/ + false, ) } @@ -164,7 +228,8 @@ impl PublicCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true + /*static=*/ + true, ) } } @@ -178,7 +243,7 @@ pub struct PublicVoidCallInterface { args: [Field], return_type: (), is_static: bool, - gas_opts: GasOpts + gas_opts: GasOpts, } impl PublicVoidCallInterface { @@ -188,12 +253,22 @@ impl PublicVoidCallInterface { } pub fn call(self, context: &mut PublicContext) { - let returns = context.call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); + let returns = context.call_public_function( + self.target_contract, + self.selector, + self.args, + self.gas_opts, + ); returns.assert_empty() } pub fn view(self, context: &mut PublicContext) { - let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); + let returns = context.static_call_public_function( + self.target_contract, + self.selector, + self.args, + self.gas_opts, + ); returns.assert_empty() } @@ -204,7 +279,8 @@ impl PublicVoidCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ false + /*static=*/ + false, ) } @@ -215,7 +291,8 @@ impl PublicVoidCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true + /*static=*/ + true, ) } } @@ -229,7 +306,7 @@ pub struct PublicStaticCallInterface { args: [Field], return_type: T, is_static: bool, - gas_opts: GasOpts + gas_opts: GasOpts, } impl PublicStaticCallInterface { @@ -238,8 +315,16 @@ impl PublicStaticCallInterface { self } - pub fn view(self, context: &mut PublicContext) -> T where T: Deserialize { - let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); + pub fn view(self, context: &mut PublicContext) -> T + where + T: Deserialize, + { + let returns = context.static_call_public_function( + self.target_contract, + self.selector, + self.args, + self.gas_opts, + ); let unpacked: T = returns.deserialize_into(); unpacked } @@ -251,7 +336,8 @@ impl PublicStaticCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true + /*static=*/ + true, ) } } @@ -265,7 +351,7 @@ pub struct PublicStaticVoidCallInterface { args: [Field], return_type: (), is_static: bool, - gas_opts: GasOpts + gas_opts: GasOpts, } impl PublicStaticVoidCallInterface { @@ -275,7 +361,12 @@ impl PublicStaticVoidCallInterface { } pub fn view(self, context: &mut PublicContext) { - let returns = context.static_call_public_function(self.target_contract, self.selector, self.args, self.gas_opts); + let returns = context.static_call_public_function( + self.target_contract, + self.selector, + self.args, + self.gas_opts, + ); returns.assert_empty() } @@ -286,7 +377,8 @@ impl PublicStaticVoidCallInterface { self.target_contract, self.selector, args_hash, - /*static=*/ true + /*static=*/ + true, ) } } diff --git a/noir-projects/aztec-nr/aztec/src/context/gas.nr b/noir-projects/aztec-nr/aztec/src/context/gas.nr index 5742cbd9549..7080cac8f91 100644 --- a/noir-projects/aztec-nr/aztec/src/context/gas.nr +++ b/noir-projects/aztec-nr/aztec/src/context/gas.nr @@ -1,6 +1,6 @@ pub struct GasOpts { - l2_gas: Option, - da_gas: Option, + l2_gas: Option, + da_gas: Option, } impl GasOpts { diff --git a/noir-projects/aztec-nr/aztec/src/context/inputs/private_context_inputs.nr b/noir-projects/aztec-nr/aztec/src/context/inputs/private_context_inputs.nr index 274112b1194..d41648e4983 100644 --- a/noir-projects/aztec-nr/aztec/src/context/inputs/private_context_inputs.nr +++ b/noir-projects/aztec-nr/aztec/src/context/inputs/private_context_inputs.nr @@ -1,9 +1,12 @@ -use dep::protocol_types::{transaction::tx_context::TxContext, abis::{call_context::CallContext}, header::Header, traits::Empty}; +use dep::protocol_types::{ + transaction::tx_context::TxContext, abis::call_context::CallContext, header::Header, + traits::Empty, +}; // PrivateContextInputs are expected to be provided to each private function // docs:start:private-context-inputs pub struct PrivateContextInputs { - call_context : CallContext, + call_context: CallContext, historical_header: Header, tx_context: TxContext, start_side_effect_counter: u32, @@ -16,7 +19,7 @@ impl Empty for PrivateContextInputs { call_context: CallContext::empty(), historical_header: Header::empty(), tx_context: TxContext::empty(), - start_side_effect_counter: 0 as u32 + start_side_effect_counter: 0 as u32, } } } diff --git a/noir-projects/aztec-nr/aztec/src/context/mod.nr b/noir-projects/aztec-nr/aztec/src/context/mod.nr index 4747f2d0ffb..f4cf63fd925 100644 --- a/noir-projects/aztec-nr/aztec/src/context/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/context/mod.nr @@ -10,9 +10,9 @@ mod call_interfaces; mod gas; pub use call_interfaces::{ - PrivateCallInterface, PrivateStaticCallInterface, PublicCallInterface, PublicStaticCallInterface, - PrivateVoidCallInterface, PrivateStaticVoidCallInterface, PublicVoidCallInterface, - PublicStaticVoidCallInterface + PrivateCallInterface, PrivateStaticCallInterface, PublicCallInterface, + PublicStaticCallInterface, PrivateVoidCallInterface, PrivateStaticVoidCallInterface, + PublicVoidCallInterface, PublicStaticVoidCallInterface, }; pub use private_context::PrivateContext; pub use packed_returns::PackedReturns; diff --git a/noir-projects/aztec-nr/aztec/src/context/packed_returns.nr b/noir-projects/aztec-nr/aztec/src/context/packed_returns.nr index 015324f0ede..ebb86a9621f 100644 --- a/noir-projects/aztec-nr/aztec/src/context/packed_returns.nr +++ b/noir-projects/aztec-nr/aztec/src/context/packed_returns.nr @@ -2,7 +2,7 @@ use crate::{hash::hash_args_array, oracle::returns::unpack_returns}; use dep::protocol_types::traits::Deserialize; pub struct PackedReturns { - packed_returns: Field, + packed_returns: Field, } impl PackedReturns { @@ -21,14 +21,15 @@ impl PackedReturns { pub fn unpack(self) -> [Field; N] { // We verify that the value returned by `unpack_returns` is the preimage of `packed_returns`, fully constraining // it. - let unpacked: [Field; N] = unsafe { - unpack_returns(self.packed_returns) - }; + let unpacked: [Field; N] = unsafe { unpack_returns(self.packed_returns) }; assert_eq(self.packed_returns, hash_args_array(unpacked)); unpacked } - pub fn unpack_into(self) -> T where T: Deserialize { + pub fn unpack_into(self) -> T + where + T: Deserialize, + { let unpacked: [Field; N] = self.unpack(); Deserialize::deserialize(unpacked) } diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index 796e49514f4..049a828acd2 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -3,32 +3,32 @@ use crate::{ messaging::process_l1_to_l2_message, hash::{hash_args_array, ArgsHasher}, keys::constants::{NULLIFIER_INDEX, OUTGOING_INDEX, NUM_KEY_TYPES, sk_generators}, oracle::{ - key_validation_request::get_key_validation_request, arguments, returns::pack_returns, - call_private_function::call_private_function_internal, header::get_header_at, - logs::{emit_encrypted_note_log, emit_encrypted_event_log}, - enqueue_public_function_call::{ - enqueue_public_function_call_internal, notify_set_min_revertible_side_effect_counter, - set_public_teardown_function_call_internal -} -} + key_validation_request::get_key_validation_request, arguments, returns::pack_returns, + call_private_function::call_private_function_internal, header::get_header_at, + logs::{emit_encrypted_note_log, emit_encrypted_event_log}, + enqueue_public_function_call::{ + enqueue_public_function_call_internal, notify_set_min_revertible_side_effect_counter, + set_public_teardown_function_call_internal, + }, + }, }; use dep::protocol_types::{ abis::{ - call_context::CallContext, function_selector::FunctionSelector, max_block_number::MaxBlockNumber, - validation_requests::{KeyValidationRequest, KeyValidationRequestAndGenerator}, - private_call_request::PrivateCallRequest, private_circuit_public_inputs::PrivateCircuitPublicInputs, - public_call_request::PublicCallRequest, read_request::ReadRequest, note_hash::NoteHash, - nullifier::Nullifier, log_hash::{LogHash, NoteLogHash, EncryptedLogHash} -}, - address::{AztecAddress, EthAddress}, + call_context::CallContext, function_selector::FunctionSelector, + max_block_number::MaxBlockNumber, + validation_requests::{KeyValidationRequest, KeyValidationRequestAndGenerator}, + private_call_request::PrivateCallRequest, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + public_call_request::PublicCallRequest, read_request::ReadRequest, note_hash::NoteHash, + nullifier::Nullifier, log_hash::{LogHash, NoteLogHash, EncryptedLogHash}, + }, address::{AztecAddress, EthAddress}, constants::{ - MAX_NOTE_HASHES_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL, MAX_NULLIFIERS_PER_CALL, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, - MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, - MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL, - MAX_NOTE_ENCRYPTED_LOGS_PER_CALL, PUBLIC_DISPATCH_SELECTOR -}, - header::Header, messaging::l2_to_l1_message::L2ToL1Message, traits::Empty + MAX_NOTE_HASHES_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL, MAX_NULLIFIERS_PER_CALL, + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, + MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, + MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_ENCRYPTED_LOGS_PER_CALL, + MAX_UNENCRYPTED_LOGS_PER_CALL, MAX_NOTE_ENCRYPTED_LOGS_PER_CALL, PUBLIC_DISPATCH_SELECTOR, + }, header::Header, messaging::l2_to_l1_message::L2ToL1Message, traits::Empty, }; // When finished, one can call .finish() to convert back to the abi @@ -52,10 +52,10 @@ pub struct PrivateContext { note_hashes: BoundedVec, nullifiers: BoundedVec, - private_call_requests : BoundedVec, - public_call_requests : BoundedVec, + private_call_requests: BoundedVec, + public_call_requests: BoundedVec, public_teardown_call_request: PublicCallRequest, - l2_to_l1_msgs : BoundedVec, + l2_to_l1_msgs: BoundedVec, // docs:end:private-context // Header of a block whose state is used during private execution (not the block the transaction is included in). @@ -94,7 +94,7 @@ impl PrivateContext { note_encrypted_logs_hashes: BoundedVec::new(), encrypted_logs_hashes: BoundedVec::new(), unencrypted_logs_hashes: BoundedVec::new(), - last_key_validation_requests: [Option::none(); NUM_KEY_TYPES] + last_key_validation_requests: [Option::none(); NUM_KEY_TYPES], } } @@ -127,11 +127,19 @@ impl PrivateContext { } fn push_nullifier(&mut self, nullifier: Field) { - self.nullifiers.push(Nullifier { value: nullifier, note_hash: 0, counter: self.next_counter() }); + self.nullifiers.push( + Nullifier { value: nullifier, note_hash: 0, counter: self.next_counter() }, + ); } fn push_nullifier_for_note_hash(&mut self, nullifier: Field, nullified_note_hash: Field) { - self.nullifiers.push(Nullifier { value: nullifier, note_hash: nullified_note_hash, counter: self.next_counter() }); + self.nullifiers.push( + Nullifier { + value: nullifier, + note_hash: nullified_note_hash, + counter: self.next_counter(), + }, + ); } // Returns the header of a block whose state is used during private execution (not the block the transaction is @@ -161,7 +169,9 @@ impl PrivateContext { max_block_number: self.max_block_number, note_hash_read_requests: self.note_hash_read_requests.storage, nullifier_read_requests: self.nullifier_read_requests.storage, - key_validation_requests_and_generators: self.key_validation_requests_and_generators.storage, + key_validation_requests_and_generators: self + .key_validation_requests_and_generators + .storage, note_hashes: self.note_hashes.storage, nullifiers: self.nullifiers.storage, private_call_requests: self.private_call_requests.storage, @@ -174,12 +184,15 @@ impl PrivateContext { encrypted_logs_hashes: self.encrypted_logs_hashes.storage, unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, historical_header: self.historical_header, - tx_context: self.inputs.tx_context + tx_context: self.inputs.tx_context, } } pub fn set_as_fee_payer(&mut self) { - dep::protocol_types::debug_log::debug_log_format("Setting {0} as fee payer", [self.this_address().to_field()]); + dep::protocol_types::debug_log::debug_log_format( + "Setting {0} as fee payer", + [self.this_address().to_field()], + ); self.is_fee_payer = true; } @@ -195,7 +208,8 @@ impl PrivateContext { // docs:start:max-block-number pub fn set_tx_max_block_number(&mut self, max_block_number: u32) { // docs:end:max-block-number - self.max_block_number = MaxBlockNumber::min_with_u32(self.max_block_number, max_block_number); + self.max_block_number = + MaxBlockNumber::min_with_u32(self.max_block_number, max_block_number); } pub fn push_note_hash_read_request(&mut self, note_hash: Field) { @@ -217,7 +231,8 @@ impl PrivateContext { } fn request_sk_app(&mut self, pk_m_hash: Field, key_index: Field) -> Field { - let cached_request = self.last_key_validation_requests[key_index].unwrap_or(KeyValidationRequest::empty()); + let cached_request = + self.last_key_validation_requests[key_index].unwrap_or(KeyValidationRequest::empty()); if cached_request.pk_m.hash() == pk_m_hash { // We get a match so the cached request is the latest one @@ -226,7 +241,10 @@ impl PrivateContext { // We didn't get a match meaning the cached result is stale. We fetch new values from oracle and instruct // protocol circuits to validate them by storing the validation request in context. let request = get_key_validation_request(pk_m_hash, key_index); - let request_and_generator = KeyValidationRequestAndGenerator { request, sk_app_generator: sk_generators[key_index] }; + let request_and_generator = KeyValidationRequestAndGenerator { + request, + sk_app_generator: sk_generators[key_index], + }; // We constrain that the pk_m_hash matches the one in the request (otherwise we could get an arbitrary // valid key request and not the one corresponding to pk_m_hash). assert(request.pk_m.hash() == pk_m_hash); @@ -254,7 +272,7 @@ impl PrivateContext { self.chain_id(), self.version(), content, - secret + secret, ); // Push nullifier (and the "commitment" corresponding to this can be "empty") @@ -268,7 +286,7 @@ impl PrivateContext { &mut self, randomness: Field, log: [u8; M], - log_hash: Field + log_hash: Field, ) { let counter = self.next_counter(); let contract_address = self.this_address(); @@ -279,7 +297,12 @@ impl PrivateContext { emit_encrypted_event_log(contract_address, randomness, log, counter); } - pub fn emit_raw_note_log(&mut self, note_hash_counter: u32, log: [u8; M], log_hash: Field) { + pub fn emit_raw_note_log( + &mut self, + note_hash_counter: u32, + log: [u8; M], + log_hash: Field, + ) { let counter = self.next_counter(); let len = log.len() as Field + 4; let side_effect = NoteLogHash { value: log_hash, counter, length: len, note_hash_counter }; @@ -292,28 +315,38 @@ impl PrivateContext { &mut self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field; ARGS_COUNT], ) -> PackedReturns { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, false) + self.call_private_function_with_packed_args( + contract_address, + function_selector, + args_hash, + false, + ) } pub fn static_call_private_function( &mut self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field; ARGS_COUNT], ) -> PackedReturns { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_private_function_with_packed_args(contract_address, function_selector, args_hash, true) + self.call_private_function_with_packed_args( + contract_address, + function_selector, + args_hash, + true, + ) } pub fn call_private_function_no_args( &mut self, contract_address: AztecAddress, - function_selector: FunctionSelector + function_selector: FunctionSelector, ) -> PackedReturns { self.call_private_function_with_packed_args(contract_address, function_selector, 0, false) } @@ -321,7 +354,7 @@ impl PrivateContext { pub fn static_call_private_function_no_args( &mut self, contract_address: AztecAddress, - function_selector: FunctionSelector + function_selector: FunctionSelector, ) -> PackedReturns { self.call_private_function_with_packed_args(contract_address, function_selector, 0, true) } @@ -331,7 +364,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - is_static_call: bool + is_static_call: bool, ) -> PackedReturns { let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call; let start_side_effect_counter = self.side_effect_counter; @@ -340,7 +373,7 @@ impl PrivateContext { function_selector, args_hash, start_side_effect_counter, - is_static_call + is_static_call, ); self.side_effect_counter = end_side_effect_counter + 1; @@ -352,16 +385,25 @@ impl PrivateContext { // | (item.public_inputs.min_revertible_side_effect_counter // > self.min_revertible_side_effect_counter) // ); - // if item.public_inputs.min_revertible_side_effect_counter // > self.min_revertible_side_effect_counter { // self.min_revertible_side_effect_counter = item.public_inputs.min_revertible_side_effect_counter; // } - - let call_context = CallContext { msg_sender: self.this_address(), contract_address, function_selector, is_static_call }; + let call_context = CallContext { + msg_sender: self.this_address(), + contract_address, + function_selector, + is_static_call, + }; self.private_call_requests.push( - PrivateCallRequest { call_context, args_hash, returns_hash, start_side_effect_counter, end_side_effect_counter } + PrivateCallRequest { + call_context, + args_hash, + returns_hash, + start_side_effect_counter, + end_side_effect_counter, + }, ); PackedReturns::new(returns_hash) @@ -371,28 +413,38 @@ impl PrivateContext { &mut self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field; ARGS_COUNT], ) { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, false) + self.call_public_function_with_packed_args( + contract_address, + function_selector, + args_hash, + false, + ) } pub fn static_call_public_function( &mut self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field; ARGS_COUNT], ) { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.call_public_function_with_packed_args(contract_address, function_selector, args_hash, true) + self.call_public_function_with_packed_args( + contract_address, + function_selector, + args_hash, + true, + ) } pub fn call_public_function_no_args( &mut self, contract_address: AztecAddress, - function_selector: FunctionSelector + function_selector: FunctionSelector, ) { self.call_public_function_with_packed_args(contract_address, function_selector, 0, false) } @@ -400,7 +452,7 @@ impl PrivateContext { pub fn static_call_public_function_no_args( &mut self, contract_address: AztecAddress, - function_selector: FunctionSelector + function_selector: FunctionSelector, ) { self.call_public_function_with_packed_args(contract_address, function_selector, 0, true) } @@ -410,7 +462,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - is_static_call: bool + is_static_call: bool, ) { let counter = self.next_counter(); @@ -426,14 +478,17 @@ impl PrivateContext { function_selector, args_hash, counter, - is_static_call + is_static_call, ); // Public calls are rerouted through the dispatch function. - let function_selector = comptime { - FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) + let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) }; + let call_context = CallContext { + msg_sender: self.this_address(), + contract_address, + function_selector, + is_static_call, }; - let call_context = CallContext { msg_sender: self.this_address(), contract_address, function_selector, is_static_call }; let call_request = PublicCallRequest { call_context, args_hash, counter }; self.public_call_requests.push(call_request); @@ -443,11 +498,16 @@ impl PrivateContext { &mut self, contract_address: AztecAddress, function_selector: FunctionSelector, - args: [Field; ARGS_COUNT] + args: [Field; ARGS_COUNT], ) { let args_hash = hash_args_array(args); arguments::pack_arguments_array(args); - self.set_public_teardown_function_with_packed_args(contract_address, function_selector, args_hash, false) + self.set_public_teardown_function_with_packed_args( + contract_address, + function_selector, + args_hash, + false, + ) } pub fn set_public_teardown_function_with_packed_args( @@ -455,7 +515,7 @@ impl PrivateContext { contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - is_static_call: bool + is_static_call: bool, ) { let counter = self.next_counter(); @@ -471,19 +531,18 @@ impl PrivateContext { function_selector, args_hash, counter, - is_static_call + is_static_call, ); - let function_selector = comptime { - FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) + let function_selector = comptime { FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR) }; + let call_context = CallContext { + msg_sender: self.this_address(), + contract_address, + function_selector, + is_static_call, }; - let call_context = CallContext { msg_sender: self.this_address(), contract_address, function_selector, is_static_call }; - self.public_teardown_call_request = PublicCallRequest { - call_context, - args_hash, - counter, - }; + self.public_teardown_call_request = PublicCallRequest { call_context, args_hash, counter }; } fn next_counter(&mut self) -> u32 { @@ -516,7 +575,7 @@ impl Empty for PrivateContext { note_encrypted_logs_hashes: BoundedVec::new(), encrypted_logs_hashes: BoundedVec::new(), unencrypted_logs_hashes: BoundedVec::new(), - last_key_validation_requests: [Option::none(); NUM_KEY_TYPES] + last_key_validation_requests: [Option::none(); NUM_KEY_TYPES], } } } diff --git a/noir-projects/aztec-nr/aztec/src/context/public_context.nr b/noir-projects/aztec-nr/aztec/src/context/public_context.nr index 089c209f620..8c09a49c8c0 100644 --- a/noir-projects/aztec-nr/aztec/src/context/public_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/public_context.nr @@ -7,7 +7,7 @@ use crate::context::gas::GasOpts; pub struct PublicContext { args_hash: Option, - compute_args_hash: fn () -> Field, + compute_args_hash: fn() -> Field, } impl PublicContext { @@ -15,7 +15,10 @@ impl PublicContext { PublicContext { args_hash: Option::none(), compute_args_hash } } - pub fn emit_unencrypted_log(_self: &mut Self, log: T) where T: Serialize { + pub fn emit_unencrypted_log(_self: &mut Self, log: T) + where + T: Serialize, + { emit_unencrypted_log(Serialize::serialize(log).as_slice()); } @@ -36,24 +39,27 @@ impl PublicContext { content: Field, secret: Field, sender: EthAddress, - leaf_index: Field + leaf_index: Field, ) { let secret_hash = compute_secret_hash(secret); let message_hash = compute_message_hash( sender, self.chain_id(), - /*recipient=*/ self.this_address(), + /*recipient=*/ + self.this_address(), self.version(), content, - secret_hash + secret_hash, ); let nullifier = compute_message_nullifier(message_hash, secret, leaf_index); assert( - !self.nullifier_exists(nullifier, self.this_address()), "L1-to-L2 message is already nullified" + !self.nullifier_exists(nullifier, self.this_address()), + "L1-to-L2 message is already nullified", ); assert( - self.l1_to_l2_msg_exists(message_hash, leaf_index), "Tried to consume nonexistent L1-to-L2 message" + self.l1_to_l2_msg_exists(message_hash, leaf_index), + "Tried to consume nonexistent L1-to-L2 message", ); self.push_nullifier(nullifier); @@ -68,14 +74,14 @@ impl PublicContext { contract_address: AztecAddress, function_selector: FunctionSelector, args: [Field], - gas_opts: GasOpts + gas_opts: GasOpts, ) -> FunctionReturns { let args = &[function_selector.to_field()].append(args); let results = call( gas_for_call(gas_opts), contract_address, args, - PUBLIC_DISPATCH_SELECTOR + PUBLIC_DISPATCH_SELECTOR, ); let data_to_return: [Field; RETURNS_COUNT] = results.0; let success: u8 = results.1; @@ -89,14 +95,14 @@ impl PublicContext { contract_address: AztecAddress, function_selector: FunctionSelector, args: [Field], - gas_opts: GasOpts + gas_opts: GasOpts, ) -> FunctionReturns { let args = &[function_selector.to_field()].append(args); let (data_to_return, success): ([Field; RETURNS_COUNT], u8) = call_static( gas_for_call(gas_opts), contract_address, args, - PUBLIC_DISPATCH_SELECTOR + PUBLIC_DISPATCH_SELECTOR, ); assert(success == 1, "Nested static call failed!"); @@ -169,7 +175,10 @@ impl PublicContext { out } - fn storage_read(self, storage_slot: Field) -> T where T: Deserialize { + fn storage_read(self, storage_slot: Field) -> T + where + T: Deserialize, + { T::deserialize(self.raw_storage_read(storage_slot)) } @@ -179,7 +188,10 @@ impl PublicContext { } } - fn storage_write(self, storage_slot: Field, value: T) where T: Serialize { + fn storage_write(self, storage_slot: Field, value: T) + where + T: Serialize, + { self.raw_storage_write(storage_slot, value.serialize()); } } @@ -188,10 +200,7 @@ impl PublicContext { fn gas_for_call(user_gas: GasOpts) -> [Field; 2] { // It's ok to use the max possible gas here, because the gas will be // capped by the gas left in the (STATIC)CALL instruction. - [ - user_gas.l2_gas.unwrap_or(MAX_FIELD_VALUE), - user_gas.da_gas.unwrap_or(MAX_FIELD_VALUE) - ] + [user_gas.l2_gas.unwrap_or(MAX_FIELD_VALUE), user_gas.da_gas.unwrap_or(MAX_FIELD_VALUE)] } // Unconstrained opcode wrappers (do not use directly). @@ -263,7 +272,7 @@ unconstrained fn call( gas: [Field; 2], address: AztecAddress, args: [Field], - function_selector: Field + function_selector: Field, ) -> ([Field; RET_SIZE], u8) { call_opcode(gas, address, args, function_selector) } @@ -271,7 +280,7 @@ unconstrained fn call_static( gas: [Field; 2], address: AztecAddress, args: [Field], - function_selector: Field + function_selector: Field, ) -> ([Field; RET_SIZE], u8) { call_static_opcode(gas, address, args, function_selector) } @@ -375,7 +384,7 @@ unconstrained fn call_opcode( address: AztecAddress, args: [Field], // TODO(5110): consider passing in calldata directly - function_selector: Field + function_selector: Field, ) -> ([Field; RET_SIZE], u8) {} // ^ return data ^ success @@ -385,7 +394,7 @@ unconstrained fn call_static_opcode( address: AztecAddress, args: [Field], // TODO(5110): consider passing in calldata directly - function_selector: Field + function_selector: Field, ) -> ([Field; RET_SIZE], u8) {} // ^ return data ^ success @@ -396,7 +405,7 @@ unconstrained fn storage_read_opcode(storage_slot: Field) -> Field {} unconstrained fn storage_write_opcode(storage_slot: Field, value: Field) {} pub struct FunctionReturns { - values: [Field; N] + values: [Field; N], } impl FunctionReturns { @@ -408,7 +417,10 @@ impl FunctionReturns { self.values } - pub fn deserialize_into(self) -> T where T: Deserialize { + pub fn deserialize_into(self) -> T + where + T: Deserialize, + { Deserialize::deserialize(self.raw()) } } diff --git a/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr b/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr index cc0cc68f08c..fad4adff72b 100644 --- a/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/unconstrained_context.nr @@ -1,5 +1,8 @@ use dep::protocol_types::{address::AztecAddress, traits::Deserialize}; -use crate::oracle::{execution::{get_chain_id, get_version, get_contract_address, get_block_number}, storage::storage_read}; +use crate::oracle::{ + execution::{get_chain_id, get_version, get_contract_address, get_block_number}, + storage::storage_read, +}; pub struct UnconstrainedContext { block_number: u32, @@ -54,10 +57,10 @@ impl UnconstrainedContext { storage_read(self.this_address(), storage_slot, self.block_number()) } - unconstrained fn storage_read( - self, - storage_slot: Field - ) -> T where T: Deserialize { + unconstrained fn storage_read(self, storage_slot: Field) -> T + where + T: Deserialize, + { T::deserialize(self.raw_storage_read(storage_slot)) } } diff --git a/noir-projects/aztec-nr/aztec/src/deploy.nr b/noir-projects/aztec-nr/aztec/src/deploy.nr index 919170e46f3..2920d1c9241 100644 --- a/noir-projects/aztec-nr/aztec/src/deploy.nr +++ b/noir-projects/aztec-nr/aztec/src/deploy.nr @@ -1,6 +1,9 @@ use crate::{context::PrivateContext, oracle::get_contract_instance::get_contract_instance}; -use dep::protocol_types::{address::AztecAddress, abis::function_selector::FunctionSelector, constants::DEPLOYER_CONTRACT_ADDRESS}; +use dep::protocol_types::{ + address::AztecAddress, abis::function_selector::FunctionSelector, + constants::DEPLOYER_CONTRACT_ADDRESS, +}; // Calls `deploy` on the deployer contract to deploy a new instance. pub fn deploy_contract(context: &mut PrivateContext, target: AztecAddress) { @@ -9,7 +12,8 @@ pub fn deploy_contract(context: &mut PrivateContext, target: AztecAddress) { let universal_deploy = instance.deployer.is_zero(); if !universal_deploy { assert( - instance.deployer == context.this_address(), "Deployer address does not match current address" + instance.deployer == context.this_address(), + "Deployer address does not match current address", ); } @@ -32,10 +36,10 @@ pub fn deploy_contract(context: &mut PrivateContext, target: AztecAddress) { let _call_result = context.call_private_function( DEPLOYER_CONTRACT_ADDRESS, comptime { - FunctionSelector::from_signature( - "deploy(Field,(Field),Field,(((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool))),bool)" - ) - }, - serialized_args + FunctionSelector::from_signature( + "deploy(Field,(Field),Field,(((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool)),((Field,Field,bool))),bool)", + ) + }, + serialized_args, ); } diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr index 63ba03f1850..960313d961f 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_event_emission.nr @@ -1,8 +1,11 @@ use crate::{ context::PrivateContext, event::event_interface::EventInterface, - encrypted_logs::payload::compute_encrypted_log, keys::getters::get_ovsk_app, oracle::random::random + encrypted_logs::payload::compute_encrypted_log, keys::getters::get_ovsk_app, + oracle::random::random, +}; +use dep::protocol_types::{ + address::AztecAddress, public_keys::{OvpkM, IvpkM}, hash::sha256_to_field, }; -use dep::protocol_types::{address::AztecAddress, public_keys::{OvpkM, IvpkM}, hash::sha256_to_field}; fn compute_raw_event_log( context: PrivateContext, @@ -11,11 +14,15 @@ fn compute_raw_event_log( ovsk_app: Field, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> ([u8; 416 + N * 32], Field) where Event: EventInterface { + recipient: AztecAddress, +) -> ([u8; 416 + N * 32], Field) +where + Event: EventInterface, +{ let contract_address: AztecAddress = context.this_address(); let plaintext = event.private_to_be_bytes(randomness); - let encrypted_log: [u8; 416 + N * 32] = compute_encrypted_log(contract_address, ovsk_app, ovpk, ivpk, recipient, plaintext); + let encrypted_log: [u8; 416 + N * 32] = + compute_encrypted_log(contract_address, ovsk_app, ovpk, ivpk, recipient, plaintext); let log_hash = sha256_to_field(encrypted_log); (encrypted_log, log_hash) } @@ -26,8 +33,11 @@ unconstrained fn compute_raw_event_log_unconstrained( randomness: Field, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> ([u8; 416 + N * 32], Field) where Event: EventInterface { + recipient: AztecAddress, +) -> ([u8; 416 + N * 32], Field) +where + Event: EventInterface, +{ let ovsk_app = get_ovsk_app(ovpk.hash()); compute_raw_event_log(context, event, randomness, ovsk_app, ovpk, ivpk, recipient) } @@ -36,18 +46,20 @@ pub fn encode_and_encrypt_event( context: &mut PrivateContext, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](Event) -> () where Event: EventInterface { - | e: Event | { + recipient: AztecAddress, +) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](Event) -> () +where + Event: EventInterface, +{ + |e: Event| { // We use the randomness to preserve function privacy by making it non brute-forceable, so a malicious sender could // use non-random values to reveal the plaintext. But they already know it themselves anyway, and is presumably not // interested in disclosing this information. We can therefore assume that the sender will cooperate in the random // value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; let ovsk_app: Field = context.request_ovsk_app(ovpk.hash()); - let (encrypted_log, log_hash) = compute_raw_event_log(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient); + let (encrypted_log, log_hash) = + compute_raw_event_log(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient); context.emit_raw_event_log_with_masked_address(randomness, encrypted_log, log_hash); } } @@ -56,17 +68,18 @@ pub fn encode_and_encrypt_event_unconstrained( context: &mut PrivateContext, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](Event) -> () where Event: EventInterface { - | e: Event | { + recipient: AztecAddress, +) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](Event) -> () +where + Event: EventInterface, +{ + |e: Event| { // We use the randomness to preserve function privacy by making it non brute-forceable, so a malicious sender could // use non-random values to reveal the plaintext. But they already know it themselves anyway, and is presumably not // interested in disclosing this information. We can therefore assume that the sender will cooperate in the random // value generation. - let randomness = unsafe { - random() - }; - let (encrypted_log, log_hash) = unsafe { + let randomness = unsafe { random() }; + let (encrypted_log, log_hash) = unsafe { compute_raw_event_log_unconstrained(*context, e, randomness, ovpk, ivpk, recipient) }; context.emit_raw_event_log_with_masked_address(randomness, encrypted_log, log_hash); @@ -81,11 +94,15 @@ pub fn encode_and_encrypt_event_with_randomness( randomness: Field, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> fn[(&mut PrivateContext, OvpkM, Field, IvpkM, AztecAddress)](Event) -> () where Event: EventInterface { - | e: Event | { + recipient: AztecAddress, +) -> fn[(&mut PrivateContext, OvpkM, Field, IvpkM, AztecAddress)](Event) -> () +where + Event: EventInterface, +{ + |e: Event| { let ovsk_app: Field = context.request_ovsk_app(ovpk.hash()); - let (encrypted_log, log_hash) = compute_raw_event_log(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient); + let (encrypted_log, log_hash) = + compute_raw_event_log(*context, e, randomness, ovsk_app, ovpk, ivpk, recipient); context.emit_raw_event_log_with_masked_address(randomness, encrypted_log, log_hash); } } @@ -95,9 +112,12 @@ pub fn encode_and_encrypt_event_with_randomness_unconstrained randomness: Field, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> fn[(&mut PrivateContext, Field, OvpkM, IvpkM, AztecAddress)](Event) -> () where Event: EventInterface { - | e: Event | { + recipient: AztecAddress, +) -> fn[(&mut PrivateContext, Field, OvpkM, IvpkM, AztecAddress)](Event) -> () +where + Event: EventInterface, +{ + |e: Event| { // Having the log hash be unconstrained here is fine because the way this works is we send the log hash // to the kernel, and it gets included as part of its public inputs. Then we send the tx to the sequencer, // which includes the kernel proof and the log preimages. The sequencer computes the hashes of the logs diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr index 11217da6ce4..698da4ee6e7 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/encrypted_note_emission.nr @@ -1,10 +1,10 @@ use crate::{ context::PrivateContext, note::{note_emission::NoteEmission, note_interface::NoteInterface}, - keys::getters::get_ovsk_app, encrypted_logs::payload::compute_encrypted_log + keys::getters::get_ovsk_app, encrypted_logs::payload::compute_encrypted_log, }; use dep::protocol_types::{ address::AztecAddress, public_keys::{PublicKeys, OvpkM, IvpkM}, hash::sha256_to_field, - abis::note_hash::NoteHash + abis::note_hash::NoteHash, }; fn compute_raw_note_log( @@ -13,8 +13,11 @@ fn compute_raw_note_log( ovsk_app: Field, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> (u32, [u8; 416 + N * 32], Field) where Note: NoteInterface { + recipient: AztecAddress, +) -> (u32, [u8; 416 + N * 32], Field) +where + Note: NoteInterface, +{ let note_header = note.get_header(); let note_hash_counter = note_header.note_hash_counter; let storage_slot = note_header.storage_slot; @@ -26,7 +29,8 @@ fn compute_raw_note_log( let contract_address: AztecAddress = context.this_address(); let plaintext = note.to_be_bytes(storage_slot); - let encrypted_log: [u8; 416 + N * 32] = compute_encrypted_log(contract_address, ovsk_app, ovpk, ivpk, recipient, plaintext); + let encrypted_log: [u8; 416 + N * 32] = + compute_encrypted_log(contract_address, ovsk_app, ovpk, ivpk, recipient, plaintext); let log_hash = sha256_to_field(encrypted_log); (note_hash_counter, encrypted_log, log_hash) @@ -37,8 +41,11 @@ unconstrained fn compute_raw_note_log_unconstrained( note: Note, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> (u32, [u8; 416 + N * 32], Field) where Note: NoteInterface { + recipient: AztecAddress, +) -> (u32, [u8; 416 + N * 32], Field) +where + Note: NoteInterface, +{ let ovsk_app = get_ovsk_app(ovpk.hash()); compute_raw_note_log(context, note, ovsk_app, ovpk, ivpk, recipient) } @@ -50,12 +57,16 @@ pub fn encode_and_encrypt_note( context: &mut PrivateContext, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](NoteEmission) -> () where Note: NoteInterface { - | e: NoteEmission | { - let ovsk_app: Field = context.request_ovsk_app(ovpk.hash()); + recipient: AztecAddress, +) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](NoteEmission) -> () +where + Note: NoteInterface, +{ + |e: NoteEmission| { + let ovsk_app: Field = context.request_ovsk_app(ovpk.hash()); - let (note_hash_counter, encrypted_log, log_hash) = compute_raw_note_log(*context, e.note, ovsk_app, ovpk, ivpk, recipient); + let (note_hash_counter, encrypted_log, log_hash) = + compute_raw_note_log(*context, e.note, ovsk_app, ovpk, ivpk, recipient); context.emit_raw_note_log(note_hash_counter, encrypted_log, log_hash); } } @@ -64,9 +75,12 @@ pub fn encode_and_encrypt_note_unconstrained( context: &mut PrivateContext, ovpk: OvpkM, ivpk: IvpkM, - recipient: AztecAddress -) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](NoteEmission) -> () where Note: NoteInterface { - | e: NoteEmission | { + recipient: AztecAddress, +) -> fn[(&mut PrivateContext, OvpkM, IvpkM, AztecAddress)](NoteEmission) -> () +where + Note: NoteInterface, +{ + |e: NoteEmission| { // Having the log hash be unconstrained here is fine because the way this works is we send the log hash // to the kernel, and it gets included as part of its public inputs. Then we send the tx to the sequencer, // which includes the kernel proof and the log preimages. The sequencer computes the hashes of the logs @@ -86,9 +100,8 @@ pub fn encode_and_encrypt_note_unconstrained( // for the log to be deleted when it shouldn't have (which is fine - they can already make the content be // whatever), or cause for the log to not be deleted when it should have (which is also fine - it'll be a log // for a note that doesn't exist). - let (note_hash_counter, encrypted_log, log_hash) = unsafe { - compute_raw_note_log_unconstrained(*context, e.note, ovpk, ivpk, recipient) - }; + let (note_hash_counter, encrypted_log, log_hash) = + unsafe { compute_raw_note_log_unconstrained(*context, e.note, ovpk, ivpk, recipient) }; context.emit_raw_note_log(note_hash_counter, encrypted_log, log_hash); } } @@ -101,9 +114,9 @@ pub fn encrypt_and_emit_partial_log( context: &mut PrivateContext, log_plaintext: [u8; M], recipient_keys: PublicKeys, - recipient: AztecAddress + recipient: AztecAddress, ) { - let ovsk_app: Field = context.request_ovsk_app(recipient_keys.ovpk_m.hash()); + let ovsk_app: Field = context.request_ovsk_app(recipient_keys.ovpk_m.hash()); let encrypted_log: [u8; 352 + M] = compute_encrypted_log( context.this_address(), @@ -111,7 +124,7 @@ pub fn encrypt_and_emit_partial_log( recipient_keys.ovpk_m, recipient_keys.ivpk_m, recipient, - log_plaintext + log_plaintext, ); let log_hash = sha256_to_field(encrypted_log); diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr index ed61f0a6e3d..1872fbb21d8 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/header.nr @@ -1,4 +1,6 @@ -use dep::protocol_types::{address::AztecAddress, public_keys::{PublicKeys, IvpkM, ToPoint}, scalar::Scalar, point::Point}; +use dep::protocol_types::{ + address::AztecAddress, public_keys::{PublicKeys, IvpkM, ToPoint}, scalar::Scalar, point::Point, +}; use crate::keys::point_to_symmetric_key::point_to_symmetric_key; @@ -13,7 +15,10 @@ impl EncryptedLogHeader { EncryptedLogHeader { address } } - fn compute_ciphertext(self, secret: Scalar, pk: T) -> [u8; 48] where T: ToPoint { + fn compute_ciphertext(self, secret: Scalar, pk: T) -> [u8; 48] + where + T: ToPoint, + { let full_key = point_to_symmetric_key(secret, pk.to_point()); let mut sym_key = [0; 16]; let mut iv = [0; 16]; @@ -34,14 +39,14 @@ unconstrained fn test_encrypted_log_header_matches_noir() { let header = EncryptedLogHeader::new(address); let secret = Scalar { lo: 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd, - hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06 + hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06, }; let point = IvpkM { inner: Point { x: 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186, y: 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e, - is_infinite: false - } + is_infinite: false, + }, }; let ciphertext = header.compute_ciphertext(secret, point); @@ -49,7 +54,9 @@ unconstrained fn test_encrypted_log_header_matches_noir() { // The following value was generated by `encrypted_log_header.test.ts`. // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let expected_header_ciphertext_from_typescript = [ - 226, 240, 253, 6, 28, 52, 19, 131, 33, 132, 178, 212, 245, 62, 14, 190, 194, 44, 7, 131, 160, 83, 64, 181, 98, 38, 153, 214, 62, 171, 253, 161, 111, 191, 28, 247, 216, 26, 222, 171, 176, 218, 48, 209, 73, 89, 200, 209 + 226, 240, 253, 6, 28, 52, 19, 131, 33, 132, 178, 212, 245, 62, 14, 190, 194, 44, 7, 131, + 160, 83, 64, 181, 98, 38, 153, 214, 62, 171, 253, 161, 111, 191, 28, 247, 216, 26, 222, 171, + 176, 218, 48, 209, 73, 89, 200, 209, ]; assert_eq(ciphertext, expected_header_ciphertext_from_typescript); diff --git a/noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr b/noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr index 8b8577f980d..60dad2821f0 100644 --- a/noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr +++ b/noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr @@ -1,15 +1,16 @@ use dep::protocol_types::{ address::AztecAddress, scalar::Scalar, point::Point, public_keys::{OvpkM, IvpkM}, - constants::GENERATOR_INDEX__SYMMETRIC_KEY, hash::poseidon2_hash_with_separator + constants::GENERATOR_INDEX__SYMMETRIC_KEY, hash::poseidon2_hash_with_separator, }; use std::{ aes128::aes128_encrypt, embedded_curve_ops::fixed_base_scalar_mul as derive_public_key, - hash::from_field_unsafe as fr_to_fq_unsafe, field::bn254::decompose + hash::from_field_unsafe as fr_to_fq_unsafe, field::bn254::decompose, }; use crate::{ - oracle::random::random, utils::point::point_to_bytes, encrypted_logs::{header::EncryptedLogHeader}, - keys::{point_to_symmetric_key::point_to_symmetric_key} + oracle::random::random, utils::point::point_to_bytes, + encrypted_logs::header::EncryptedLogHeader, + keys::point_to_symmetric_key::point_to_symmetric_key, }; pub fn compute_encrypted_log( @@ -18,7 +19,7 @@ pub fn compute_encrypted_log( ovpk: OvpkM, ivpk: IvpkM, recipient: AztecAddress, - plaintext: [u8; P] + plaintext: [u8; P], ) -> [u8; M] { let (eph_sk, eph_pk) = generate_ephemeral_key_pair(); @@ -27,11 +28,11 @@ pub fn compute_encrypted_log( let incoming_header_ciphertext: [u8; 48] = header.compute_ciphertext(eph_sk, ivpk); let outgoing_header_ciphertext: [u8; 48] = header.compute_ciphertext(eph_sk, ovpk); let incoming_body_ciphertext = compute_incoming_body_ciphertext(plaintext, eph_sk, ivpk); - let outgoing_body_ciphertext: [u8; 144] = compute_outgoing_body_ciphertext(recipient, ivpk, fr_to_fq(ovsk_app), eph_sk, eph_pk); + let outgoing_body_ciphertext: [u8; 144] = + compute_outgoing_body_ciphertext(recipient, ivpk, fr_to_fq(ovsk_app), eph_sk, eph_pk); let mut encrypted_bytes: [u8; M] = [0; M]; // @todo We ignore the tags for now - let eph_pk_bytes = point_to_bytes(eph_pk); for i in 0..32 { encrypted_bytes[64 + i] = eph_pk_bytes[i]; @@ -72,14 +73,11 @@ fn fr_to_fq(r: Field) -> Scalar { fn generate_ephemeral_key_pair() -> (Scalar, Point) { // @todo Need to draw randomness from the full domain of Fq not only Fr - // We use the randomness to preserve the privacy of both the sender and recipient via encryption, so a malicious // sender could use non-random values to reveal the plaintext. But they already know it themselves anyway, and so // the recipient already trusts them to not disclose this information. We can therefore assume that the sender will // cooperate in the random value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; // We use the unsafe version of `fr_to_fq` because multi_scalar_mul (called by derive_public_key) will constrain // the scalars. @@ -89,7 +87,11 @@ fn generate_ephemeral_key_pair() -> (Scalar, Point) { (eph_sk, eph_pk) } -pub fn compute_incoming_body_ciphertext(plaintext: [u8; P], eph_sk: Scalar, ivpk: IvpkM) -> [u8] { +pub fn compute_incoming_body_ciphertext( + plaintext: [u8; P], + eph_sk: Scalar, + ivpk: IvpkM, +) -> [u8] { let full_key = point_to_symmetric_key(eph_sk, ivpk.to_point()); let mut sym_key = [0; 16]; let mut iv = [0; 16]; @@ -108,11 +110,10 @@ pub fn compute_outgoing_body_ciphertext( recipient_ivpk: IvpkM, ovsk_app: Scalar, eph_sk: Scalar, - eph_pk: Point + eph_pk: Point, ) -> [u8; 144] { // Again, we could compute `eph_pk` here, but we keep the interface more similar // and also make it easier to optimise it later as we just pass it along - let mut buffer = [0 as u8; 128]; let serialized_eph_sk_high: [u8; 32] = eph_sk.hi.to_be_bytes(); @@ -133,8 +134,9 @@ pub fn compute_outgoing_body_ciphertext( // We compute the symmetric key using poseidon. let full_key: [u8; 32] = poseidon2_hash_with_separator( [ovsk_app.hi, ovsk_app.lo, eph_pk.x, eph_pk.y], - GENERATOR_INDEX__SYMMETRIC_KEY as Field - ).to_be_bytes(); + GENERATOR_INDEX__SYMMETRIC_KEY as Field, + ) + .to_be_bytes(); let mut sym_key = [0; 16]; let mut iv = [0; 16]; @@ -147,46 +149,88 @@ pub fn compute_outgoing_body_ciphertext( } mod test { - use crate::{encrypted_logs::payload::{compute_encrypted_log, compute_incoming_body_ciphertext, compute_outgoing_body_ciphertext}}; + use crate::encrypted_logs::payload::{ + compute_encrypted_log, compute_incoming_body_ciphertext, compute_outgoing_body_ciphertext, + }; use std::embedded_curve_ops::fixed_base_scalar_mul as derive_public_key; - use dep::protocol_types::{address::AztecAddress, public_keys::{OvpkM, IvpkM}, point::Point, scalar::Scalar}; + use dep::protocol_types::{ + address::AztecAddress, public_keys::{OvpkM, IvpkM}, point::Point, scalar::Scalar, + }; use std::test::OracleMock; #[test] unconstrained fn test_encrypted_log_matches_typescript() { // All the values in this test were copied over from `tagged_log.test.ts` - let contract_address = AztecAddress::from_field(0x10f48cd9eff7ae5b209c557c70de2e657ee79166868676b787e9417e19260e04); + let contract_address = AztecAddress::from_field( + 0x10f48cd9eff7ae5b209c557c70de2e657ee79166868676b787e9417e19260e04, + ); let ovsk_app = 0x03a6513d6def49f41d20373d2cec894c23e7492794b08fc50c0e8a1bd2512612; let ovpk_m = OvpkM { inner: Point { x: 0x1961448682803198631f299340e4206bb12809d4bebbf012b30f59af73ba1a15, y: 0x133674060c3925142aceb4f1dcd9f9137d0217d37ff8729ee5ceaa6e2790353d, - is_infinite: false - } + is_infinite: false, + }, }; let ivpk_m = IvpkM { inner: Point { x: 0x260cd3904f6df16e974c29944fdc839e40fb5cf293f03df2eb370851d3a527bc, y: 0x0eef2964fe6640e84c82b5d2915892409b38e9e25d39f68dd79edb725c55387f, - is_infinite: false - } + is_infinite: false, + }, }; let plaintext = [ - 0, 0, 0, 1, 48, 22, 64, 206, 234, 117, 131, 145, 178, 225, 97, 201, 44, 5, 19, 241, 41, 2, 15, 65, 37, 37, 106, 253, 174, 38, 70, 206, 49, 9, 159, 92, 16, 244, 140, 217, 239, 247, 174, 91, 32, 156, 85, 124, 112, 222, 46, 101, 126, 231, 145, 102, 134, 134, 118, 183, 135, 233, 65, 126, 25, 38, 14, 4, 15, 228, 107, 229, 131, 183, 31, 74, 181, 183, 12, 38, 87, 255, 29, 5, 204, 207, 29, 41, 42, 147, 105, 98, 141, 26, 25, 79, 148, 78, 101, 153, 0, 0, 16, 39 + 0, 0, 0, 1, 48, 22, 64, 206, 234, 117, 131, 145, 178, 225, 97, 201, 44, 5, 19, 241, 41, + 2, 15, 65, 37, 37, 106, 253, 174, 38, 70, 206, 49, 9, 159, 92, 16, 244, 140, 217, 239, + 247, 174, 91, 32, 156, 85, 124, 112, 222, 46, 101, 126, 231, 145, 102, 134, 134, 118, + 183, 135, 233, 65, 126, 25, 38, 14, 4, 15, 228, 107, 229, 131, 183, 31, 74, 181, 183, + 12, 38, 87, 255, 29, 5, 204, 207, 29, 41, 42, 147, 105, 98, 141, 26, 25, 79, 148, 78, + 101, 153, 0, 0, 16, 39, ]; let eph_sk = 0x1358d15019d4639393d62b97e1588c095957ce74a1c32d6ec7d62fe6705d9538; let _ = OracleMock::mock("getRandomField").returns(eph_sk); - let recipient = AztecAddress::from_field(0x10ee41ee4b62703b16f61e03cb0d88c4b306a9eb4a6ceeb2aff13428541689a2); + let recipient = AztecAddress::from_field( + 0x10ee41ee4b62703b16f61e03cb0d88c4b306a9eb4a6ceeb2aff13428541689a2, + ); - let log: [u8; 448] = compute_encrypted_log(contract_address, ovsk_app, ovpk_m, ivpk_m, recipient, plaintext); + let log: [u8; 448] = compute_encrypted_log( + contract_address, + ovsk_app, + ovpk_m, + ivpk_m, + recipient, + plaintext, + ); // The following value was generated by `tagged_log.test.ts` // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let encrypted_log_from_typescript = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 70, 12, 14, 67, 77, 132, 110, 193, 234, 40, 110, 64, 144, 235, 86, 55, 111, 242, 123, 221, 193, 170, 202, 225, 216, 86, 84, 159, 112, 31, 167, 126, 79, 51, 186, 47, 71, 253, 172, 99, 112, 241, 59, 197, 241, 107, 186, 232, 87, 187, 230, 171, 62, 228, 234, 42, 51, 145, 146, 238, 242, 42, 71, 206, 13, 244, 66, 111, 195, 20, 203, 98, 148, 204, 242, 145, 183, 156, 29, 141, 54, 44, 220, 194, 35, 229, 16, 32, 204, 211, 49, 142, 112, 82, 202, 116, 241, 254, 146, 42, 217, 20, 189, 70, 228, 182, 171, 205, 104, 27, 99, 171, 28, 91, 244, 21, 30, 130, 240, 5, 72, 174, 124, 97, 197, 157, 248, 193, 23, 193, 76, 46, 141, 144, 70, 211, 45, 67, 167, 218, 129, 140, 104, 190, 41, 110, 249, 209, 68, 106, 135, 164, 80, 235, 63, 101, 80, 32, 13, 38, 99, 145, 91, 11, 173, 151, 231, 247, 65, 153, 117, 229, 167, 64, 239, 182, 126, 235, 83, 4, 169, 8, 8, 160, 4, 235, 252, 21, 96, 84, 161, 69, 145, 145, 215, 254, 161, 117, 246, 198, 65, 89, 179, 194, 90, 19, 121, 12, 202, 114, 80, 195, 14, 60, 128, 105, 142, 100, 86, 90, 108, 157, 219, 22, 172, 20, 121, 195, 25, 159, 236, 2, 70, 75, 42, 37, 34, 2, 17, 149, 20, 176, 32, 18, 204, 56, 117, 121, 34, 15, 3, 88, 123, 64, 68, 74, 233, 63, 59, 131, 222, 194, 192, 167, 110, 217, 10, 128, 73, 129, 172, 61, 43, 12, 98, 165, 203, 191, 154, 161, 150, 4, 239, 95, 48, 60, 159, 33, 222, 142, 102, 73, 193, 236, 145, 197, 160, 216, 254, 113, 243, 25, 244, 251, 192, 222, 35, 7, 114, 101, 35, 152, 151, 112, 24, 32, 94, 138, 71, 160, 91, 68, 131, 217, 117, 140, 19, 147, 37, 197, 192, 21, 43, 172, 239, 239, 205, 15, 110, 76, 26, 211, 42, 117, 4, 15, 135, 145, 247, 37, 73, 84, 164, 149, 250, 35, 0, 205, 105, 178, 143, 104, 98, 100, 250, 193, 154, 136, 175, 177, 109, 225, 207, 252, 147, 250, 250, 189, 117, 147, 101, 230, 132 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 141, 70, 12, 14, 67, 77, 132, 110, 193, 234, 40, 110, 64, 144, 235, + 86, 55, 111, 242, 123, 221, 193, 170, 202, 225, 216, 86, 84, 159, 112, 31, 167, 126, 79, + 51, 186, 47, 71, 253, 172, 99, 112, 241, 59, 197, 241, 107, 186, 232, 87, 187, 230, 171, + 62, 228, 234, 42, 51, 145, 146, 238, 242, 42, 71, 206, 13, 244, 66, 111, 195, 20, 203, + 98, 148, 204, 242, 145, 183, 156, 29, 141, 54, 44, 220, 194, 35, 229, 16, 32, 204, 211, + 49, 142, 112, 82, 202, 116, 241, 254, 146, 42, 217, 20, 189, 70, 228, 182, 171, 205, + 104, 27, 99, 171, 28, 91, 244, 21, 30, 130, 240, 5, 72, 174, 124, 97, 197, 157, 248, + 193, 23, 193, 76, 46, 141, 144, 70, 211, 45, 67, 167, 218, 129, 140, 104, 190, 41, 110, + 249, 209, 68, 106, 135, 164, 80, 235, 63, 101, 80, 32, 13, 38, 99, 145, 91, 11, 173, + 151, 231, 247, 65, 153, 117, 229, 167, 64, 239, 182, 126, 235, 83, 4, 169, 8, 8, 160, 4, + 235, 252, 21, 96, 84, 161, 69, 145, 145, 215, 254, 161, 117, 246, 198, 65, 89, 179, 194, + 90, 19, 121, 12, 202, 114, 80, 195, 14, 60, 128, 105, 142, 100, 86, 90, 108, 157, 219, + 22, 172, 20, 121, 195, 25, 159, 236, 2, 70, 75, 42, 37, 34, 2, 17, 149, 20, 176, 32, 18, + 204, 56, 117, 121, 34, 15, 3, 88, 123, 64, 68, 74, 233, 63, 59, 131, 222, 194, 192, 167, + 110, 217, 10, 128, 73, 129, 172, 61, 43, 12, 98, 165, 203, 191, 154, 161, 150, 4, 239, + 95, 48, 60, 159, 33, 222, 142, 102, 73, 193, 236, 145, 197, 160, 216, 254, 113, 243, 25, + 244, 251, 192, 222, 35, 7, 114, 101, 35, 152, 151, 112, 24, 32, 94, 138, 71, 160, 91, + 68, 131, 217, 117, 140, 19, 147, 37, 197, 192, 21, 43, 172, 239, 239, 205, 15, 110, 76, + 26, 211, 42, 117, 4, 15, 135, 145, 247, 37, 73, 84, 164, 149, 250, 35, 0, 205, 105, 178, + 143, 104, 98, 100, 250, 193, 154, 136, 175, 177, 109, 225, 207, 252, 147, 250, 250, 189, + 117, 147, 101, 230, 132, ]; assert_eq(encrypted_log_from_typescript, log); } @@ -196,17 +240,22 @@ mod test { // All the values in this test were copied over from `encrypted_note_log_incoming_body.test.ts` let eph_sk = Scalar { lo: 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd, - hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06 + hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06, }; let ivpk = IvpkM { inner: Point { x: 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186, y: 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e, - is_infinite: false - } + is_infinite: false, + }, }; let plaintext = [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ]; // `compute_incoming_body_ciphertext(...)` function then derives symmetric key from `eph_sk` and `ivpk` and encrypts @@ -216,7 +265,16 @@ mod test { // The following value was generated by `encrypted_note_log_incoming_body.test.ts`. // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let note_body_ciphertext_from_typescript = [ - 226, 240, 253, 6, 28, 52, 19, 131, 33, 132, 178, 212, 245, 62, 14, 190, 147, 228, 160, 190, 146, 61, 95, 203, 124, 153, 68, 168, 17, 150, 92, 0, 99, 214, 85, 64, 191, 78, 157, 131, 149, 96, 236, 253, 96, 172, 157, 30, 27, 176, 228, 74, 242, 190, 138, 48, 33, 93, 46, 37, 223, 130, 25, 245, 188, 163, 159, 223, 187, 24, 139, 206, 131, 154, 159, 130, 37, 17, 158, 114, 242, 141, 124, 193, 232, 54, 146, 96, 145, 100, 125, 234, 57, 43, 95, 115, 183, 39, 121, 232, 134, 229, 148, 25, 46, 77, 87, 127, 95, 7, 77, 188, 37, 234, 245, 142, 232, 87, 252, 28, 67, 67, 90, 214, 254, 89, 47, 68, 66, 187, 227, 8, 59, 162, 25, 141, 97, 141, 217, 197, 115, 15, 212, 202, 157, 41, 150, 62, 219, 57, 224, 92, 185, 212, 142, 94, 146, 41, 178, 145, 68, 169, 23, 185, 206, 138, 70, 47, 176, 210, 165, 236, 23, 206, 229, 108 + 226, 240, 253, 6, 28, 52, 19, 131, 33, 132, 178, 212, 245, 62, 14, 190, 147, 228, 160, + 190, 146, 61, 95, 203, 124, 153, 68, 168, 17, 150, 92, 0, 99, 214, 85, 64, 191, 78, 157, + 131, 149, 96, 236, 253, 96, 172, 157, 30, 27, 176, 228, 74, 242, 190, 138, 48, 33, 93, + 46, 37, 223, 130, 25, 245, 188, 163, 159, 223, 187, 24, 139, 206, 131, 154, 159, 130, + 37, 17, 158, 114, 242, 141, 124, 193, 232, 54, 146, 96, 145, 100, 125, 234, 57, 43, 95, + 115, 183, 39, 121, 232, 134, 229, 148, 25, 46, 77, 87, 127, 95, 7, 77, 188, 37, 234, + 245, 142, 232, 87, 252, 28, 67, 67, 90, 214, 254, 89, 47, 68, 66, 187, 227, 8, 59, 162, + 25, 141, 97, 141, 217, 197, 115, 15, 212, 202, 157, 41, 150, 62, 219, 57, 224, 92, 185, + 212, 142, 94, 146, 41, 178, 145, 68, 169, 23, 185, 206, 138, 70, 47, 176, 210, 165, 236, + 23, 206, 229, 108, ]; assert_eq(note_body_ciphertext_from_typescript.len(), ciphertext.len()); @@ -230,15 +288,15 @@ mod test { fn test_encrypted_log_outgoing_body_matches_typescript() { let eph_sk = Scalar { lo: 0x00000000000000000000000000000000d0d302ee245dfaf2807e604eec4715fe, - hi: 0x000000000000000000000000000000000f096b423017226a18461115fa8d34bb + hi: 0x000000000000000000000000000000000f096b423017226a18461115fa8d34bb, }; let recipient_ivsk = Scalar { lo: 0x000000000000000000000000000000004828f8f95676ebb481df163f87fd4022, - hi: 0x000000000000000000000000000000000f4d97c25d578f9348251a71ca17ae31 + hi: 0x000000000000000000000000000000000f4d97c25d578f9348251a71ca17ae31, }; let sender_ovsk_app = Scalar { lo: 0x0000000000000000000000000000000074d2e28c6bc5176ac02cf7c7d36a444e, - hi: 0x00000000000000000000000000000000089c6887cb1446d86c64e81afc78048b + hi: 0x00000000000000000000000000000000089c6887cb1446d86c64e81afc78048b, }; let eph_pk = derive_public_key(eph_sk); @@ -246,12 +304,25 @@ mod test { let recipient = AztecAddress::from_field(0xdeadbeef); - let ciphertext = compute_outgoing_body_ciphertext(recipient, recipient_ivpk, sender_ovsk_app, eph_sk, eph_pk); + let ciphertext = compute_outgoing_body_ciphertext( + recipient, + recipient_ivpk, + sender_ovsk_app, + eph_sk, + eph_pk, + ); // The following value was generated by `encrypted_log_outgoing_body.test.ts` // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let outgoing_body_ciphertext_from_typescript = [ - 127, 182, 227, 75, 192, 197, 54, 47, 168, 134, 233, 148, 251, 46, 86, 12, 73, 50, 238, 50, 31, 174, 27, 202, 110, 77, 161, 197, 244, 124, 17, 100, 143, 150, 232, 14, 156, 248, 43, 177, 16, 82, 244, 103, 88, 74, 84, 200, 15, 65, 187, 14, 163, 60, 91, 22, 104, 31, 211, 190, 124, 121, 79, 92, 239, 65, 185, 106, 51, 178, 168, 137, 84, 43, 79, 158, 151, 152, 83, 42, 170, 13, 106, 209, 254, 74, 39, 145, 73, 215, 17, 234, 196, 89, 30, 58, 120, 127, 88, 69, 121, 61, 18, 206, 89, 118, 243, 238, 177, 71, 73, 47, 147, 4, 155, 25, 173, 248, 206, 52, 17, 180, 122, 186, 106, 191, 252, 102, 197, 91, 16, 39, 94, 91, 224, 30, 168, 177, 26, 144, 5, 124, 128, 6 + 127, 182, 227, 75, 192, 197, 54, 47, 168, 134, 233, 148, 251, 46, 86, 12, 73, 50, 238, + 50, 31, 174, 27, 202, 110, 77, 161, 197, 244, 124, 17, 100, 143, 150, 232, 14, 156, 248, + 43, 177, 16, 82, 244, 103, 88, 74, 84, 200, 15, 65, 187, 14, 163, 60, 91, 22, 104, 31, + 211, 190, 124, 121, 79, 92, 239, 65, 185, 106, 51, 178, 168, 137, 84, 43, 79, 158, 151, + 152, 83, 42, 170, 13, 106, 209, 254, 74, 39, 145, 73, 215, 17, 234, 196, 89, 30, 58, + 120, 127, 88, 69, 121, 61, 18, 206, 89, 118, 243, 238, 177, 71, 73, 47, 147, 4, 155, 25, + 173, 248, 206, 52, 17, 180, 122, 186, 106, 191, 252, 102, 197, 91, 16, 39, 94, 91, 224, + 30, 168, 177, 26, 144, 5, 124, 128, 6, ]; assert_eq(outgoing_body_ciphertext_from_typescript, ciphertext); diff --git a/noir-projects/aztec-nr/aztec/src/generators.nr b/noir-projects/aztec-nr/aztec/src/generators.nr index 03b9df31273..7671d8f28c8 100644 --- a/noir-projects/aztec-nr/aztec/src/generators.nr +++ b/noir-projects/aztec-nr/aztec/src/generators.nr @@ -1,13 +1,37 @@ use dep::protocol_types::point::Point; // A set of generators generated with `derive_generators(...)` function from noir::std -global Ga1 = Point { x: 0x30426e64aee30e998c13c8ceecda3a77807dbead52bc2f3bf0eae851b4b710c1, y: 0x113156a068f603023240c96b4da5474667db3b8711c521c748212a15bc034ea6, is_infinite: false }; -global Ga2 = Point { x: 0x2825c79cc6a5cbbeef7d6a8f1b6a12b312aa338440aefeb4396148c89147c049, y: 0x129bfd1da54b7062d6b544e7e36b90736350f6fba01228c41c72099509f5701e, is_infinite: false }; -global Ga3 = Point { x: 0x0edb1e293c3ce91bfc04e3ceaa50d2c541fa9d091c72eb403efb1cfa2cb3357f, y: 0x1341d675fa030ece3113ad53ca34fd13b19b6e9762046734f414824c4d6ade35, is_infinite: false }; -global Ga4 = Point { x: 0x0e0dad2250583f2a9f0acb04ededf1701b85b0393cae753fe7e14b88af81cb52, y: 0x0973b02c5caac339ee4ad5dab51329920f7bf1b6a07e1dabe5df67040b300962, is_infinite: false }; -global Ga5 = Point { x: 0x2f3342e900e8c488a28931aae68970738fdc68afde2910de7b320c00c902087d, y: 0x1bf958dc63cb09d59230603a0269ae86d6f92494da244910351f1132df20fc08, is_infinite: false }; +global Ga1 = Point { + x: 0x30426e64aee30e998c13c8ceecda3a77807dbead52bc2f3bf0eae851b4b710c1, + y: 0x113156a068f603023240c96b4da5474667db3b8711c521c748212a15bc034ea6, + is_infinite: false, +}; +global Ga2 = Point { + x: 0x2825c79cc6a5cbbeef7d6a8f1b6a12b312aa338440aefeb4396148c89147c049, + y: 0x129bfd1da54b7062d6b544e7e36b90736350f6fba01228c41c72099509f5701e, + is_infinite: false, +}; +global Ga3 = Point { + x: 0x0edb1e293c3ce91bfc04e3ceaa50d2c541fa9d091c72eb403efb1cfa2cb3357f, + y: 0x1341d675fa030ece3113ad53ca34fd13b19b6e9762046734f414824c4d6ade35, + is_infinite: false, +}; +global Ga4 = Point { + x: 0x0e0dad2250583f2a9f0acb04ededf1701b85b0393cae753fe7e14b88af81cb52, + y: 0x0973b02c5caac339ee4ad5dab51329920f7bf1b6a07e1dabe5df67040b300962, + is_infinite: false, +}; +global Ga5 = Point { + x: 0x2f3342e900e8c488a28931aae68970738fdc68afde2910de7b320c00c902087d, + y: 0x1bf958dc63cb09d59230603a0269ae86d6f92494da244910351f1132df20fc08, + is_infinite: false, +}; // If you change this update `G_SLOT` in `yarn-project/simulator/src/client/test_utils.ts` as well -global G_slot = Point { x: 0x041223147b680850dc82e8a55a952d4df20256fe0593d949a9541ca00f0abf15, y: 0x0a8c72e60d0e60f5d804549d48f3044d06140b98ed717a9b532af630c1530791, is_infinite: false }; +global G_slot = Point { + x: 0x041223147b680850dc82e8a55a952d4df20256fe0593d949a9541ca00f0abf15, + y: 0x0a8c72e60d0e60f5d804549d48f3044d06140b98ed717a9b532af630c1530791, + is_infinite: false, +}; mod test { use crate::generators::{Ga1, Ga2, Ga3, Ga4, Ga5, G_slot}; diff --git a/noir-projects/aztec-nr/aztec/src/hash.nr b/noir-projects/aztec-nr/aztec/src/hash.nr index b96fec6e1a5..c58c78dbb82 100644 --- a/noir-projects/aztec-nr/aztec/src/hash.nr +++ b/noir-projects/aztec-nr/aztec/src/hash.nr @@ -1,8 +1,10 @@ use dep::protocol_types::{ address::{AztecAddress, EthAddress}, - constants::{GENERATOR_INDEX__SECRET_HASH, GENERATOR_INDEX__MESSAGE_NULLIFIER, GENERATOR_INDEX__FUNCTION_ARGS}, - point::Point, traits::Hash, - hash::{sha256_to_field, poseidon2_hash_with_separator, poseidon2_hash_with_separator_slice} + constants::{ + GENERATOR_INDEX__SECRET_HASH, GENERATOR_INDEX__MESSAGE_NULLIFIER, + GENERATOR_INDEX__FUNCTION_ARGS, + }, point::Point, traits::Hash, + hash::{sha256_to_field, poseidon2_hash_with_separator, poseidon2_hash_with_separator_slice}, }; use crate::utils::to_bytes::{arr_to_be_bytes_arr, str_to_be_bytes_arr}; @@ -16,7 +18,10 @@ pub fn compute_secret_hash(secret: Field) -> Field { poseidon2_hash_with_separator([secret], GENERATOR_INDEX__SECRET_HASH) } -pub fn compute_unencrypted_log_hash(contract_address: AztecAddress, log: [u8; N]) -> Field { +pub fn compute_unencrypted_log_hash( + contract_address: AztecAddress, + log: [u8; N], +) -> Field { let mut hash_bytes = [0; N + 36]; // Address is converted to 32 bytes in ts let address_bytes: [u8; 32] = contract_address.to_field().to_be_bytes(); @@ -40,7 +45,7 @@ pub fn compute_message_hash( recipient: AztecAddress, version: Field, content: Field, - secret_hash: Field + secret_hash: Field, ) -> Field { let mut hash_bytes = [0 as u8; 192]; let sender_bytes: [u8; 32] = sender.to_field().to_be_bytes(); @@ -67,7 +72,7 @@ pub fn compute_message_hash( pub fn compute_message_nullifier(message_hash: Field, secret: Field, leaf_index: Field) -> Field { poseidon2_hash_with_separator( [message_hash, secret, leaf_index], - GENERATOR_INDEX__MESSAGE_NULLIFIER + GENERATOR_INDEX__MESSAGE_NULLIFIER, ) } @@ -126,13 +131,15 @@ unconstrained fn compute_var_args_hash() { #[test] unconstrained fn compute_unenc_log_hash_array() { - let contract_address = AztecAddress::from_field(0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6); + let contract_address = AztecAddress::from_field( + 0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6, + ); let log = [ 0x20660de09f35f876e3e69d227b2a35166ad05f09d82d06366ec9b6f65a51fec2, 0x1b52bfe3b8689761916f76dc3d38aa8810860db325cd39ca611eed980091f01c, 0x2e559c4045c378a56ad13b9edb1e8de4e7ad3b3aa35cc7ba9ec77f7a68fa43a4, 0x25d0f689c4a4178a29d59306f2675824d19be6d25e44fa03b03f49c263053dd2, - 0x2d513a722d6f352dc0961f156afdc5e31495b9f0e35cb069261a8e55e2df67fd + 0x2d513a722d6f352dc0961f156afdc5e31495b9f0e35cb069261a8e55e2df67fd, ]; let serialized_log = arr_to_be_bytes_arr(log); let hash = compute_unencrypted_log_hash(contract_address, serialized_log); @@ -141,8 +148,12 @@ unconstrained fn compute_unenc_log_hash_array() { #[test] unconstrained fn compute_unenc_log_hash_addr() { - let contract_address = AztecAddress::from_field(0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6); - let log = AztecAddress::from_field(0x26aa302d4715fd8a687453cb26d616b0768027bd54bcae56b09d908ecd9f8303); + let contract_address = AztecAddress::from_field( + 0x233a3e0df23b2b15b324194cb4a151f26c0b7333250781d34cc269d85dc334c6, + ); + let log = AztecAddress::from_field( + 0x26aa302d4715fd8a687453cb26d616b0768027bd54bcae56b09d908ecd9f8303, + ); let serialized_log: [u8; 32] = log.to_field().to_be_bytes(); let hash = compute_unencrypted_log_hash(contract_address, serialized_log); assert(hash == 0x0083ab647dfb26e7ddee90a0f4209d049d4660cab42000c544b986aaa84c55a3); @@ -150,7 +161,9 @@ unconstrained fn compute_unenc_log_hash_addr() { #[test] unconstrained fn compute_unenc_log_hash_str() { - let contract_address = AztecAddress::from_field(0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8); + let contract_address = AztecAddress::from_field( + 0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8, + ); let log = "dummy"; let serialized_log = str_to_be_bytes_arr(log); let hash = compute_unencrypted_log_hash(contract_address, serialized_log); @@ -159,7 +172,9 @@ unconstrained fn compute_unenc_log_hash_str() { #[test] unconstrained fn compute_unenc_log_hash_longer_str() { - let contract_address = AztecAddress::from_field(0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8); + let contract_address = AztecAddress::from_field( + 0x1b401e1146c5c507962287065c81f0ef7590adae3802c533d7549d6bf0a41bd8, + ); let log = "Hello this is a string"; let serialized_log = str_to_be_bytes_arr(log); let hash = compute_unencrypted_log_hash(contract_address, serialized_log); diff --git a/noir-projects/aztec-nr/aztec/src/history/contract_inclusion.nr b/noir-projects/aztec-nr/aztec/src/history/contract_inclusion.nr index 46219e12e16..456c1dac837 100644 --- a/noir-projects/aztec-nr/aztec/src/history/contract_inclusion.nr +++ b/noir-projects/aztec-nr/aztec/src/history/contract_inclusion.nr @@ -1,6 +1,6 @@ use dep::protocol_types::{ header::Header, address::AztecAddress, hash::compute_siloed_nullifier, - constants::DEPLOYER_CONTRACT_ADDRESS + constants::DEPLOYER_CONTRACT_ADDRESS, }; trait ProveContractDeployment { @@ -10,7 +10,8 @@ trait ProveContractDeployment { impl ProveContractDeployment for Header { fn prove_contract_deployment(self, contract_address: AztecAddress) { // Compute deployment nullifier - let nullifier = compute_siloed_nullifier(DEPLOYER_CONTRACT_ADDRESS, contract_address.to_field()); + let nullifier = + compute_siloed_nullifier(DEPLOYER_CONTRACT_ADDRESS, contract_address.to_field()); self.prove_nullifier_inclusion(nullifier); } @@ -23,7 +24,8 @@ trait ProveContractNonDeployment { impl ProveContractNonDeployment for Header { fn prove_contract_non_deployment(self, contract_address: AztecAddress) { // Compute deployment nullifier - let nullifier = compute_siloed_nullifier(DEPLOYER_CONTRACT_ADDRESS, contract_address.to_field()); + let nullifier = + compute_siloed_nullifier(DEPLOYER_CONTRACT_ADDRESS, contract_address.to_field()); // docs:start:prove_nullifier_non_inclusion self.prove_nullifier_non_inclusion(nullifier); diff --git a/noir-projects/aztec-nr/aztec/src/history/note_inclusion.nr b/noir-projects/aztec-nr/aztec/src/history/note_inclusion.nr index 4e245febc9f..a7f18eb4e99 100644 --- a/noir-projects/aztec-nr/aztec/src/history/note_inclusion.nr +++ b/noir-projects/aztec-nr/aztec/src/history/note_inclusion.nr @@ -3,18 +3,20 @@ use dep::protocol_types::header::Header; use crate::{ note::{utils::compute_note_hash_for_nullify, note_interface::{NoteInterface, NullifiableNote}}, - oracle::get_membership_witness::get_note_hash_membership_witness + oracle::get_membership_witness::get_note_hash_membership_witness, }; trait ProveNoteInclusion { - fn prove_note_inclusion(header: Header, note: Note) where Note: NoteInterface + NullifiableNote; + fn prove_note_inclusion(header: Header, note: Note) + where + Note: NoteInterface + NullifiableNote; } impl ProveNoteInclusion for Header { - fn prove_note_inclusion( - self, - note: Note - ) where Note: NoteInterface + NullifiableNote { + fn prove_note_inclusion(self, note: Note) + where + Note: NoteInterface + NullifiableNote, + { let note_hash = compute_note_hash_for_nullify(note); let witness = unsafe { @@ -25,7 +27,9 @@ impl ProveNoteInclusion for Header { // we don't even care _where_ in the tree it is stored. This is because entries in the note hash tree are // unique. assert_eq( - self.state.partial.note_hash_tree.root, root_from_sibling_path(note_hash, witness.index, witness.path), "Proving note inclusion failed" + self.state.partial.note_hash_tree.root, + root_from_sibling_path(note_hash, witness.index, witness.path), + "Proving note inclusion failed", ); } } diff --git a/noir-projects/aztec-nr/aztec/src/history/note_validity.nr b/noir-projects/aztec-nr/aztec/src/history/note_validity.nr index eba2cfc2d05..3efac1fc1aa 100644 --- a/noir-projects/aztec-nr/aztec/src/history/note_validity.nr +++ b/noir-projects/aztec-nr/aztec/src/history/note_validity.nr @@ -3,15 +3,20 @@ use crate::{context::PrivateContext, note::note_interface::{NoteInterface, Nulli use dep::protocol_types::header::Header; trait ProveNoteValidity { - fn prove_note_validity(header: Header, note: Note, context: &mut PrivateContext) where Note: NoteInterface + NullifiableNote; + fn prove_note_validity( + header: Header, + note: Note, + context: &mut PrivateContext, + ) + where + Note: NoteInterface + NullifiableNote; } impl ProveNoteValidity for Header { - fn prove_note_validity( - self, - note: Note, - context: &mut PrivateContext - ) where Note: NoteInterface + NullifiableNote { + fn prove_note_validity(self, note: Note, context: &mut PrivateContext) + where + Note: NoteInterface + NullifiableNote, + { self.prove_note_inclusion(note); self.prove_note_not_nullified(note, context); } diff --git a/noir-projects/aztec-nr/aztec/src/history/nullifier_inclusion.nr b/noir-projects/aztec-nr/aztec/src/history/nullifier_inclusion.nr index 81aee809ebc..3651acabab9 100644 --- a/noir-projects/aztec-nr/aztec/src/history/nullifier_inclusion.nr +++ b/noir-projects/aztec-nr/aztec/src/history/nullifier_inclusion.nr @@ -2,8 +2,9 @@ use dep::protocol_types::merkle_tree::root::root_from_sibling_path; use dep::protocol_types::header::Header; use crate::{ - context::PrivateContext, oracle::get_nullifier_membership_witness::get_nullifier_membership_witness, - note::{utils::compute_siloed_nullifier, note_interface::{NoteInterface, NullifiableNote}} + context::PrivateContext, + oracle::get_nullifier_membership_witness::get_nullifier_membership_witness, + note::{utils::compute_siloed_nullifier, note_interface::{NoteInterface, NullifiableNote}}, }; trait ProveNullifierInclusion { @@ -21,27 +22,37 @@ impl ProveNullifierInclusion for Header { // the leaf that contains the nullifier we're proving inclusion for. assert( self.state.partial.nullifier_tree.root - == root_from_sibling_path(witness.leaf_preimage.hash(), witness.index, witness.path), "Proving nullifier inclusion failed" - ); - - // 3) Then we simply check that the value in the leaf is the expected one. Note that we don't need to perform - // any checks on the rest of the values in the leaf preimage (the next index or next nullifier), since all we - // care about is showing that the tree contains an entry with the expected nullifier. - assert(witness.leaf_preimage.nullifier == nullifier, "Nullifier does not match value in witness"); - } + == root_from_sibling_path(witness.leaf_preimage.hash(), witness.index, witness.path) + , + "Proving nullifier inclusion failed", + ); + + // 3) Then we simply check that the value in the leaf is the expected one. Note that we don't need to perform + // any checks on the rest of the values in the leaf preimage (the next index or next nullifier), since all we + // care about is showing that the tree contains an entry with the expected nullifier. + assert( + witness.leaf_preimage.nullifier == nullifier, + "Nullifier does not match value in witness", + ); + } } trait ProveNoteIsNullified { - fn prove_note_is_nullified(header: Header, note: Note, context: &mut PrivateContext) where Note: NoteInterface + NullifiableNote; + fn prove_note_is_nullified( + header: Header, + note: Note, + context: &mut PrivateContext, + ) + where + Note: NoteInterface + NullifiableNote; } impl ProveNoteIsNullified for Header { // docs:start:prove_note_is_nullified - fn prove_note_is_nullified( - self, - note: Note, - context: &mut PrivateContext - ) where Note: NoteInterface + NullifiableNote { + fn prove_note_is_nullified(self, note: Note, context: &mut PrivateContext) + where + Note: NoteInterface + NullifiableNote, + { let nullifier = compute_siloed_nullifier(note, context); self.prove_nullifier_inclusion(nullifier); diff --git a/noir-projects/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr b/noir-projects/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr index 977a5477547..e8cf5d7bf4d 100644 --- a/noir-projects/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr +++ b/noir-projects/aztec-nr/aztec/src/history/nullifier_non_inclusion.nr @@ -1,9 +1,11 @@ use dep::protocol_types::merkle_tree::root::root_from_sibling_path; -use dep::protocol_types::{header::Header, utils::field::{full_field_less_than, full_field_greater_than}}; +use dep::protocol_types::{ + header::Header, utils::field::{full_field_less_than, full_field_greater_than}, +}; use crate::{ context::PrivateContext, note::{utils::compute_siloed_nullifier, note_interface::{NoteInterface, NullifiableNote}}, - oracle::get_nullifier_membership_witness::get_low_nullifier_membership_witness + oracle::get_nullifier_membership_witness::get_low_nullifier_membership_witness, }; trait ProveNullifierNonInclusion { @@ -14,7 +16,10 @@ impl ProveNullifierNonInclusion for Header { fn prove_nullifier_non_inclusion(self, nullifier: Field) { // 1) Get the membership witness of a low nullifier of the nullifier let witness = unsafe { - get_low_nullifier_membership_witness(self.global_variables.block_number as u32, nullifier) + get_low_nullifier_membership_witness( + self.global_variables.block_number as u32, + nullifier, + ) }; // 2) First we prove that the tree leaf in the witness is present in the nullifier tree. This is expected to be @@ -23,12 +28,14 @@ impl ProveNullifierNonInclusion for Header { let low_nullifier_leaf = witness.leaf_preimage; assert( self.state.partial.nullifier_tree.root - == root_from_sibling_path(low_nullifier_leaf.hash(), witness.index, witness.path), "Proving nullifier non-inclusion failed: Could not prove low nullifier inclusion" + == root_from_sibling_path(low_nullifier_leaf.hash(), witness.index, witness.path), + "Proving nullifier non-inclusion failed: Could not prove low nullifier inclusion", ); // 3) Prove that the low leaf is indeed smaller than the nullifier assert( - full_field_less_than(low_nullifier_leaf.nullifier, nullifier), "Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed" + full_field_less_than(low_nullifier_leaf.nullifier, nullifier), + "Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed", ); // 4) Prove that the low leaf is pointing "over" the nullifier, which means that the nullifier is not included @@ -36,22 +43,28 @@ impl ProveNullifierNonInclusion for Header { // special case in which the low leaf is the largest of all entries, in which case there's no 'next' entry. assert( full_field_greater_than(low_nullifier_leaf.next_nullifier, nullifier) - | (low_nullifier_leaf.next_index == 0), "Proving nullifier non-inclusion failed: low_nullifier.next_value > nullifier.value check failed" + | (low_nullifier_leaf.next_index == 0), + "Proving nullifier non-inclusion failed: low_nullifier.next_value > nullifier.value check failed", ); } } trait ProveNoteNotNullified { - fn prove_note_not_nullified(header: Header, note: Note, context: &mut PrivateContext) where Note: NoteInterface + NullifiableNote; + fn prove_note_not_nullified( + header: Header, + note: Note, + context: &mut PrivateContext, + ) + where + Note: NoteInterface + NullifiableNote; } impl ProveNoteNotNullified for Header { // docs:start:prove_note_not_nullified - fn prove_note_not_nullified( - self, - note: Note, - context: &mut PrivateContext - ) where Note: NoteInterface + NullifiableNote { + fn prove_note_not_nullified(self, note: Note, context: &mut PrivateContext) + where + Note: NoteInterface + NullifiableNote, + { let nullifier = compute_siloed_nullifier(note, context); self.prove_nullifier_non_inclusion(nullifier); diff --git a/noir-projects/aztec-nr/aztec/src/history/public_storage.nr b/noir-projects/aztec-nr/aztec/src/history/public_storage.nr index 44708269b3f..78aeeb63be7 100644 --- a/noir-projects/aztec-nr/aztec/src/history/public_storage.nr +++ b/noir-projects/aztec-nr/aztec/src/history/public_storage.nr @@ -1,28 +1,36 @@ use dep::protocol_types::{ constants::GENERATOR_INDEX__PUBLIC_LEAF_INDEX, hash::poseidon2_hash_with_separator, - address::AztecAddress, header::Header, utils::field::full_field_less_than + address::AztecAddress, header::Header, utils::field::full_field_less_than, }; use dep::protocol_types::merkle_tree::root::root_from_sibling_path; -use crate::{oracle::get_public_data_witness::get_public_data_witness}; +use crate::oracle::get_public_data_witness::get_public_data_witness; trait PublicStorageHistoricalRead { - fn public_storage_historical_read(header: Header, storage_slot: Field, contract_address: AztecAddress) -> Field; + fn public_storage_historical_read( + header: Header, + storage_slot: Field, + contract_address: AztecAddress, + ) -> Field; } impl PublicStorageHistoricalRead for Header { - fn public_storage_historical_read(self, storage_slot: Field, contract_address: AztecAddress) -> Field { + fn public_storage_historical_read( + self, + storage_slot: Field, + contract_address: AztecAddress, + ) -> Field { // 1) Compute the leaf index by siloing the storage slot with the contract address let public_data_tree_index = poseidon2_hash_with_separator( [contract_address.to_field(), storage_slot], - GENERATOR_INDEX__PUBLIC_LEAF_INDEX + GENERATOR_INDEX__PUBLIC_LEAF_INDEX, ); // 2) Get the membership witness for the tree index. let witness = unsafe { get_public_data_witness( self.global_variables.block_number as u32, - public_data_tree_index + public_data_tree_index, ) }; @@ -32,28 +40,35 @@ impl PublicStorageHistoricalRead for Header { // (slot, next index and next slot). assert( self.state.partial.public_data_tree.root - == root_from_sibling_path(witness.leaf_preimage.hash(), witness.index, witness.path), "Proving public value inclusion failed" - ); + == root_from_sibling_path(witness.leaf_preimage.hash(), witness.index, witness.path) + , + "Proving public value inclusion failed", + ); - // 4) Now that we know the preimage is valid, we determine the value that's represented by this tree entry. Here - // we have two scenarios: - // 1. The tree entry is initialized, and the value is the same as the one in the witness - // 2. The entry was never initialized, and the value is default zero (the default) - // The code below is based on the same checks in `validate_public_data_reads` in `base_rollup_inputs`. - let preimage = witness.leaf_preimage; - - let is_less_than_slot = full_field_less_than(preimage.slot, public_data_tree_index); - let is_next_greater_than = full_field_less_than(public_data_tree_index, preimage.next_slot); - let is_max = ((preimage.next_index == 0) & (preimage.next_slot == 0)); - let is_in_range = is_less_than_slot & (is_next_greater_than | is_max); - - let value = if is_in_range { - 0 - } else { - assert_eq(preimage.slot, public_data_tree_index, "Public data tree index doesn't match witness"); - preimage.value - }; + // 4) Now that we know the preimage is valid, we determine the value that's represented by this tree entry. Here + // we have two scenarios: + // 1. The tree entry is initialized, and the value is the same as the one in the witness + // 2. The entry was never initialized, and the value is default zero (the default) + // The code below is based on the same checks in `validate_public_data_reads` in `base_rollup_inputs`. + let preimage = witness.leaf_preimage; + + let is_less_than_slot = full_field_less_than(preimage.slot, public_data_tree_index); + let is_next_greater_than = + full_field_less_than(public_data_tree_index, preimage.next_slot); + let is_max = ((preimage.next_index == 0) & (preimage.next_slot == 0)); + let is_in_range = is_less_than_slot & (is_next_greater_than | is_max); + + let value = if is_in_range { + 0 + } else { + assert_eq( + preimage.slot, + public_data_tree_index, + "Public data tree index doesn't match witness", + ); + preimage.value + }; - value - } + value + } } diff --git a/noir-projects/aztec-nr/aztec/src/initializer.nr b/noir-projects/aztec-nr/aztec/src/initializer.nr index 1be907c5ce9..ec966af74af 100644 --- a/noir-projects/aztec-nr/aztec/src/initializer.nr +++ b/noir-projects/aztec-nr/aztec/src/initializer.nr @@ -1,20 +1,22 @@ use dep::protocol_types::{ - address::AztecAddress, hash::poseidon2_hash_with_separator, constants::GENERATOR_INDEX__CONSTRUCTOR, - abis::function_selector::FunctionSelector + address::AztecAddress, hash::poseidon2_hash_with_separator, + constants::GENERATOR_INDEX__CONSTRUCTOR, abis::function_selector::FunctionSelector, }; use crate::{ context::{PrivateContext, PublicContext}, oracle::get_contract_instance::get_contract_instance, - oracle::get_contract_instance::get_contract_instance_avm + oracle::get_contract_instance::get_contract_instance_avm, }; pub fn mark_as_initialized_public(context: &mut PublicContext) { - let init_nullifier = compute_unsiloed_contract_initialization_nullifier((*context).this_address()); + let init_nullifier = + compute_unsiloed_contract_initialization_nullifier((*context).this_address()); context.push_nullifier(init_nullifier); } pub fn mark_as_initialized_private(context: &mut PrivateContext) { - let init_nullifier = compute_unsiloed_contract_initialization_nullifier((*context).this_address()); + let init_nullifier = + compute_unsiloed_contract_initialization_nullifier((*context).this_address()); context.push_nullifier(init_nullifier); } @@ -38,7 +40,8 @@ pub fn assert_initialization_matches_address_preimage_public(context: PublicCont let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash()); assert(instance.initialization_hash == expected_init, "Initialization hash does not match"); assert( - (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()), "Initializer address is not the contract deployer" + (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()), + "Initializer address is not the contract deployer", ); } @@ -48,13 +51,17 @@ pub fn assert_initialization_matches_address_preimage_private(context: PrivateCo let expected_init = compute_initialization_hash(context.selector(), context.get_args_hash()); assert(instance.initialization_hash == expected_init, "Initialization hash does not match"); assert( - (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()), "Initializer address is not the contract deployer" + (instance.deployer.is_zero()) | (instance.deployer == context.msg_sender()), + "Initializer address is not the contract deployer", ); } -pub fn compute_initialization_hash(init_selector: FunctionSelector, init_args_hash: Field) -> Field { +pub fn compute_initialization_hash( + init_selector: FunctionSelector, + init_args_hash: Field, +) -> Field { poseidon2_hash_with_separator( [init_selector.to_field(), init_args_hash], - GENERATOR_INDEX__CONSTRUCTOR + GENERATOR_INDEX__CONSTRUCTOR, ) } diff --git a/noir-projects/aztec-nr/aztec/src/keys/constants.nr b/noir-projects/aztec-nr/aztec/src/keys/constants.nr index 6914fb446c9..2d465369fed 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/constants.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/constants.nr @@ -1,4 +1,7 @@ -use dep::protocol_types::constants::{GENERATOR_INDEX__NSK_M, GENERATOR_INDEX__IVSK_M, GENERATOR_INDEX__OVSK_M, GENERATOR_INDEX__TSK_M}; +use dep::protocol_types::constants::{ + GENERATOR_INDEX__NSK_M, GENERATOR_INDEX__IVSK_M, GENERATOR_INDEX__OVSK_M, + GENERATOR_INDEX__TSK_M, +}; // Note: In fetch_key_from_registry we expect that the shared mutable slot is index * 2 + 1 for the x coordinate and // index * 2 + 2 for the y coordinate. For example, the npk_m x coordinates will be stored in a map at storage slot @@ -15,5 +18,5 @@ global sk_generators = [ GENERATOR_INDEX__NSK_M as Field, GENERATOR_INDEX__IVSK_M as Field, GENERATOR_INDEX__OVSK_M as Field, - GENERATOR_INDEX__TSK_M as Field + GENERATOR_INDEX__TSK_M as Field, ]; diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr index 4e599139665..52502eed6bf 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr @@ -1,7 +1,9 @@ use dep::protocol_types::{address::AztecAddress, public_keys::PublicKeys}; use crate::{ - oracle::{keys::get_public_keys_and_partial_address, key_validation_request::get_key_validation_request}, - keys::{constants::{NULLIFIER_INDEX, OUTGOING_INDEX}} + oracle::{ + keys::get_public_keys_and_partial_address, + key_validation_request::get_key_validation_request, + }, keys::constants::{NULLIFIER_INDEX, OUTGOING_INDEX}, }; mod test; @@ -21,11 +23,12 @@ pub unconstrained fn get_ovsk_app(ovpk_m_hash: Field) -> Field { // keys at once since the constraints for reading them all are actually fewer than if we read them one at a time - any // read keys that are not required by the caller can simply be discarded. pub fn get_public_keys(account: AztecAddress) -> PublicKeys { - let (hinted_canonical_public_keys, partial_address) = unsafe { - get_public_keys_and_partial_address(account) - }; + let (hinted_canonical_public_keys, partial_address) = + unsafe { get_public_keys_and_partial_address(account) }; assert_eq( - account, AztecAddress::compute(hinted_canonical_public_keys.hash(), partial_address), "Invalid public keys hint for address" + account, + AztecAddress::compute(hinted_canonical_public_keys.hash(), partial_address), + "Invalid public keys hint for address", ); hinted_canonical_public_keys diff --git a/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr b/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr index a0147001bed..9a5ee36603c 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/getters/test.nr @@ -18,7 +18,9 @@ unconstrained fn test_get_public_keys_unknown() { // Instead of querying for some unknown account, which would result in the oracle erroring out, we mock a bad oracle // response to check that the circuit properly checks the address derivation. - let _ = OracleMock::mock("getPublicKeysAndPartialAddress").returns([0; KEY_ORACLE_RESPONSE_LENGTH]).times(1); + let _ = OracleMock::mock("getPublicKeysAndPartialAddress") + .returns([0; KEY_ORACLE_RESPONSE_LENGTH]) + .times(1); let _ = get_public_keys(account.address); } diff --git a/noir-projects/aztec-nr/aztec/src/keys/point_to_symmetric_key.nr b/noir-projects/aztec-nr/aztec/src/keys/point_to_symmetric_key.nr index b6af664ea91..7c55cbe548b 100644 --- a/noir-projects/aztec-nr/aztec/src/keys/point_to_symmetric_key.nr +++ b/noir-projects/aztec-nr/aztec/src/keys/point_to_symmetric_key.nr @@ -1,4 +1,6 @@ -use dep::protocol_types::{constants::GENERATOR_INDEX__SYMMETRIC_KEY, scalar::Scalar, point::Point, utils::arr_copy_slice}; +use dep::protocol_types::{ + constants::GENERATOR_INDEX__SYMMETRIC_KEY, scalar::Scalar, point::Point, utils::arr_copy_slice, +}; use crate::utils::point::point_to_bytes; use std::{hash::sha256, embedded_curve_ops::multi_scalar_mul}; @@ -8,7 +10,8 @@ pub fn point_to_symmetric_key(secret: Scalar, point: Point) -> [u8; 32] { let shared_secret: Point = multi_scalar_mul([point], [secret]); let shared_secret = point_to_bytes(shared_secret); let mut shared_secret_bytes_with_separator = [0 as u8; 33]; - shared_secret_bytes_with_separator = arr_copy_slice(shared_secret, shared_secret_bytes_with_separator, 0); + shared_secret_bytes_with_separator = + arr_copy_slice(shared_secret, shared_secret_bytes_with_separator, 0); shared_secret_bytes_with_separator[32] = GENERATOR_INDEX__SYMMETRIC_KEY; sha256(shared_secret_bytes_with_separator) } @@ -18,12 +21,12 @@ unconstrained fn test_point_to_symmetric_key_matches_noir() { // Value taken from "derive shared secret" test in encrypt_buffer.test.ts let secret = Scalar { lo: 0x00000000000000000000000000000000649e7ca01d9de27b21624098b897babd, - hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06 + hi: 0x0000000000000000000000000000000023b3127c127b1f29a7adff5cccf8fb06, }; let point = Point { x: 0x2688431c705a5ff3e6c6f2573c9e3ba1c1026d2251d0dbbf2d810aa53fd1d186, y: 0x1e96887b117afca01c00468264f4f80b5bb16d94c1808a448595f115556e5c8e, - is_infinite: false + is_infinite: false, }; let key = point_to_symmetric_key(secret, point); @@ -31,7 +34,8 @@ unconstrained fn test_point_to_symmetric_key_matches_noir() { // The following value was generated by `encrypt_buffer.test.ts`. // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data. let key_from_typescript = [ - 251, 232, 177, 34, 2, 174, 35, 92, 165, 118, 168, 3, 153, 140, 46, 210, 203, 154, 184, 158, 236, 33, 95, 77, 93, 120, 72, 88, 190, 209, 64, 159 + 251, 232, 177, 34, 2, 174, 35, 92, 165, 118, 168, 3, 153, 140, 46, 210, 203, 154, 184, 158, + 236, 33, 95, 77, 93, 120, 72, 88, 190, 209, 64, 159, ]; assert_eq(key, key_from_typescript); } diff --git a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr index 52a42d1694d..e2ac081fb88 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/dispatch/mod.nr @@ -4,12 +4,12 @@ use std::panic; /// Returns an `fn public_dispatch(...)` function for the given module that's assumed to be an Aztec contract. pub comptime fn generate_public_dispatch(m: Module) -> Quoted { let functions = m.functions(); - let functions = functions.filter(|function: FunctionDefinition| function.has_named_attribute("public")); + let functions = + functions.filter(|function: FunctionDefinition| function.has_named_attribute("public")); let unit = get_type::<()>(); - let ifs = functions.map( - |function: FunctionDefinition| { + let ifs = functions.map(|function: FunctionDefinition| { let name = function.name(); let parameters = function.parameters(); let return_type = function.return_type(); @@ -78,8 +78,7 @@ pub comptime fn generate_public_dispatch(m: Module) -> Quoted { } }; if_ - } - ); + }); if ifs.len() == 0 { // No dispatch function if there are no public functions @@ -119,14 +118,10 @@ comptime fn size_in_fields(typ: Type) -> u32 { } comptime fn array_size_in_fields(typ: Type) -> Option { - typ.as_array().and_then( - |typ: (Type, Type)| { - let (typ, element_size) = typ; - element_size.as_constant().map(|x: u32| { - x * size_in_fields(typ) - }) - } - ) + typ.as_array().and_then(|typ: (Type, Type)| { + let (typ, element_size) = typ; + element_size.as_constant().map(|x: u32| { x * size_in_fields(typ) }) + }) } comptime fn bool_size_in_fields(typ: Type) -> Option { @@ -162,28 +157,24 @@ comptime fn str_size_in_fields(typ: Type) -> Option { } comptime fn struct_size_in_fields(typ: Type) -> Option { - typ.as_struct().map( - |typ: (StructDefinition, [Type])| { - let struct_type = typ.0; - let mut size = 0; - for field in struct_type.fields() { - size += size_in_fields(field.1); - } - size + typ.as_struct().map(|typ: (StructDefinition, [Type])| { + let struct_type = typ.0; + let mut size = 0; + for field in struct_type.fields() { + size += size_in_fields(field.1); } - ) + size + }) } comptime fn tuple_size_in_fields(typ: Type) -> Option { - typ.as_tuple().map( - |types: [Type]| { - let mut size = 0; - for typ in types { - size += size_in_fields(typ); - } - size + typ.as_tuple().map(|types: [Type]| { + let mut size = 0; + for typ in types { + size += size_in_fields(typ); } - ) + size + }) } comptime fn get_type() -> Type { diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/interfaces.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/interfaces.nr index c0587085c25..d2800f8fae4 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/interfaces.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/interfaces.nr @@ -1,18 +1,19 @@ use std::{ meta::{unquote, type_of}, collections::umap::UHashMap, - hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher} + hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}, +}; +use crate::macros::utils::{ + get_fn_visibility, is_fn_view, is_fn_private, add_to_field_slice, compute_fn_selector, + is_fn_public, }; -use crate::macros::utils::{get_fn_visibility, is_fn_view, is_fn_private, add_to_field_slice, compute_fn_selector, is_fn_public}; -comptime mut global STUBS: UHashMap> = UHashMap::default(); +comptime mut global STUBS: UHashMap> = + UHashMap::default(); pub(crate) comptime fn create_fn_abi_export(f: FunctionDefinition) -> Quoted { let name = f.name(); - let mut parameters = f.parameters().map( - | (name, typ): (Quoted, Type) | { - quote { $name: $typ } - } - ).join(quote{,}); + let mut parameters = + f.parameters().map(|(name, typ): (Quoted, Type)| { quote { $name: $typ } }).join(quote {,}); let parameters_struct_name = f"{name}_parameters".quoted_contents(); let parameters = quote { @@ -76,7 +77,7 @@ pub comptime fn stub_fn(f: FunctionDefinition) -> Quoted { $args_hasher $appended_arg } - } + }, ); let args_hash_name = if fn_visibility == quote { private } { @@ -94,11 +95,8 @@ pub comptime fn stub_fn(f: FunctionDefinition) -> Quoted { args_acc }; - let fn_parameters_list = fn_parameters.map( - | (name, typ): (Quoted, Type) | { - quote { $name: $typ } - } - ).join(quote{,}); + let fn_parameters_list = + fn_parameters.map(|(name, typ): (Quoted, Type)| { quote { $name: $typ } }).join(quote {,}); let fn_name_str = fn_name.as_str_quote(); @@ -110,7 +108,8 @@ pub comptime fn stub_fn(f: FunctionDefinition) -> Quoted { quote { $fn_name_len, $fn_return_type } }; - let call_interface_name = f"dep::aztec::context::call_interfaces::{fn_visibility_capitalized}{is_static_call_capitalized}{is_void_capitalized}CallInterface".quoted_contents(); + let call_interface_name = f"dep::aztec::context::call_interfaces::{fn_visibility_capitalized}{is_static_call_capitalized}{is_void_capitalized}CallInterface" + .quoted_contents(); let fn_selector: Field = compute_fn_selector(f); diff --git a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr index 5ac843c6b9a..b60212dc10f 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr @@ -3,7 +3,7 @@ mod interfaces; use std::meta::type_of; use super::utils::{ modify_fn_body, is_fn_private, get_fn_visibility, is_fn_view, is_fn_initializer, is_fn_internal, - fn_has_noinitcheck, add_to_hasher, module_has_storage, module_has_initializer + fn_has_noinitcheck, add_to_hasher, module_has_storage, module_has_initializer, }; use protocol_types::meta::flatten_to_fields; @@ -64,7 +64,8 @@ pub comptime fn noinitcheck(_f: FunctionDefinition) { comptime fn create_assert_correct_initializer_args(f: FunctionDefinition) -> Quoted { let fn_visibility = get_fn_visibility(f); - f"dep::aztec::initializer::assert_initialization_matches_address_preimage_{fn_visibility}(context);".quoted_contents() + f"dep::aztec::initializer::assert_initialization_matches_address_preimage_{fn_visibility}(context);" + .quoted_contents() } comptime fn create_mark_as_initialized(f: FunctionDefinition) -> Quoted { @@ -74,7 +75,8 @@ comptime fn create_mark_as_initialized(f: FunctionDefinition) -> Quoted { comptime fn create_init_check(f: FunctionDefinition) -> Quoted { let fn_visibility = get_fn_visibility(f); - f"dep::aztec::initializer::assert_is_initialized_{fn_visibility}(&mut context);".quoted_contents() + f"dep::aztec::initializer::assert_is_initialized_{fn_visibility}(&mut context);" + .quoted_contents() } /// Private functions are executed client-side and preserve privacy. @@ -88,23 +90,19 @@ pub comptime fn private(f: FunctionDefinition) -> Quoted { // Private functions undergo a lot of transformations from their Aztec.nr form into a circuit that can be fed to the // Private Kernel Circuit. - // First we change the function signature so that it also receives `PrivateContextInputs`, which contain information // about the execution context (e.g. the caller). let original_params = f.parameters(); - f.set_parameters( - &[ - ( - quote { inputs }, quote { crate::context::inputs::private_context_inputs::PrivateContextInputs }.as_type() - ) - ].append(original_params) - ); + f.set_parameters(&[( + quote { inputs }, + quote { crate::context::inputs::private_context_inputs::PrivateContextInputs }.as_type(), + )] + .append(original_params)); let mut body = f.body().as_block().unwrap(); // The original params are hashed and passed to the `context` object, so that the kernel can verify we've received // the correct values. - // TODO: Optimize args_hasher for small number of arguments let args_hasher_name = quote { args_hasher }; let args_hasher = original_params.fold( @@ -118,13 +116,12 @@ pub comptime fn private(f: FunctionDefinition) -> Quoted { $args_hasher $appended_arg } - } + }, ); let context_creation = quote { let mut context = dep::aztec::context::private_context::PrivateContext::new(inputs, args_hasher.hash()); }; // Modifications introduced by the different marker attributes. - let internal_check = if is_fn_internal(f) { create_internal_check(f) } else { @@ -158,7 +155,6 @@ pub comptime fn private(f: FunctionDefinition) -> Quoted { // Finally, we need to change the return type to be `PrivateCircuitPublicInputs`, which is what the Private Kernel // circuit expects. - let return_value_var_name = quote { macro__returned__values }; let return_value_type = f.return_type(); @@ -166,12 +162,13 @@ pub comptime fn private(f: FunctionDefinition) -> Quoted { quote {} } else if return_value_type != type_of(()) { // The original return value is passed to a second args hasher which the context receives. - let (body_without_return, last_body_expr) = body.pop_back(); let return_value = last_body_expr.quoted(); - let return_value_assignment = quote { let $return_value_var_name: $return_value_type = $return_value; }; + let return_value_assignment = + quote { let $return_value_var_name: $return_value_type = $return_value; }; let return_hasher_name = quote { return_hasher }; - let return_value_into_hasher = add_to_hasher(return_hasher_name, return_value_var_name, return_value_type); + let return_value_into_hasher = + add_to_hasher(return_hasher_name, return_value_var_name, return_value_type); body = body_without_return; @@ -190,7 +187,9 @@ pub comptime fn private(f: FunctionDefinition) -> Quoted { & last_body_expr.as_assert_eq().is_none() & last_body_expr.as_let().is_none() { let unused_return_value_name = f"_{return_value_var_name}".quoted_contents(); - body = body_without_return.push_back(quote { let $unused_return_value_name = $last_body_expr; }.as_expr().unwrap()); + body = body_without_return.push_back( + quote { let $unused_return_value_name = $last_body_expr; }.as_expr().unwrap(), + ); } quote {} }; @@ -216,7 +215,8 @@ pub comptime fn private(f: FunctionDefinition) -> Quoted { f.set_body(modified_body); f.add_attribute("recursive"); f.set_return_type( - quote { dep::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs }.as_type() + quote { dep::protocol_types::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs } + .as_type(), ); f.set_return_data(); @@ -243,7 +243,9 @@ comptime fn transform_public(f: FunctionDefinition) -> Quoted { // Public functions undergo a lot of transformations from their Aztec.nr form. let original_params = f.parameters(); - let args_len = original_params.map(|(name, typ): (Quoted, Type)| flatten_to_fields(name, typ, &[]).0.len()).fold(0, |acc: u32, val: u32| acc + val); + let args_len = original_params + .map(|(name, typ): (Quoted, Type)| flatten_to_fields(name, typ, &[]).0.len()) + .fold(0, |acc: u32, val: u32| acc + val); // Unlike in the private case, in public the `context` does not need to receive the hash of the original params. let context_creation = quote { let mut context = dep::aztec::context::public_context::PublicContext::new(|| { diff --git a/noir-projects/aztec-nr/aztec/src/macros/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/mod.nr index 677d0af070b..cc9b860f528 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/mod.nr @@ -19,13 +19,14 @@ use dispatch::generate_public_dispatch; /// Note: This is a module annotation, so the returned quote gets injected inside the module (contract) itself. pub comptime fn aztec(m: Module) -> Quoted { let interface = generate_contract_interface(m); - let unconstrained_functions = m.functions().filter( - | f: FunctionDefinition | f.is_unconstrained() & !f.has_named_attribute("test") & !f.has_named_attribute("public") - ); + let unconstrained_functions = m.functions().filter(|f: FunctionDefinition| { + f.is_unconstrained() & !f.has_named_attribute("test") & !f.has_named_attribute("public") + }); for f in unconstrained_functions { transform_unconstrained(f); } - let compute_note_hash_and_optionally_a_nullifier = generate_compute_note_hash_and_optionally_a_nullifier(); + let compute_note_hash_and_optionally_a_nullifier = + generate_compute_note_hash_and_optionally_a_nullifier(); let note_exports = generate_note_exports(); let public_dispatch = generate_public_dispatch(m); quote { @@ -108,9 +109,12 @@ comptime fn generate_compute_note_hash_and_optionally_a_nullifier() -> Quoted { let mut max_note_length: u32 = 0; let notes = NOTES.entries(); let body = if notes.len() > 0 { - max_note_length = notes.fold(0, | acc, (_, (_, len, _, _)): (Type, (StructDefinition, u32, Field, [(Quoted, u32, bool)])) | { - acc + len - }); + max_note_length = notes.fold( + 0, + |acc, (_, (_, len, _, _)): (Type, (StructDefinition, u32, Field, [(Quoted, u32, bool)]))| { + acc + len + }, + ); let mut if_statements_list = &[]; @@ -121,11 +125,13 @@ comptime fn generate_compute_note_hash_and_optionally_a_nullifier() -> Quoted { } else { quote { else if } }; - if_statements_list = if_statements_list.push_back(quote { + if_statements_list = if_statements_list.push_back( + quote { $if_or_else_if note_type_id == $typ::get_note_type_id() { aztec::note::utils::compute_note_hash_and_optionally_a_nullifier($typ::deserialize_content, note_header, compute_nullifier, serialized_note) } - }); + }, + ); } let if_statements = if_statements_list.join(quote {}); @@ -161,9 +167,9 @@ comptime fn generate_note_exports() -> Quoted { let notes = NOTES.values(); // Second value in each tuple is `note_serialized_len` and that is ignored here because it's only used when // generating the `compute_note_hash_and_optionally_a_nullifier` function. - notes.map( - | (s, _, note_type_id, fields): (StructDefinition, u32, Field, [(Quoted, u32, bool)]) | { + notes + .map(|(s, _, note_type_id, fields): (StructDefinition, u32, Field, [(Quoted, u32, bool)])| { generate_note_export(s, note_type_id, fields) - } - ).join(quote {}) + }) + .join(quote {}) } diff --git a/noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr index ec702f4f7b1..edbf60dc17b 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr @@ -1,6 +1,6 @@ use std::{ meta::{type_of, unquote, typ::fresh_type_variable}, collections::umap::UHashMap, - hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher} + hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}, }; use protocol_types::meta::{flatten_to_fields, pack_from_fields}; use crate::note::{note_header::NoteHeader, note_getter_options::PropertySelector}; @@ -11,7 +11,8 @@ comptime global NOTE_HEADER_TYPE = type_of(NoteHeader::empty()); /// `fields` is an array of tuples where each tuple contains the name of the field/struct member (e.g. `amount` /// in `TokenNote`), the index of where the serialized member starts in the serialized note and a flag indicating /// whether the field is nullable or not. -comptime mut global NOTES: UHashMap> = UHashMap::default(); +comptime mut global NOTES: UHashMap> = + UHashMap::default(); /// Computes a note type id by hashing a note name (e.g. `TokenNote`), getting the first 4 bytes of the hash /// and returning it as a `Field`. @@ -24,7 +25,7 @@ comptime fn compute_note_type_id(name: Quoted) -> Field { let hash = protocol_types::hash::poseidon2_hash_bytes(bytes); let hash_bytes = hash.to_be_bytes::<4>(); protocol_types::utils::field::field_from_bytes(hash_bytes, true) - } + }, ) } @@ -64,14 +65,15 @@ comptime fn generate_note_interface( s: StructDefinition, note_type_id: Field, indexed_fixed_fields: [(Quoted, Type, u32)], - indexed_nullable_fields: [(Quoted, Type, u32)] + indexed_nullable_fields: [(Quoted, Type, u32)], ) -> (Quoted, u32) { let name = s.name(); let typ = s.as_type(); // First we compute note content serialization. We do that by passing the whole note struct // to the `flatten_to_fields(...)` and omitting the header. - let (content_fields_list, content_aux_vars_list) = flatten_to_fields(quote { self }, typ, &[quote {self.header}]); + let (content_fields_list, content_aux_vars_list) = + flatten_to_fields(quote { self }, typ, &[quote {self.header}]); // If there are `aux_vars` we need to join them with `;` and add a trailing `;` to the joined string. let content_aux_vars = if content_aux_vars_list.len() > 0 { @@ -88,20 +90,27 @@ comptime fn generate_note_interface( typ, quote { value }, 0, - &[(quote {header}, quote { aztec::note::note_header::NoteHeader::empty() })] + &[(quote {header}, quote { aztec::note::note_header::NoteHeader::empty() })], ); // Second we compute quotes for MSM // `compute_note_hash()` is computed over all the fields so we need to merge fixed and nullable. let merged_fields = indexed_fixed_fields.append(indexed_nullable_fields); // Now we prefix each of the merged fields with `self.` since they refer to the struct members here. - let prefixed_merged_fields = merged_fields.map(| (name, typ, index): (Quoted, Type, u32) | (quote { self.$name }, typ, index)); - let (new_generators_list, new_scalars_list, _, new_aux_vars) = generate_multi_scalar_mul(prefixed_merged_fields); - - let new_generators = new_generators_list.push_back(quote { aztec::generators::G_slot }).join(quote {,}); - let new_scalars = new_scalars_list.push_back(quote { std::hash::from_field_unsafe(self.header.storage_slot) }).join(quote {,}); - - (quote { + let prefixed_merged_fields = merged_fields.map(|(name, typ, index): (Quoted, Type, u32)| { + (quote { self.$name }, typ, index) + }); + let (new_generators_list, new_scalars_list, _, new_aux_vars) = + generate_multi_scalar_mul(prefixed_merged_fields); + + let new_generators = + new_generators_list.push_back(quote { aztec::generators::G_slot }).join(quote {,}); + let new_scalars = new_scalars_list + .push_back(quote { std::hash::from_field_unsafe(self.header.storage_slot) }) + .join(quote {,}); + + ( + quote { impl aztec::note::note_interface::NoteInterface<$content_len> for $name { fn to_be_bytes(self, storage_slot: Field) -> [u8; $content_len * 32 + 64] { let serialized_note = self.serialize_content(); @@ -155,7 +164,9 @@ comptime fn generate_note_interface( point.x } } - }, content_len) + }, + content_len, + ) } /// Generates note properties struct for a given note struct `s`. @@ -186,19 +197,19 @@ comptime fn generate_note_properties(s: StructDefinition) -> Quoted { let property_selector_type = type_of(PropertySelector { index: 0, offset: 0, length: 0 }); let note_header_type: Type = type_of(NoteHeader::empty()); - let non_header_fields = s.fields().filter(| (_, typ): (Quoted, Type) | typ != note_header_type); + let non_header_fields = s.fields().filter(|(_, typ): (Quoted, Type)| typ != note_header_type); - let properties_types = non_header_fields.map( - | (name, _): (Quoted, Type) | { - quote { $name: $property_selector_type } - } - ).join(quote {,}); + let properties_types = non_header_fields + .map(|(name, _): (Quoted, Type)| { quote { $name: $property_selector_type } }) + .join(quote {,}); // TODO #8694: Properly handle non-field types https://github.com/AztecProtocol/aztec-packages/issues/8694 let mut properties_list = &[]; for i in 0..non_header_fields.len() { let (name, _) = non_header_fields[i]; - properties_list = properties_list.push_back(quote { $name: aztec::note::note_getter_options::PropertySelector { index: $i, offset: 0, length: 32 } }); + properties_list = properties_list.push_back( + quote { $name: aztec::note::note_getter_options::PropertySelector { index: $i, offset: 0, length: 32 } }, + ); } let properties = properties_list.join(quote {,}); @@ -243,7 +254,7 @@ comptime fn generate_note_properties(s: StructDefinition) -> Quoted { pub(crate) comptime fn generate_note_export( s: StructDefinition, note_type_id: Field, - fields: [(Quoted, u32, bool)] + fields: [(Quoted, u32, bool)], ) -> Quoted { let name = s.name(); let mut hasher = Poseidon2Hasher::default(); @@ -259,7 +270,9 @@ pub(crate) comptime fn generate_note_export( for field in fields { let (name, index, nullable) = field; note_fields = note_fields.push_back(quote { $name: aztec::note::note_field::NoteField }); - note_field_constructors = note_field_constructors.push_back(quote { $name: aztec::note::note_field::NoteField { index: $index, nullable: $nullable }}); + note_field_constructors = note_field_constructors.push_back( + quote { $name: aztec::note::note_field::NoteField { index: $index, nullable: $nullable }}, + ); } let note_fields = note_fields.join(quote {,}); @@ -289,7 +302,9 @@ pub(crate) comptime fn generate_note_export( /// ] /// args_list: [amount: U128, npk_m_hash: Field, randomness: Field] /// aux_vars: [] -comptime fn generate_multi_scalar_mul(indexed_fields: [(Quoted, Type, u32)]) -> ([Quoted], [Quoted], [Quoted], Quoted) { +comptime fn generate_multi_scalar_mul( + indexed_fields: [(Quoted, Type, u32)], +) -> ([Quoted], [Quoted], [Quoted], Quoted) { let mut generators_list = &[]; let mut scalars_list = &[]; let mut args_list = &[]; @@ -302,8 +317,10 @@ comptime fn generate_multi_scalar_mul(indexed_fields: [(Quoted, Type, u32)]) -> for j in 0..flattened_field.len() { let flattened_as_field = flattened_field[j]; let generator_index = start_generator_index + j; - generators_list = generators_list.push_back(f"aztec::generators::Ga{generator_index}".quoted_contents()); - scalars_list = scalars_list.push_back(quote { std::hash::from_field_unsafe($flattened_as_field) }); + generators_list = generators_list.push_back(f"aztec::generators::Ga{generator_index}" + .quoted_contents()); + scalars_list = + scalars_list.push_back(quote { std::hash::from_field_unsafe($flattened_as_field) }); } args_list = args_list.push_back(quote { $field_name: $typ }); aux_vars_list = aux_vars_list.append(aux_vars); @@ -371,22 +388,31 @@ comptime fn generate_multi_scalar_mul(indexed_fields: [(Quoted, Type, u32)]) -> comptime fn generate_setup_payload( s: StructDefinition, indexed_fixed_fields: [(Quoted, Type, u32)], - indexed_nullable_fields: [(Quoted, Type, u32)] + indexed_nullable_fields: [(Quoted, Type, u32)], ) -> (Quoted, Quoted) { let name = s.name(); let setup_payload_name = f"{name}SetupPayload".quoted_contents(); // First we get the MSM related quotes - let (new_generators_list, new_scalars_list, new_args_list, new_aux_vars) = generate_multi_scalar_mul(indexed_fixed_fields); - let new_args = &[quote {mut self}].append(new_args_list).push_back(quote { storage_slot: Field }).join(quote {,}); - let new_generators = new_generators_list.push_back(quote { aztec::generators::G_slot }).join(quote {,}); - let new_scalars = new_scalars_list.push_back(quote { std::hash::from_field_unsafe(storage_slot) }).join(quote {,}); + let (new_generators_list, new_scalars_list, new_args_list, new_aux_vars) = + generate_multi_scalar_mul(indexed_fixed_fields); + let new_args = &[quote {mut self}] + .append(new_args_list) + .push_back(quote { storage_slot: Field }) + .join(quote {,}); + let new_generators = + new_generators_list.push_back(quote { aztec::generators::G_slot }).join(quote {,}); + let new_scalars = new_scalars_list + .push_back(quote { std::hash::from_field_unsafe(storage_slot) }) + .join(quote {,}); // Then the log plaintext ones let log_plaintext_length = indexed_fixed_fields.len() * 32 + 64; - let setup_log_plaintext = get_setup_log_plaintext_body(s, log_plaintext_length, indexed_nullable_fields); + let setup_log_plaintext = + get_setup_log_plaintext_body(s, log_plaintext_length, indexed_nullable_fields); - (quote { + ( + quote { struct $setup_payload_name { log_plaintext: [u8; $log_plaintext_length], hiding_point: aztec::protocol_types::point::Point @@ -413,7 +439,9 @@ comptime fn generate_setup_payload( Self { log_plaintext: [0; $log_plaintext_length], hiding_point: aztec::protocol_types::point::Point::empty() } } } - }, setup_payload_name) + }, + setup_payload_name, + ) } /// Generates setup log plaintext for a given note struct `s`. The setup log plaintext is computed by serializing @@ -423,13 +451,15 @@ comptime fn generate_setup_payload( comptime fn get_setup_log_plaintext_body( s: StructDefinition, log_plaintext_length: u32, - indexed_nullable_fields: [(Quoted, Type, u32)] + indexed_nullable_fields: [(Quoted, Type, u32)], ) -> Quoted { let name = s.name(); // Now we compute serialization of the fixed fields. We do that by passing the whole note struct // to the flatten_to_fields function but we omit the NoteHeader and the nullable fields. - let to_omit = indexed_nullable_fields.map(| (name, _, _): (Quoted, Type, u32) | name).push_back(quote { header }); + let to_omit = indexed_nullable_fields.map(|(name, _, _): (Quoted, Type, u32)| name).push_back( + quote { header }, + ); let (fields_list, aux_vars) = flatten_to_fields(quote { }, s.as_type(), to_omit); // If there are `aux_vars` we need to join them with `;` and add a trailing `;` to the joined string. @@ -499,7 +529,7 @@ comptime fn get_setup_log_plaintext_body( comptime fn generate_finalization_payload( s: StructDefinition, indexed_fixed_fields: [(Quoted, Type, u32)], - indexed_nullable_fields: [(Quoted, Type, u32)] + indexed_nullable_fields: [(Quoted, Type, u32)], ) -> (Quoted, Quoted) { let name = s.name(); let finalization_payload_name = f"{name}FinalizationPayload".quoted_contents(); @@ -507,7 +537,9 @@ comptime fn generate_finalization_payload( // We compute serialization of the nullable fields which are to be emitted as an unencrypted log. We do that by // passing the whole note struct to the `flatten_to_fields(...)` function but we omit the `NoteHeader` and // the fixed fields. - let to_omit = indexed_fixed_fields.map(| (name, _, _): (Quoted, Type, u32) | name).push_back(quote { header }); + let to_omit = indexed_fixed_fields.map(|(name, _, _): (Quoted, Type, u32)| name).push_back( + quote { header }, + ); let (fields_list, aux_vars) = flatten_to_fields(quote { }, s.as_type(), to_omit); // If there are `aux_vars` we need to join them with `;` and add a trailing `;` to the joined string. @@ -523,13 +555,15 @@ comptime fn generate_finalization_payload( let fields = fields_list.join(quote {,}); // Now we compute quotes relevant to the multi-scalar multiplication. - let (generators_list, scalars_list, args_list, msm_aux_vars) = generate_multi_scalar_mul(indexed_nullable_fields); + let (generators_list, scalars_list, args_list, msm_aux_vars) = + generate_multi_scalar_mul(indexed_nullable_fields); let generators = generators_list.join(quote {,}); let scalars = scalars_list.join(quote {,}); let args = args_list.join(quote {,}); - (quote { + ( + quote { struct $finalization_payload_name { log: [Field; $log_length], note_hash: Field, @@ -556,7 +590,9 @@ comptime fn generate_finalization_payload( Self { log: [0; $log_length], note_hash: 0 } } } - }, finalization_payload_name) + }, + finalization_payload_name, + ) } /// Generates `PartialNote` implementation for a given note struct `s`. @@ -573,7 +609,11 @@ comptime fn generate_finalization_payload( /// } /// } /// ``` -comptime fn generate_partial_note_impl(s: StructDefinition, setup_payload_name: Quoted, finalization_payload_name: Quoted) -> Quoted { +comptime fn generate_partial_note_impl( + s: StructDefinition, + setup_payload_name: Quoted, + finalization_payload_name: Quoted, +) -> Quoted { let name = s.name(); quote { impl aztec::note::note_interface::PartialNote<$setup_payload_name, $finalization_payload_name> for $name { @@ -595,7 +635,7 @@ comptime fn register_note( note_serialized_len: u32, note_type_id: Field, fixed_fields: [(Quoted, Type, u32)], - nullable_fields: [(Quoted, Type, u32)] + nullable_fields: [(Quoted, Type, u32)], ) { let mut fields = &[]; for field in fixed_fields { @@ -607,10 +647,7 @@ comptime fn register_note( fields = fields.push_back((name, index, true)); } - NOTES.insert( - note.as_type(), - (note, note_serialized_len, note_type_id, fields) - ); + NOTES.insert(note.as_type(), (note, note_serialized_len, note_type_id, fields)); } /// Separates note struct members into fixed and nullable ones. It also stores the index of where each struct member @@ -618,7 +655,7 @@ comptime fn register_note( /// An example of a struct member occupying multiple fields is `amount` in `TokenNote` that uses `U128` type. comptime fn index_note_fields( s: StructDefinition, - nullable_fields: [Quoted] + nullable_fields: [Quoted], ) -> ([(Quoted, Type, u32)], [(Quoted, Type, u32)]) { let mut indexed_fixed_fields: [(Quoted, Type, u32)] = &[]; let mut indexed_nullable_fields = &[]; @@ -626,7 +663,7 @@ comptime fn index_note_fields( for field in s.fields() { let (name, typ) = field; if (typ != NOTE_HEADER_TYPE) { - if nullable_fields.all(| field | field != name) { + if nullable_fields.all(|field| field != name) { indexed_fixed_fields = indexed_fixed_fields.push_back((name, typ, counter)); } else { indexed_nullable_fields = indexed_nullable_fields.push_back((name, typ, counter)); @@ -634,14 +671,14 @@ comptime fn index_note_fields( } let (flattened, _) = flatten_to_fields(name, typ, &[]); // Each struct member can occupy multiple fields so we need to increment the counter accordingly - counter+=flattened.len(); + counter += flattened.len(); } (indexed_fixed_fields, indexed_nullable_fields) } /// Injects `NoteHeader` to the note struct if not present. comptime fn inject_note_header(s: StructDefinition) { - let filtered_header = s.fields().filter(| (_, typ): (Quoted, Type) | typ == NOTE_HEADER_TYPE); + let filtered_header = s.fields().filter(|(_, typ): (Quoted, Type)| typ == NOTE_HEADER_TYPE); if (filtered_header.len() == 0) { let new_fields = s.fields().push_back((quote { header }, NOTE_HEADER_TYPE)); s.set_fields(new_fields); @@ -669,16 +706,24 @@ pub comptime fn partial_note(s: StructDefinition, nullable_fields: [Quoted]) -> let note_properties = generate_note_properties(s); let note_type_id = compute_note_type_id(s.name()); - let (setup_payload_impl, setup_payload_name) = generate_setup_payload(s, indexed_fixed_fields, indexed_nullable_fields); - let (finalization_payload_impl, finalization_payload_name) = generate_finalization_payload(s, indexed_fixed_fields, indexed_nullable_fields); - let (note_interface_impl, note_serialized_len) = generate_note_interface(s, note_type_id, indexed_fixed_fields, indexed_nullable_fields); - let partial_note_impl = generate_partial_note_impl(s, setup_payload_name, finalization_payload_name); + let (setup_payload_impl, setup_payload_name) = + generate_setup_payload(s, indexed_fixed_fields, indexed_nullable_fields); + let (finalization_payload_impl, finalization_payload_name) = + generate_finalization_payload(s, indexed_fixed_fields, indexed_nullable_fields); + let (note_interface_impl, note_serialized_len) = generate_note_interface( + s, + note_type_id, + indexed_fixed_fields, + indexed_nullable_fields, + ); + let partial_note_impl = + generate_partial_note_impl(s, setup_payload_name, finalization_payload_name); register_note( s, note_serialized_len, note_type_id, indexed_fixed_fields, - indexed_nullable_fields + indexed_nullable_fields, ); quote { @@ -704,13 +749,18 @@ pub comptime fn note(s: StructDefinition) -> Quoted { let note_properties = generate_note_properties(s); let note_type_id = compute_note_type_id(s.name()); - let (note_interface_impl, note_serialized_len) = generate_note_interface(s, note_type_id, indexed_fixed_fields, indexed_nullable_fields); + let (note_interface_impl, note_serialized_len) = generate_note_interface( + s, + note_type_id, + indexed_fixed_fields, + indexed_nullable_fields, + ); register_note( s, note_serialized_len, note_type_id, indexed_fixed_fields, - indexed_nullable_fields + indexed_nullable_fields, ); quote { @@ -730,10 +780,17 @@ pub comptime fn note_custom_interface(s: StructDefinition) -> Quoted { let note_properties = generate_note_properties(s); let note_type_id = compute_note_type_id(s.name()); let serialized_len_type = fresh_type_variable(); - let note_interface_impl = s.as_type().get_trait_impl(quote { crate::note::note_interface::NoteInterface<$serialized_len_type> }.as_trait_constraint()); + let note_interface_impl = s.as_type().get_trait_impl( + quote { crate::note::note_interface::NoteInterface<$serialized_len_type> } + .as_trait_constraint(), + ); let name = s.name(); - let note_serialized_len = note_interface_impl.expect(f"Note {name} must implement NoteInterface trait").trait_generic_args()[0].as_constant().unwrap(); + let note_serialized_len = note_interface_impl + .expect(f"Note {name} must implement NoteInterface trait") + .trait_generic_args()[0] + .as_constant() + .unwrap(); let (indexed_fixed_fields, indexed_nullable_fields) = index_note_fields(s, &[]); register_note( @@ -741,7 +798,7 @@ pub comptime fn note_custom_interface(s: StructDefinition) -> Quoted { note_serialized_len, note_type_id, indexed_fixed_fields, - indexed_nullable_fields + indexed_nullable_fields, ); quote { diff --git a/noir-projects/aztec-nr/aztec/src/macros/storage/mod.nr b/noir-projects/aztec-nr/aztec/src/macros/storage/mod.nr index 391f6cc874b..c9535db0716 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/storage/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/storage/mod.nr @@ -1,9 +1,13 @@ -use std::{collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}, meta::unquote}; +use std::{ + collections::umap::UHashMap, hash::{BuildHasherDefault, poseidon2::Poseidon2Hasher}, + meta::unquote, +}; use super::utils::get_serialized_size; use super::utils::is_note; -comptime mut global STORAGE_LAYOUT_NAME: UHashMap> = UHashMap::default(); +comptime mut global STORAGE_LAYOUT_NAME: UHashMap> = + UHashMap::default(); /// Marks a struct as the one describing the storage layout of a contract. Only a single struct in the entire contract /// should have this macro (or `storage_no_init`) applied to it. @@ -16,25 +20,28 @@ pub comptime fn storage(s: StructDefinition) -> Quoted { // - it implements said `init` function by allocating appropriate storage slots to each state variable. // - it exposes the storage layout by creating a `StorageLayout` struct that is exposed via the `abi(storage)` // macro. - let mut slot: u32 = 1; let mut storage_vars_constructors = &[]; let mut storage_layout_fields = &[]; let mut storage_layout_constructors = &[]; // TODO(#8658): uncomment the code below to inject the Context type parameter. - //let mut new_storage_fields = &[]; //let context_generic = s.add_generic("Context"); for field in s.fields() { let (name, typ) = field; - let (storage_field_constructor, serialized_size) = generate_storage_field_constructor(typ, quote { $slot }, false); - storage_vars_constructors = storage_vars_constructors.push_back(quote { $name: $storage_field_constructor }); + let (storage_field_constructor, serialized_size) = + generate_storage_field_constructor(typ, quote { $slot }, false); + storage_vars_constructors = + storage_vars_constructors.push_back(quote { $name: $storage_field_constructor }); // We have `Storable` in a separate `.nr` file instead of defining it in the last quote of this function // because that way a dev gets a more reasonable error if he defines a struct with the same name in // a contract. - storage_layout_fields = storage_layout_fields.push_back(quote { $name: dep::aztec::prelude::Storable }); - storage_layout_constructors = storage_layout_constructors.push_back(quote { $name: dep::aztec::prelude::Storable { slot: $slot } }); + storage_layout_fields = + storage_layout_fields.push_back(quote { $name: dep::aztec::prelude::Storable }); + storage_layout_constructors = storage_layout_constructors.push_back( + quote { $name: dep::aztec::prelude::Storable { slot: $slot } }, + ); //let with_context_generic = add_context_generic(typ, context_generic); //println(with_context_generic); //new_storage_fields = new_storage_fields.push_back((name, with_context_generic )); @@ -42,7 +49,6 @@ pub comptime fn storage(s: StructDefinition) -> Quoted { } //s.set_fields(new_storage_fields); - let storage_vars_constructors = storage_vars_constructors.join(quote {,}); let storage_impl = quote { impl Storage { @@ -95,16 +101,22 @@ pub comptime fn storage_no_init(_s: StructDefinition) { /// Returns the expression required to initialize a state variable with a given slot, along with its serialization size, /// i.e. how many contiguous storage slots the variable requires. -comptime fn generate_storage_field_constructor(typ: Type, slot: Quoted, parent_is_map: bool) -> (Quoted, u32) { +comptime fn generate_storage_field_constructor( + typ: Type, + slot: Quoted, + parent_is_map: bool, +) -> (Quoted, u32) { assert( - typ.as_struct().is_some(), "Storage containers must be generic structs of the form `Container<_, Context>`, or Map" + typ.as_struct().is_some(), + "Storage containers must be generic structs of the form `Container<_, Context>`, or Map", ); let (container_struct, generics) = typ.as_struct().unwrap(); let struct_name = container_struct.name(); if is_storage_map(typ) { // Map state variables recursively initialize their contents - this includes nested maps. - let (value_constructor, _) = generate_storage_field_constructor(generics[1], quote { slot }, true); + let (value_constructor, _) = + generate_storage_field_constructor(generics[1], quote { slot }, true); (quote { $struct_name::new(context, $slot, | context, slot | { $value_constructor }) }, 1) } else { let (container_struct, container_struct_generics) = typ.as_struct().unwrap(); @@ -119,7 +131,6 @@ comptime fn generate_storage_field_constructor(typ: Type, slot: Quoted, parent_i if is_note(stored_struct) & (container_struct_name != quote { PublicMutable }) { // Private notes always occupy a single slot, since the slot is only used as a state variable // identifier. - // Someone could store a Note in PublicMutable for whatever reason though. // TODO(#8659): remove the PublicMutable exception above 1 @@ -152,7 +163,9 @@ comptime fn is_storage_map(typ: Type) -> bool { } comptime fn add_context_generic(typ: Type, context_generic: Type) -> Type { - let (def, mut generics) = typ.as_struct().expect(f"Storage containers must be generic structs of the form `Container<..., Context>`"); + let (def, mut generics) = typ.as_struct().expect( + f"Storage containers must be generic structs of the form `Container<..., Context>`", + ); let name = def.name(); if is_storage_map(typ) { @@ -162,6 +175,6 @@ comptime fn add_context_generic(typ: Type, context_generic: Type) -> Type { generics[generics.len() - 1] = context_generic; } - let generics = generics.map(|typ: Type| quote{$typ}).join(quote{,}); + let generics = generics.map(|typ: Type| quote {$typ}).join(quote {,}); quote { $name<$generics> }.as_type() } diff --git a/noir-projects/aztec-nr/aztec/src/macros/utils.nr b/noir-projects/aztec-nr/aztec/src/macros/utils.nr index 27c2086246e..7eb80d1c650 100644 --- a/noir-projects/aztec-nr/aztec/src/macros/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/macros/utils.nr @@ -37,16 +37,13 @@ pub(crate) comptime fn fn_has_noinitcheck(f: FunctionDefinition) -> bool { /// Takes a function body as a collection of expressions, and alters it by prepending and appending quoted values. pub(crate) comptime fn modify_fn_body(body: [Expr], prepend: Quoted, append: Quoted) -> Expr { // We need to quote the body before we can alter its contents, so we fold it by quoting each expression. - let mut body_quote = body.fold( - quote {}, - |full_quote: Quoted, expr: Expr| { - let expr_quote = expr.quoted(); - quote { + let mut body_quote = body.fold(quote {}, |full_quote: Quoted, expr: Expr| { + let expr_quote = expr.quoted(); + quote { $full_quote $expr_quote } - } - ); + }); body_quote = quote { { $prepend @@ -77,7 +74,9 @@ pub(crate) comptime fn add_to_field_slice(slice_name: Quoted, name: Quoted, typ: $slice_name = $slice_name.append($name.as_bytes().map(| byte: u8 | byte as Field).as_slice()); } } else { - panic(f"Cannot add to slice: unsupported type {typ} variable {name}") + panic( + f"Cannot add to slice: unsupported type {typ} variable {name}", + ) } } @@ -101,13 +100,15 @@ pub(crate) comptime fn add_to_hasher(hasher_name: Quoted, name: Quoted, typ: Typ $hasher_name.add_multiple($name.as_bytes().map(| byte: u8 | byte as Field)); } } else { - panic(f"Cannot add to hasher: unsupported type {typ} of variable {name}") + panic( + f"Cannot add to hasher: unsupported type {typ} of variable {name}", + ) } } comptime fn signature_of_type(typ: Type) -> Quoted { if typ.is_field() { - quote{Field} + quote {Field} } else if typ.as_integer().is_some() { let (is_signed, bit_size) = typ.as_integer().unwrap(); if is_signed { @@ -128,20 +129,13 @@ comptime fn signature_of_type(typ: Type) -> Quoted { f"[{element_typ_quote};{array_len}]".quoted_contents() } else if typ.as_struct().is_some() { let (s, _) = typ.as_struct().unwrap(); - let field_signatures = s.fields().map( - | (_, typ): (Quoted, Type) | { - signature_of_type(typ) - } - ).join(quote {,}); + let field_signatures = + s.fields().map(|(_, typ): (Quoted, Type)| { signature_of_type(typ) }).join(quote {,}); f"({field_signatures})".quoted_contents() } else if typ.as_tuple().is_some() { // Note that tuples are handled the same way as structs let types = typ.as_tuple().unwrap(); - let field_signatures = types.map( - | typ: Type | { - signature_of_type(typ) - } - ).join(quote {,}); + let field_signatures = types.map(|typ: Type| { signature_of_type(typ) }).join(quote {,}); f"({field_signatures})".quoted_contents() } else { panic(f"Unsupported type {typ}") @@ -170,7 +164,7 @@ impl AsStrQuote for Quoted { quote { let signature_as_array: [u8; $total_len] = $acc.as_array(); signature_as_array.as_str_unchecked() - } + }, ); quote { $result } } @@ -183,13 +177,9 @@ pub(crate) comptime fn compute_fn_selector(f: FunctionDefinition) -> Field { // fn foo(a: Field, b: AztecAddress) -> Field // // The signature will be "foo(Field,AztecAddress)". - let fn_name = f.name(); - let args_signatures = f.parameters().map( - | (_, typ): (Quoted, Type) | { - signature_of_type(typ) - } - ).join(quote {,}); + let args_signatures = + f.parameters().map(|(_, typ): (Quoted, Type)| { signature_of_type(typ) }).join(quote {,}); let signature_quote = quote { $fn_name($args_signatures) }; let signature_str_quote = signature_quote.as_str_quote(); @@ -209,13 +199,13 @@ pub(crate) comptime fn compute_event_selector(s: StructDefinition) -> Field { // } // // The signature will be "Foo(Field,AztecAddress)". - let event_name = s.name(); - let args_signatures = s.fields().map( - | (_, typ): (Quoted, Type) | { + let args_signatures = s + .fields() + .map(|(_, typ): (Quoted, Type)| { signature_of_type(typ) // signature_of_type can handle structs, so this supports nested structs - } - ).join(quote {,}); + }) + .join(quote {,}); let signature_quote = quote { $event_name($args_signatures) }; let signature_str_quote = signature_quote.as_str_quote(); @@ -227,15 +217,22 @@ pub(crate) comptime fn compute_event_selector(s: StructDefinition) -> Field { pub(crate) comptime fn get_serialized_size(typ: Type) -> u32 { let any = fresh_type_variable(); - let maybe_serialize_impl = typ.get_trait_impl(quote { protocol_types::traits::Serialize<$any> }.as_trait_constraint()); + let maybe_serialize_impl = + typ.get_trait_impl(quote { protocol_types::traits::Serialize<$any> }.as_trait_constraint()); - maybe_serialize_impl.expect(f"Attempted to fetch serialization length, but {typ} does not implement the Serialize trait").trait_generic_args()[0].as_constant().unwrap() + maybe_serialize_impl + .expect( + f"Attempted to fetch serialization length, but {typ} does not implement the Serialize trait", + ) + .trait_generic_args()[0] + .as_constant() + .unwrap() } pub(crate) comptime fn module_has_storage(m: Module) -> bool { - m.structs().any( - |s: StructDefinition| s.has_named_attribute("storage") | s.has_named_attribute("storage_no_init") - ) + m.structs().any(|s: StructDefinition| { + s.has_named_attribute("storage") | s.has_named_attribute("storage_no_init") + }) } pub(crate) comptime fn module_has_initializer(m: Module) -> bool { @@ -243,11 +240,10 @@ pub(crate) comptime fn module_has_initializer(m: Module) -> bool { } pub(crate) comptime fn is_note(typ: Type) -> bool { - typ.as_struct().map_or( - false, - | struc: (StructDefinition, [Type]) | { - let (def, _) = struc; - def.has_named_attribute("note") | def.has_named_attribute("partial_note") | def.has_named_attribute("note_custom_interface") - } - ) + typ.as_struct().map_or(false, |struc: (StructDefinition, [Type])| { + let (def, _) = struc; + def.has_named_attribute("note") + | def.has_named_attribute("partial_note") + | def.has_named_attribute("note_custom_interface") + }) } diff --git a/noir-projects/aztec-nr/aztec/src/messaging.nr b/noir-projects/aztec-nr/aztec/src/messaging.nr index aecc3db1c07..ffeddf4d72f 100644 --- a/noir-projects/aztec-nr/aztec/src/messaging.nr +++ b/noir-projects/aztec-nr/aztec/src/messaging.nr @@ -1,9 +1,11 @@ use crate::{ hash::{compute_secret_hash, compute_message_hash, compute_message_nullifier}, - oracle::get_l1_to_l2_membership_witness::get_l1_to_l2_membership_witness + oracle::get_l1_to_l2_membership_witness::get_l1_to_l2_membership_witness, }; -use dep::protocol_types::{address::{AztecAddress, EthAddress}, merkle_tree::root::root_from_sibling_path}; +use dep::protocol_types::{ + address::{AztecAddress, EthAddress}, merkle_tree::root::root_from_sibling_path, +}; pub fn process_l1_to_l2_message( l1_to_l2_root: Field, @@ -12,7 +14,7 @@ pub fn process_l1_to_l2_message( chain_id: Field, version: Field, content: Field, - secret: Field + secret: Field, ) -> Field { let secret_hash = compute_secret_hash(secret); let message_hash = compute_message_hash( @@ -21,14 +23,13 @@ pub fn process_l1_to_l2_message( contract_address, version, content, - secret_hash + secret_hash, ); // We prove that `message_hash` is in the tree by showing the derivation of the tree root, using a merkle path we // get from an oracle. - let (leaf_index, sibling_path) = unsafe { - get_l1_to_l2_membership_witness(contract_address, message_hash, secret) - }; + let (leaf_index, sibling_path) = + unsafe { get_l1_to_l2_membership_witness(contract_address, message_hash, secret) }; let root = root_from_sibling_path(message_hash, leaf_index, sibling_path); assert(root == l1_to_l2_root, "Message not in state"); diff --git a/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr b/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr index 8d07d8c40ba..a348ef3f876 100644 --- a/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr +++ b/noir-projects/aztec-nr/aztec/src/note/lifecycle.nr @@ -2,15 +2,18 @@ use crate::context::{PrivateContext, PublicContext}; use crate::note::{ note_header::NoteHeader, note_interface::{NoteInterface, NullifiableNote}, utils::{compute_note_hash_for_read_request, compute_note_hash_for_nullify_internal}, - note_emission::NoteEmission + note_emission::NoteEmission, }; use crate::oracle::notes::{notify_created_note, notify_nullified_note}; pub fn create_note( context: &mut PrivateContext, storage_slot: Field, - note: &mut Note -) -> NoteEmission where Note: NoteInterface + NullifiableNote { + note: &mut Note, +) -> NoteEmission +where + Note: NoteInterface + NullifiableNote, +{ let contract_address = (*context).this_address(); let note_hash_counter = context.side_effect_counter; @@ -24,7 +27,7 @@ pub fn create_note( Note::get_note_type_id(), serialized_note, note_hash, - note_hash_counter + note_hash_counter, ); context.push_note_hash(note_hash); @@ -35,8 +38,11 @@ pub fn create_note( pub fn create_note_hash_from_public( context: &mut PublicContext, storage_slot: Field, - note: &mut Note -) where Note: NoteInterface + NullifiableNote { + note: &mut Note, +) +where + Note: NoteInterface + NullifiableNote, +{ let contract_address = (*context).this_address(); // Public note hashes are transient, but have no side effect counters, so we just need note_hash_counter != 0 let header = NoteHeader { contract_address, storage_slot, nonce: 0, note_hash_counter: 1 }; @@ -47,10 +53,10 @@ pub fn create_note_hash_from_public( } // Note: This function is currently totally unused. -pub fn destroy_note( - context: &mut PrivateContext, - note: Note -) where Note: NoteInterface + NullifiableNote { +pub fn destroy_note(context: &mut PrivateContext, note: Note) +where + Note: NoteInterface + NullifiableNote, +{ let note_hash_for_read_request = compute_note_hash_for_read_request(note); destroy_note_unsafe(context, note, note_hash_for_read_request) @@ -59,9 +65,13 @@ pub fn destroy_note( pub fn destroy_note_unsafe( context: &mut PrivateContext, note: Note, - note_hash_for_read_request: Field -) where Note: NoteInterface + NullifiableNote { - let note_hash_for_nullify = compute_note_hash_for_nullify_internal(note, note_hash_for_read_request); + note_hash_for_read_request: Field, +) +where + Note: NoteInterface + NullifiableNote, +{ + let note_hash_for_nullify = + compute_note_hash_for_nullify_internal(note, note_hash_for_read_request); let nullifier = note.compute_nullifier(context, note_hash_for_nullify); let note_hash_counter = note.get_header().note_hash_counter; diff --git a/noir-projects/aztec-nr/aztec/src/note/note_emission.nr b/noir-projects/aztec-nr/aztec/src/note/note_emission.nr index 2c89b39b7e8..a9f9ee13fbd 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_emission.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_emission.nr @@ -3,7 +3,7 @@ * The exact `emit` logic is passed in by the application code */ pub struct NoteEmission { - note: Note + note: Note, } impl NoteEmission { diff --git a/noir-projects/aztec-nr/aztec/src/note/note_field.nr b/noir-projects/aztec-nr/aztec/src/note/note_field.nr index 35e7fbc282a..f5c740a1e5c 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_field.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_field.nr @@ -1,5 +1,5 @@ // Used by macros when generating note export. pub struct NoteField { index: u32, - nullable: bool + nullable: bool, } diff --git a/noir-projects/aztec-nr/aztec/src/note/note_getter/mod.nr b/noir-projects/aztec-nr/aztec/src/note/note_getter/mod.nr index 9185bccdd3b..fb463154c9d 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_getter/mod.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_getter/mod.nr @@ -1,10 +1,12 @@ -use dep::protocol_types::{constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, GET_NOTES_ORACLE_RETURN_LENGTH}}; +use dep::protocol_types::constants::{ + MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, GET_NOTES_ORACLE_RETURN_LENGTH, +}; use crate::context::PrivateContext; use crate::note::{ constants::{GET_NOTE_ORACLE_RETURN_LENGTH, VIEW_NOTE_ORACLE_RETURN_LENGTH}, note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, NoteStatus, PropertySelector}, note_interface::{NoteInterface, NullifiableNote}, note_viewer_options::NoteViewerOptions, - utils::compute_note_hash_for_read_request + utils::compute_note_hash_for_read_request, }; use crate::oracle; use crate::utils::comparison::compare; @@ -15,7 +17,7 @@ mod test; fn extract_property_value_from_selector( serialized_note: [Field; N], - selector: PropertySelector + selector: PropertySelector, ) -> Field { // Selectors use PropertySelectors in order to locate note properties inside the serialized note. // This allows easier packing and custom (de)serialization schemas. A note property is located @@ -34,11 +36,10 @@ fn extract_property_value_from_selector( value_field } -fn check_note_header( - context: PrivateContext, - storage_slot: Field, - note: Note -) where Note: NoteInterface { +fn check_note_header(context: PrivateContext, storage_slot: Field, note: Note) +where + Note: NoteInterface, +{ let header = note.get_header(); let contract_address = context.this_address(); assert(header.contract_address.eq(contract_address), "Mismatch note header contract address."); @@ -47,14 +48,16 @@ fn check_note_header( fn check_note_fields( serialized_note: [Field; N], - selects: BoundedVec, N> + selects: BoundedVec, N>, ) { for i in 0..selects.len { let select = selects.get_unchecked(i).unwrap_unchecked(); - let value_field = extract_property_value_from_selector(serialized_note, select.property_selector); + let value_field = + extract_property_value_from_selector(serialized_note, select.property_selector); assert( - compare(value_field, select.comparator, select.value.to_field()), "Mismatch return note field." + compare(value_field, select.comparator, select.value.to_field()), + "Mismatch return note field.", ); } } @@ -62,7 +65,7 @@ fn check_note_fields( fn check_notes_order( fields_0: [Field; N], fields_1: [Field; N], - sorts: BoundedVec, N> + sorts: BoundedVec, N>, ) { for i in 0..sorts.len { let sort = sorts.get_unchecked(i).unwrap_unchecked(); @@ -80,11 +83,12 @@ fn check_notes_order( pub fn get_note( context: &mut PrivateContext, - storage_slot: Field -) -> (Note, Field) where Note: NoteInterface + NullifiableNote { - let note = unsafe { - get_note_internal(storage_slot) - }; + storage_slot: Field, +) -> (Note, Field) +where + Note: NoteInterface + NullifiableNote, +{ + let note = unsafe { get_note_internal(storage_slot) }; // Constraining that we got a valid note from the oracle is fairly straightforward: all we need to do is check that // the metadata is correct, and that the note exists. @@ -99,11 +103,12 @@ pub fn get_note( pub fn get_notes( context: &mut PrivateContext, storage_slot: Field, - options: NoteGetterOptions -) -> (BoundedVec, BoundedVec) where Note: NoteInterface + NullifiableNote + Eq { - let opt_notes = unsafe { - get_notes_internal(storage_slot, options) - }; + options: NoteGetterOptions, + ) -> (BoundedVec, BoundedVec) +where + Note: NoteInterface + NullifiableNote + Eq, +{ + let opt_notes = unsafe { get_notes_internal(storage_slot, options) }; // We apply the constraints in a separate function instead of inlining them here to make it easier to test that // these checks correctly reject bad notes. @@ -113,7 +118,7 @@ pub fn get_notes( unconstrained fn apply_preprocessor( notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], preprocessor: fn([Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], PREPROCESSOR_ARGS) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - preprocessor_args: PREPROCESSOR_ARGS + preprocessor_args: PREPROCESSOR_ARGS, ) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] { preprocessor(notes, preprocessor_args) } @@ -122,8 +127,11 @@ fn constrain_get_notes_internal; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - options: NoteGetterOptions -) -> (BoundedVec, BoundedVec) where Note: NoteInterface + NullifiableNote + Eq { + options: NoteGetterOptions, + ) -> (BoundedVec, BoundedVec) +where + Note: NoteInterface + NullifiableNote + Eq, +{ // The filter is applied first to avoid pushing note read requests for notes we're not interested in. Note that // while the filter function can technically mutate the contents of the notes (as opposed to simply removing some), // the private kernel will later validate that these note actually exist, so transformations would cause for that @@ -133,7 +141,8 @@ fn constrain_get_notes_internal = BoundedVec::new(); + let mut note_hashes: BoundedVec = + BoundedVec::new(); // We have now collapsed the sparse array of Options into a BoundedVec. This is a more ergonomic type and also // results in reduced gate counts when setting a limit value, since we guarantee that the limit is an upper bound @@ -163,7 +172,10 @@ fn constrain_get_notes_internal(storage_slot: Field) -> Note where Note: NoteInterface { +unconstrained fn get_note_internal(storage_slot: Field) -> Note +where + Note: NoteInterface, +{ let placeholder_note = [Option::none()]; let placeholder_fields = [0; GET_NOTE_ORACLE_RETURN_LENGTH]; let placeholder_note_length = [0; N]; @@ -184,17 +196,21 @@ unconstrained fn get_note_internal(storage_slot: Field) -> Not NoteStatus.ACTIVE, placeholder_note, placeholder_fields, - placeholder_note_length - )[0].expect(f"Failed to get a note") // Notice: we don't allow dummies to be returned from get_note (singular). + placeholder_note_length, + )[0] + .expect(f"Failed to get a note") // Notice: we don't allow dummies to be returned from get_note (singular). } unconstrained fn get_notes_internal( storage_slot: Field, - options: NoteGetterOptions -) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where Note: NoteInterface { + options: NoteGetterOptions, +) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] +where + Note: NoteInterface, +{ // This function simply performs some transformations from NoteGetterOptions into the types required by the oracle. - - let (num_selects, select_by_indexes, select_by_offsets, select_by_lengths, select_values, select_comparators, sort_by_indexes, sort_by_offsets, sort_by_lengths, sort_order) = flatten_options(options.selects, options.sorts); + let (num_selects, select_by_indexes, select_by_offsets, select_by_lengths, select_values, select_comparators, sort_by_indexes, sort_by_offsets, sort_by_lengths, sort_order) = + flatten_options(options.selects, options.sorts); let placeholder_opt_notes = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; let placeholder_fields = [0; GET_NOTES_ORACLE_RETURN_LENGTH]; let placeholder_note_length = [0; N]; @@ -216,7 +232,7 @@ unconstrained fn get_notes_internal( storage_slot: Field, - options: NoteViewerOptions -) -> BoundedVec where Note: NoteInterface { - let (num_selects, select_by_indexes, select_by_offsets, select_by_lengths, select_values, select_comparators, sort_by_indexes, sort_by_offsets, sort_by_lengths, sort_order) = flatten_options(options.selects, options.sorts); + options: NoteViewerOptions, +) -> BoundedVec +where + Note: NoteInterface, +{ + let (num_selects, select_by_indexes, select_by_offsets, select_by_lengths, select_values, select_comparators, sort_by_indexes, sort_by_offsets, sort_by_lengths, sort_order) = + flatten_options(options.selects, options.sorts); let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE]; let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH]; let placeholder_note_length = [0; N]; @@ -248,7 +268,7 @@ pub unconstrained fn view_notes( options.status, placeholder_opt_notes, placeholder_fields, - placeholder_note_length + placeholder_note_length, ); let mut notes = BoundedVec::new(); @@ -263,7 +283,7 @@ pub unconstrained fn view_notes( unconstrained fn flatten_options( selects: BoundedVec, N>, - sorts: BoundedVec, N> + sorts: BoundedVec, N>, ) -> (u8, [u8; N], [u8; N], [u8; N], [Field; N], [u8; N], [u8; N], [u8; N], [u8; N], [u8; N]) { let mut num_selects = 0; let mut select_by_indexes = [0; N]; @@ -299,6 +319,7 @@ unconstrained fn flatten_options( } ( - num_selects, select_by_indexes, select_by_offsets, select_by_lengths, select_values, select_comparators, sort_by_indexes, sort_by_offsets, sort_by_lengths, sort_order + num_selects, select_by_indexes, select_by_offsets, select_by_lengths, select_values, + select_comparators, sort_by_indexes, sort_by_offsets, sort_by_lengths, sort_order, ) } diff --git a/noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr b/noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr index a78c52a09e5..b9267de3c5a 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr @@ -1,10 +1,9 @@ use dep::protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL; use crate::{ note::{ - note_getter_options::{NoteGetterOptions, SortOrder, PropertySelector}, - note_getter::constrain_get_notes_internal -}, - oracle::execution::get_contract_address + note_getter_options::{NoteGetterOptions, SortOrder, PropertySelector}, + note_getter::constrain_get_notes_internal, + }, oracle::execution::get_contract_address, }; use crate::test::{helpers::test_environment::TestEnvironment, mocks::mock_note::MockNote}; @@ -25,8 +24,11 @@ unconstrained fn build_valid_note(value: Field) -> MockNote { unconstrained fn assert_equivalent_vec_and_array( vec: BoundedVec, - arr: [Option; N] -) where T: Eq { + arr: [Option; N], +) +where + T: Eq, +{ let mut count = 0; for i in 0..N { @@ -48,7 +50,8 @@ unconstrained fn processes_single_note() { notes_to_constrain[0] = Option::some(build_valid_note(13)); let options = NoteGetterOptions::new(); - let (returned, _) = constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options); + let (returned, _) = + constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options); assert_equivalent_vec_and_array(returned, notes_to_constrain); assert_eq(context.note_hash_read_requests.len(), 1); @@ -64,7 +67,8 @@ unconstrained fn processes_many_notes() { notes_to_constrain[1] = Option::some(build_valid_note(19)); let options = NoteGetterOptions::new(); - let (returned, _) = constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options); + let (returned, _) = + constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options); assert_equivalent_vec_and_array(returned, notes_to_constrain); assert_eq(context.note_hash_read_requests.len(), 2); @@ -84,7 +88,8 @@ unconstrained fn collapses_notes_at_the_beginning_of_the_array() { opt_notes[13] = Option::some(build_valid_note(5)); let options = NoteGetterOptions::new(); - let (returned, _) = constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options); + let (returned, _) = + constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options); let mut expected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; expected[0] = Option::some(build_valid_note(0)); @@ -102,10 +107,12 @@ unconstrained fn can_return_zero_notes() { let mut env = setup(); let mut context = env.private(); - let opt_notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; + let opt_notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = + [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; let options = NoteGetterOptions::new(); - let (returned, _) = constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options); + let (returned, _) = + constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options); assert_eq(returned.len(), 0); } @@ -114,7 +121,8 @@ unconstrained fn rejects_mote_notes_than_limit() { let mut env = setup(); let mut context = env.private(); - let mut opt_notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; + let mut opt_notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = + [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; opt_notes[1] = Option::some(build_valid_note(0)); opt_notes[2] = Option::some(build_valid_note(1)); opt_notes[3] = Option::some(build_valid_note(2)); @@ -147,7 +155,8 @@ unconstrained fn applies_filter_before_constraining() { }; let options = NoteGetterOptions::with_filter(filter_fn, ()); - let (returned, _) = constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options); + let (returned, _) = + constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options); // Only the note with value 42 should be returned, and moved to the beginning of the array. The other notes were not // constrained, and hence validation did not fail. @@ -164,7 +173,6 @@ unconstrained fn rejects_mismatched_address() { let mut context = env.private(); let note = MockNote::new(1).storage_slot(storage_slot).build(); // We're not setting the right contract address - let mut opt_notes = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; opt_notes[0] = Option::some(note); @@ -178,7 +186,6 @@ unconstrained fn rejects_mismatched_storage_slot() { let mut context = env.private(); let note = MockNote::new(1).contract_address(get_contract_address()).build(); // We're not setting the right storage slot - let mut opt_notes = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; opt_notes[0] = Option::some(note); @@ -199,10 +206,10 @@ unconstrained fn rejects_mismatched_selector() { let mut options = NoteGetterOptions::new(); options = options.select( - PropertySelector { index: 0, offset: 0, length: 32 }, - Comparator.EQ, - value + 1 - ); + PropertySelector { index: 0, offset: 0, length: 32 }, + Comparator.EQ, + value + 1, + ); let _ = constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options); } @@ -218,10 +225,7 @@ unconstrained fn rejects_mismatched_desc_sort_order() { opt_notes[1] = Option::some(build_valid_note(2)); let mut options = NoteGetterOptions::new(); - options = options.sort( - PropertySelector { index: 0, offset: 0, length: 32 }, - SortOrder.DESC - ); + options = options.sort(PropertySelector { index: 0, offset: 0, length: 32 }, SortOrder.DESC); let _ = constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options); } @@ -236,9 +240,6 @@ unconstrained fn rejects_mismatched_asc_sort_order() { opt_notes[1] = Option::some(build_valid_note(1)); let mut options = NoteGetterOptions::new(); - options = options.sort( - PropertySelector { index: 0, offset: 0, length: 32 }, - SortOrder.ASC - ); + options = options.sort(PropertySelector { index: 0, offset: 0, length: 32 }, SortOrder.ASC); let _ = constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options); } diff --git a/noir-projects/aztec-nr/aztec/src/note/note_getter_options.nr b/noir-projects/aztec-nr/aztec/src/note/note_getter_options.nr index 519a6426cc4..452818b9c3b 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_getter_options.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_getter_options.nr @@ -27,10 +27,7 @@ pub struct SortOrderEnum { ASC: u8, } -global SortOrder = SortOrderEnum { - DESC: 1, - ASC: 2, -}; +global SortOrder = SortOrderEnum { DESC: 1, ASC: 2 }; pub struct Sort { property_selector: PropertySelector, @@ -57,7 +54,7 @@ global NoteStatus = NoteStatusEnum { // This is the default filter and preprocessor, which does nothing fn return_all_notes( notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - _p: Field + _p: Field, ) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] { notes } @@ -70,9 +67,9 @@ pub struct NoteGetterOptions { offset: u32, // Preprocessor and filter functions are used to filter notes. The preprocessor is applied before the filter and // unlike filter it is applied in an unconstrained context. - preprocessor: fn ([Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], PREPROCESSOR_ARGS) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], + preprocessor: fn([Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], PREPROCESSOR_ARGS) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], preprocessor_args: PREPROCESSOR_ARGS, - filter: fn ([Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], FILTER_ARGS) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], + filter: fn([Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], FILTER_ARGS) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], filter_args: FILTER_ARGS, status: u8, } @@ -93,8 +90,11 @@ impl NoteGetterOptions Self where T: ToField { + value: T, + ) -> Self + where + T: ToField, + { self.selects.push(Option::some(Select::new(property_selector, comparator, value.to_field()))); *self } @@ -132,7 +132,10 @@ impl NoteGetterOptions NoteGetterOptions where Note: NoteInterface { +impl NoteGetterOptions +where + Note: NoteInterface, +{ // This function initializes a NoteGetterOptions that simply returns the maximum number of notes allowed in a call. pub fn new() -> Self { Self { @@ -144,18 +147,21 @@ impl NoteGetterOptions where Note: Note preprocessor_args: 0, filter: return_all_notes, filter_args: 0, - status: NoteStatus.ACTIVE + status: NoteStatus.ACTIVE, } } } -impl NoteGetterOptions where Note: NoteInterface { +impl NoteGetterOptions +where + Note: NoteInterface, +{ // This function initializes a NoteGetterOptions with a preprocessor, which takes the notes returned from // the database and preprocessor_args as its parameters. // `preprocessor_args` allows you to provide additional data or context to the custom preprocessor. pub fn with_preprocessor( preprocessor: fn([Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], PREPROCESSOR_ARGS) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - preprocessor_args: PREPROCESSOR_ARGS + preprocessor_args: PREPROCESSOR_ARGS, ) -> Self { Self { selects: BoundedVec::new(), @@ -166,18 +172,21 @@ impl NoteGetterOptions NoteGetterOptions where Note: NoteInterface { +impl NoteGetterOptions +where + Note: NoteInterface, +{ // This function initializes a NoteGetterOptions with a filter, which takes // the notes returned from the database and filter_args as its parameters. // `filter_args` allows you to provide additional data or context to the custom filter. pub fn with_filter( filter: fn([Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], FILTER_ARGS) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - filter_args: FILTER_ARGS + filter_args: FILTER_ARGS, ) -> Self { Self { selects: BoundedVec::new(), @@ -188,7 +197,7 @@ impl NoteGetterOptions Self { - NoteHeader { contract_address: AztecAddress::zero(), nonce: 0, storage_slot: 0, note_hash_counter: 0 } + NoteHeader { + contract_address: AztecAddress::zero(), + nonce: 0, + storage_slot: 0, + note_hash_counter: 0, + } } } @@ -39,7 +44,10 @@ impl Serialize for NoteHeader { // (Serialize trait needs to be implemented for a note when it's passed as an argument to a contract function // --> then it's used when computing args hash.) [ - self.contract_address.to_field(), self.nonce, self.storage_slot, self.note_hash_counter as Field + self.contract_address.to_field(), + self.nonce, + self.storage_slot, + self.note_hash_counter as Field, ] } } diff --git a/noir-projects/aztec-nr/aztec/src/note/note_interface.nr b/noir-projects/aztec-nr/aztec/src/note/note_interface.nr index 7b1cc26f020..b2c0f5b8d17 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_interface.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_interface.nr @@ -44,7 +44,7 @@ pub trait NoteInterface { fn get_note_type_id() -> Field; // Autogenerated by the #[note] macro - fn to_be_bytes(self, storage_slot: Field) -> [u8; N*32 + 64]; + fn to_be_bytes(self, storage_slot: Field) -> [u8; N * 32 + 64]; // Autogenerated by the #[note] macro fn compute_note_hash(self) -> Field; diff --git a/noir-projects/aztec-nr/aztec/src/note/note_type_id.nr b/noir-projects/aztec-nr/aztec/src/note/note_type_id.nr index e69de29bb2d..8b137891791 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_type_id.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_type_id.nr @@ -0,0 +1 @@ + diff --git a/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr b/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr index ab0209c4b18..321e3d6c0ad 100644 --- a/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr +++ b/noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr @@ -15,13 +15,16 @@ pub struct NoteViewerOptions { // docs:end:NoteViewerOptions impl NoteViewerOptions { - pub fn new() -> NoteViewerOptions where Note: NoteInterface { + pub fn new() -> NoteViewerOptions + where + Note: NoteInterface, + { NoteViewerOptions { selects: BoundedVec::new(), sorts: BoundedVec::new(), limit: MAX_NOTES_PER_PAGE as u32, offset: 0, - status: NoteStatus.ACTIVE + status: NoteStatus.ACTIVE, } } @@ -33,8 +36,11 @@ impl NoteViewerOptions { &mut self, property_selector: PropertySelector, comparator: u8, - value: T - ) -> Self where T: ToField { + value: T, + ) -> Self + where + T: ToField, + { self.selects.push(Option::some(Select::new(property_selector, comparator, value.to_field()))); *self } diff --git a/noir-projects/aztec-nr/aztec/src/note/utils.nr b/noir-projects/aztec-nr/aztec/src/note/utils.nr index 7ff195bb09e..0dab8de2243 100644 --- a/noir-projects/aztec-nr/aztec/src/note/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/note/utils.nr @@ -1,20 +1,22 @@ use crate::{ context::PrivateContext, - note::{note_header::NoteHeader, note_interface::{NullifiableNote, NoteInterface}} + note::{note_header::NoteHeader, note_interface::{NullifiableNote, NoteInterface}}, }; use dep::protocol_types::{ hash::{ - compute_unique_note_hash, compute_siloed_note_hash as compute_siloed_note_hash, - compute_siloed_nullifier as compute_siloed_nullifier_from_preimage -}, - utils::arr_copy_slice + compute_unique_note_hash, compute_siloed_note_hash as compute_siloed_note_hash, + compute_siloed_nullifier as compute_siloed_nullifier_from_preimage, + }, utils::arr_copy_slice, }; pub fn compute_siloed_nullifier( note_with_header: Note, - context: &mut PrivateContext -) -> Field where Note: NoteInterface + NullifiableNote { + context: &mut PrivateContext, +) -> Field +where + Note: NoteInterface + NullifiableNote, +{ let header = note_with_header.get_header(); let note_hash_for_nullify = compute_note_hash_for_nullify(note_with_header); let inner_nullifier = note_with_header.compute_nullifier(context, note_hash_for_nullify); @@ -23,7 +25,10 @@ pub fn compute_siloed_nullifier( } // TODO(#7775): make this not impossible to understand -pub fn compute_note_hash_for_read_request(note: Note) -> Field where Note: NoteInterface + NullifiableNote { +pub fn compute_note_hash_for_read_request(note: Note) -> Field +where + Note: NoteInterface + NullifiableNote, +{ let note_hash = note.compute_note_hash(); let nonce = note.get_header().nonce; let counter = note.get_header().note_hash_counter; @@ -38,8 +43,11 @@ pub fn compute_note_hash_for_read_request(note: Note) -> Field // TODO(#7775): make this not impossible to understand pub fn compute_note_hash_for_nullify_internal( note: Note, - note_hash_for_read_request: Field -) -> Field where Note: NoteInterface + NullifiableNote { + note_hash_for_read_request: Field, +) -> Field +where + Note: NoteInterface + NullifiableNote, +{ let header = note.get_header(); if header.note_hash_counter != 0 { @@ -48,7 +56,8 @@ pub fn compute_note_hash_for_nullify_internal( note_hash_for_read_request } else { // Case 2: Non-revertible note, nullified by a revertible nullifier - let unique_note_hash = compute_unique_note_hash(header.nonce, note_hash_for_read_request); + let unique_note_hash = + compute_unique_note_hash(header.nonce, note_hash_for_read_request); compute_siloed_note_hash(header.contract_address, unique_note_hash) } } else { @@ -100,7 +109,10 @@ pub fn compute_note_hash_for_nullify_internal( // } // } -pub fn compute_note_hash_for_nullify(note: Note) -> Field where Note: NoteInterface + NullifiableNote { +pub fn compute_note_hash_for_nullify(note: Note) -> Field +where + Note: NoteInterface + NullifiableNote, +{ let note_hash_for_read_request = compute_note_hash_for_read_request(note); compute_note_hash_for_nullify_internal(note, note_hash_for_read_request) } @@ -109,8 +121,11 @@ pub unconstrained fn compute_note_hash_and_optionally_a_nullifier T, note_header: NoteHeader, compute_nullifier: bool, - serialized_note: [Field; S] -) -> [Field; 4] where T: NoteInterface + NullifiableNote { + serialized_note: [Field; S], +) -> [Field; 4] +where + T: NoteInterface + NullifiableNote, +{ let mut note = deserialize_content(arr_copy_slice(serialized_note, [0; N], 0)); note.set_header(note_header); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr b/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr index a6ea2b95de2..8321bccc27a 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/arguments.nr @@ -5,18 +5,14 @@ pub fn pack_arguments(args: [Field]) { // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When // unpacking however the caller must check that the returned value is indeed the preimage. - unsafe { - pack_arguments_oracle_wrapper(args) - }; + unsafe { pack_arguments_oracle_wrapper(args) }; } /// Same as `pack_arguments`, but using arrays instead of slices. pub fn pack_arguments_array(args: [Field; N]) { // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. When // unpacking however the caller must check that the returned value is indeed the preimage. - unsafe { - pack_arguments_array_oracle_wrapper(args) - }; + unsafe { pack_arguments_array_oracle_wrapper(args) }; } unconstrained fn pack_arguments_oracle_wrapper(args: [Field]) { diff --git a/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr b/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr index aae089cd731..16bb50aacf2 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/call_private_function.nr @@ -1,4 +1,6 @@ -use dep::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress, utils::reader::Reader}; +use dep::protocol_types::{ + abis::function_selector::FunctionSelector, address::AztecAddress, utils::reader::Reader, +}; #[oracle(callPrivateFunction)] unconstrained fn call_private_function_oracle( @@ -6,7 +8,7 @@ unconstrained fn call_private_function_oracle( _function_selector: FunctionSelector, _args_hash: Field, _start_side_effect_counter: u32, - _is_static_call: bool + _is_static_call: bool, ) -> [Field; 2] {} pub unconstrained fn call_private_function_internal( @@ -14,14 +16,14 @@ pub unconstrained fn call_private_function_internal( function_selector: FunctionSelector, args_hash: Field, start_side_effect_counter: u32, - is_static_call: bool + is_static_call: bool, ) -> (u32, Field) { let fields = call_private_function_oracle( contract_address, function_selector, args_hash, start_side_effect_counter, - is_static_call + is_static_call, ); let mut reader = Reader::new(fields); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr b/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr index 06a991fbdda..1bf5812d8b2 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr @@ -1,4 +1,4 @@ -use dep::protocol_types::{abis::{function_selector::FunctionSelector}, address::AztecAddress}; +use dep::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}; #[oracle(enqueuePublicFunctionCall)] unconstrained fn enqueue_public_function_call_oracle( @@ -6,7 +6,7 @@ unconstrained fn enqueue_public_function_call_oracle( _function_selector: FunctionSelector, _args_hash: Field, _side_effect_counter: u32, - _is_static_call: bool + _is_static_call: bool, ) -> Field {} pub unconstrained fn enqueue_public_function_call_internal( @@ -14,14 +14,14 @@ pub unconstrained fn enqueue_public_function_call_internal( function_selector: FunctionSelector, args_hash: Field, side_effect_counter: u32, - is_static_call: bool + is_static_call: bool, ) -> Field { enqueue_public_function_call_oracle( contract_address, function_selector, args_hash, side_effect_counter, - is_static_call + is_static_call, ) } @@ -31,7 +31,7 @@ unconstrained fn set_public_teardown_function_call_oracle( _function_selector: FunctionSelector, _args_hash: Field, _side_effect_counter: u32, - _is_static_call: bool + _is_static_call: bool, ) -> Field {} pub unconstrained fn set_public_teardown_function_call_internal( @@ -39,21 +39,19 @@ pub unconstrained fn set_public_teardown_function_call_internal( function_selector: FunctionSelector, args_hash: Field, side_effect_counter: u32, - is_static_call: bool + is_static_call: bool, ) -> Field { set_public_teardown_function_call_oracle( contract_address, function_selector, args_hash, side_effect_counter, - is_static_call + is_static_call, ) } pub fn notify_set_min_revertible_side_effect_counter(counter: u32) { - unsafe { - notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter) - }; + unsafe { notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter) }; } pub unconstrained fn notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter: u32) { diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr index 0912dd49d02..7e8416c50c9 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_contract_instance.nr @@ -1,27 +1,34 @@ use dep::protocol_types::{ address::AztecAddress, contract_instance::ContractInstance, constants::CONTRACT_INSTANCE_LENGTH, - utils::reader::Reader + utils::reader::Reader, }; #[oracle(getContractInstance)] -unconstrained fn get_contract_instance_oracle(_address: AztecAddress) -> [Field; CONTRACT_INSTANCE_LENGTH] {} +unconstrained fn get_contract_instance_oracle( + _address: AztecAddress, +) -> [Field; CONTRACT_INSTANCE_LENGTH] {} // Returns a ContractInstance plus a boolean indicating whether the instance was found. #[oracle(avmOpcodeGetContractInstance)] -unconstrained fn get_contract_instance_oracle_avm(_address: AztecAddress) -> [Field; CONTRACT_INSTANCE_LENGTH + 1] {} +unconstrained fn get_contract_instance_oracle_avm( + _address: AztecAddress, +) -> [Field; CONTRACT_INSTANCE_LENGTH + 1] {} -unconstrained fn get_contract_instance_internal(address: AztecAddress) -> [Field; CONTRACT_INSTANCE_LENGTH] { +unconstrained fn get_contract_instance_internal( + address: AztecAddress, +) -> [Field; CONTRACT_INSTANCE_LENGTH] { get_contract_instance_oracle(address) } -pub unconstrained fn get_contract_instance_internal_avm(address: AztecAddress) -> [Field; CONTRACT_INSTANCE_LENGTH + 1] { +pub unconstrained fn get_contract_instance_internal_avm( + address: AztecAddress, +) -> [Field; CONTRACT_INSTANCE_LENGTH + 1] { get_contract_instance_oracle_avm(address) } pub fn get_contract_instance(address: AztecAddress) -> ContractInstance { - let instance = unsafe { - ContractInstance::deserialize(get_contract_instance_internal(address)) - }; + let instance = + unsafe { ContractInstance::deserialize(get_contract_instance_internal(address)) }; // The to_address function combines all values in the instance object to produce an address, so by checking that we // get the expected address we validate the entire struct. assert_eq(instance.to_address(), address); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr index b5774779874..313791269c4 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_l1_to_l2_membership_witness.nr @@ -1,13 +1,16 @@ -use dep::protocol_types::{address::AztecAddress, constants::L1_TO_L2_MSG_TREE_HEIGHT, utils::arr_copy_slice}; +use dep::protocol_types::{ + address::AztecAddress, constants::L1_TO_L2_MSG_TREE_HEIGHT, utils::arr_copy_slice, +}; /// Returns the leaf index and sibling path of an entry in the L1 to L2 messaging tree, which can then be used to prove /// its existence. pub unconstrained fn get_l1_to_l2_membership_witness( contract_address: AztecAddress, message_hash: Field, - secret: Field + secret: Field, ) -> (Field, [Field; L1_TO_L2_MSG_TREE_HEIGHT]) { - let returned_message = get_l1_to_l2_membership_witness_oracle(contract_address, message_hash, secret); + let returned_message = + get_l1_to_l2_membership_witness_oracle(contract_address, message_hash, secret); let leaf_index = returned_message[0]; let sibling_path = arr_copy_slice(returned_message, [0; L1_TO_L2_MSG_TREE_HEIGHT], 1); @@ -19,5 +22,5 @@ pub unconstrained fn get_l1_to_l2_membership_witness( unconstrained fn get_l1_to_l2_membership_witness_oracle( _contract_address: AztecAddress, _message_hash: Field, - _secret: Field + _secret: Field, ) -> [Field; L1_TO_L2_MSG_TREE_HEIGHT + 1] {} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_membership_witness.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_membership_witness.nr index c4f81e072c2..3987fab937a 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_membership_witness.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_membership_witness.nr @@ -1,4 +1,6 @@ -use dep::protocol_types::{constants::{ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT}, utils::arr_copy_slice}; +use dep::protocol_types::{ + constants::{ARCHIVE_HEIGHT, NOTE_HASH_TREE_HEIGHT}, utils::arr_copy_slice, +}; global NOTE_HASH_TREE_ID = 1; global ARCHIVE_TREE_ID = 4; @@ -19,13 +21,13 @@ pub struct MembershipWitness { unconstrained fn get_membership_witness_oracle( _block_number: u32, _tree_id: Field, - _leaf_value: Field + _leaf_value: Field, ) -> [Field; M] {} pub unconstrained fn get_membership_witness( block_number: u32, tree_id: Field, - leaf_value: Field + leaf_value: Field, ) -> MembershipWitness { let fields: [Field; M] = get_membership_witness_oracle(block_number, tree_id, leaf_value); MembershipWitness { index: fields[0], path: arr_copy_slice(fields, [0; N], 1) } @@ -35,7 +37,7 @@ pub unconstrained fn get_membership_witness( pub unconstrained fn get_note_hash_membership_witness( block_number: u32, - leaf_value: Field + leaf_value: Field, ) -> MembershipWitness { get_membership_witness(block_number, NOTE_HASH_TREE_ID, leaf_value) } @@ -45,7 +47,7 @@ pub unconstrained fn get_note_hash_membership_witness( pub unconstrained fn get_archive_membership_witness( block_number: u32, - leaf_value: Field + leaf_value: Field, ) -> MembershipWitness { get_membership_witness(block_number, ARCHIVE_TREE_ID, leaf_value) } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr index c63db464eb2..3bf863ebee9 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_nullifier_membership_witness.nr @@ -1,6 +1,6 @@ use dep::protocol_types::{ abis::nullifier_leaf_preimage::{NullifierLeafPreimage, NULLIFIER_LEAF_PREIMAGE_LENGTH}, - constants::NULLIFIER_TREE_HEIGHT, utils::arr_copy_slice + constants::NULLIFIER_TREE_HEIGHT, utils::arr_copy_slice, }; // INDEX_LENGTH + NULLIFIER_LEAF_PREIMAGE_LENGTH + NULLIFIER_TREE_HEIGHT @@ -21,8 +21,8 @@ impl NullifierMembershipWitness { path: arr_copy_slice( fields, [0; NULLIFIER_TREE_HEIGHT], - 1 + NULLIFIER_LEAF_PREIMAGE_LENGTH - ) + 1 + NULLIFIER_LEAF_PREIMAGE_LENGTH, + ), } } } @@ -30,12 +30,15 @@ impl NullifierMembershipWitness { #[oracle(getLowNullifierMembershipWitness)] unconstrained fn get_low_nullifier_membership_witness_oracle( _block_number: u32, - _nullifier: Field + _nullifier: Field, ) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {} // Nullifier here refers to the nullifier we are looking to get non-inclusion proof for (by proving that a lower // nullifier's next_value is bigger than the nullifier) -pub unconstrained fn get_low_nullifier_membership_witness(block_number: u32, nullifier: Field) -> NullifierMembershipWitness { +pub unconstrained fn get_low_nullifier_membership_witness( + block_number: u32, + nullifier: Field, +) -> NullifierMembershipWitness { let fields = get_low_nullifier_membership_witness_oracle(block_number, nullifier); NullifierMembershipWitness::deserialize(fields) } @@ -43,12 +46,15 @@ pub unconstrained fn get_low_nullifier_membership_witness(block_number: u32, nul #[oracle(getNullifierMembershipWitness)] unconstrained fn get_nullifier_membership_witness_oracle( _block_number: u32, - _nullifier: Field + _nullifier: Field, ) -> [Field; NULLIFIER_MEMBERSHIP_WITNESS] {} // Nullifier here refers to the nullifier we are looking to get non-inclusion proof for (by proving that a lower // nullifier's next_value is bigger than the nullifier) -pub unconstrained fn get_nullifier_membership_witness(block_number: u32, nullifier: Field) -> NullifierMembershipWitness { +pub unconstrained fn get_nullifier_membership_witness( + block_number: u32, + nullifier: Field, +) -> NullifierMembershipWitness { let fields = get_nullifier_membership_witness_oracle(block_number, nullifier); NullifierMembershipWitness::deserialize(fields) } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_public_data_witness.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_public_data_witness.nr index 6fde781574b..f37a79a3875 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_public_data_witness.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_public_data_witness.nr @@ -1,4 +1,6 @@ -use dep::protocol_types::{constants::PUBLIC_DATA_TREE_HEIGHT, data::PublicDataTreeLeafPreimage, utils::arr_copy_slice}; +use dep::protocol_types::{ + constants::PUBLIC_DATA_TREE_HEIGHT, data::PublicDataTreeLeafPreimage, utils::arr_copy_slice, +}; global LEAF_PREIMAGE_LENGTH: u32 = 4; global PUBLIC_DATA_WITNESS: u32 = 45; @@ -12,17 +14,26 @@ pub struct PublicDataWitness { #[oracle(getPublicDataTreeWitness)] unconstrained fn get_public_data_witness_oracle( _block_number: u32, - _public_data_tree_index: Field + _public_data_tree_index: Field, ) -> [Field; PUBLIC_DATA_WITNESS] {} pub unconstrained fn get_public_data_witness( block_number: u32, - public_data_tree_index: Field + public_data_tree_index: Field, ) -> PublicDataWitness { let fields = get_public_data_witness_oracle(block_number, public_data_tree_index); PublicDataWitness { index: fields[0], - leaf_preimage: PublicDataTreeLeafPreimage { slot: fields[1], value: fields[2], next_index: fields[3] as u32, next_slot: fields[4] }, - path: arr_copy_slice(fields, [0; PUBLIC_DATA_TREE_HEIGHT], 1 + LEAF_PREIMAGE_LENGTH) + leaf_preimage: PublicDataTreeLeafPreimage { + slot: fields[1], + value: fields[2], + next_index: fields[3] as u32, + next_slot: fields[4], + }, + path: arr_copy_slice( + fields, + [0; PUBLIC_DATA_TREE_HEIGHT], + 1 + LEAF_PREIMAGE_LENGTH, + ), } } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/get_sibling_path.nr b/noir-projects/aztec-nr/aztec/src/oracle/get_sibling_path.nr index 252fbc06cd2..6e8edfaa305 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/get_sibling_path.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/get_sibling_path.nr @@ -2,10 +2,14 @@ unconstrained fn get_sibling_path_oracle( _block_number: u32, _tree_id: Field, - _leaf_index: Field + _leaf_index: Field, ) -> [Field; N] {} -pub unconstrained fn get_sibling_path(block_number: u32, tree_id: Field, leaf_index: Field) -> [Field; N] { +pub unconstrained fn get_sibling_path( + block_number: u32, + tree_id: Field, + leaf_index: Field, +) -> [Field; N] { let value: [Field; N] = get_sibling_path_oracle(block_number, tree_id, leaf_index); value } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/header.nr b/noir-projects/aztec-nr/aztec/src/oracle/header.nr index 3b4ccb2ceff..b093494e4a1 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/header.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/header.nr @@ -1,7 +1,9 @@ use dep::protocol_types::merkle_tree::root::root_from_sibling_path; use dep::protocol_types::{constants::HEADER_LENGTH, header::Header}; -use crate::{context::PrivateContext, oracle::get_membership_witness::get_archive_membership_witness}; +use crate::{ + context::PrivateContext, oracle::get_membership_witness::get_archive_membership_witness, +}; use crate::test::helpers::test_environment::TestEnvironment; @@ -30,13 +32,12 @@ pub fn get_header_at(block_number: u32, context: PrivateContext) -> Header { // We could not perform the proof otherwise because the last archive root from the header would not "contain" // the header we want to prove against assert( - last_archive_block_number >= block_number, "Last archive block number is smaller than the block number we want to prove against" + last_archive_block_number >= block_number, + "Last archive block number is smaller than the block number we want to prove against", ); // 3) Get the header hint of a given block from an oracle - let historical = unsafe { - get_header_at_internal(block_number) - }; + let historical = unsafe { get_header_at_internal(block_number) }; // 4) We make sure that the header hint we received from the oracle exists in the state tree and is the actual header // at the desired block number @@ -44,7 +45,7 @@ pub fn get_header_at(block_number: u32, context: PrivateContext) -> Header { historical, block_number, last_archive_block_number, - header.last_archive.root + header.last_archive.root, ); // 5) Return the block header @@ -56,24 +57,24 @@ fn constrain_get_header_at_internal( header_hint: Header, block_number: u32, last_archive_block_number: u32, - last_archive_root: Field + last_archive_root: Field, ) { // 1) Compute the block hash from the block header let block_hash = header_hint.hash(); // 2) Get the membership witness of the block in the archive tree - let witness = unsafe { - get_archive_membership_witness(last_archive_block_number, block_hash) - }; + let witness = unsafe { get_archive_membership_witness(last_archive_block_number, block_hash) }; // 3) Check that the block is in the archive (i.e. the witness is valid) assert( - last_archive_root == root_from_sibling_path(block_hash, witness.index, witness.path), "Proving membership of a block in archive failed" + last_archive_root == root_from_sibling_path(block_hash, witness.index, witness.path), + "Proving membership of a block in archive failed", ); // 4) Check that the header hint has the same block number as the block number we are looking for, ensuring we are actually grabbing the header we specify assert( - header_hint.global_variables.block_number as u32 == block_number, "Block number provided is not the same as the block number from the header hint" + header_hint.global_variables.block_number as u32 == block_number, + "Block number provided is not the same as the block number from the header hint", ); } @@ -94,6 +95,6 @@ unconstrained fn fetching_a_valid_but_different_header_should_fail() { bad_header, 2, current_header.global_variables.block_number as u32 - 1, - current_header.last_archive.root + current_header.last_archive.root, ); } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/key_validation_request.nr b/noir-projects/aztec-nr/aztec/src/oracle/key_validation_request.nr index 8db93e173b0..6a779675fc4 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/key_validation_request.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/key_validation_request.nr @@ -1,14 +1,16 @@ -use dep::protocol_types::abis::validation_requests::{KeyValidationRequest, key_validation_request::KEY_VALIDATION_REQUEST_LENGTH}; +use dep::protocol_types::abis::validation_requests::{ + KeyValidationRequest, key_validation_request::KEY_VALIDATION_REQUEST_LENGTH, +}; #[oracle(getKeyValidationRequest)] unconstrained fn get_key_validation_request_oracle( _pk_m_hash: Field, - _key_index: Field + _key_index: Field, ) -> [Field; KEY_VALIDATION_REQUEST_LENGTH] {} unconstrained fn get_key_validation_request_internal( npk_m_hash: Field, - key_index: Field + key_index: Field, ) -> KeyValidationRequest { let result = get_key_validation_request_oracle(npk_m_hash, key_index); KeyValidationRequest::deserialize(result) @@ -16,7 +18,7 @@ unconstrained fn get_key_validation_request_internal( pub unconstrained fn get_key_validation_request( pk_m_hash: Field, - key_index: Field + key_index: Field, ) -> KeyValidationRequest { get_key_validation_request_internal(pk_m_hash, key_index) } diff --git a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr index 434635d40c8..7c6bb4a317f 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/keys.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/keys.nr @@ -1,19 +1,27 @@ use dep::protocol_types::{ address::{AztecAddress, PartialAddress}, public_keys::{PublicKeys, NpkM, IvpkM, OvpkM, TpkM}, - point::Point + point::Point, }; #[oracle(getPublicKeysAndPartialAddress)] unconstrained fn get_public_keys_and_partial_address_oracle(_address: AztecAddress) -> [Field; 13] {} -pub unconstrained fn get_public_keys_and_partial_address(address: AztecAddress) -> (PublicKeys, PartialAddress) { +pub unconstrained fn get_public_keys_and_partial_address( + address: AztecAddress, +) -> (PublicKeys, PartialAddress) { let result = get_public_keys_and_partial_address_oracle(address); let keys = PublicKeys { npk_m: NpkM { inner: Point { x: result[0], y: result[1], is_infinite: result[2] as bool } }, - ivpk_m: IvpkM { inner: Point { x: result[3], y: result[4], is_infinite: result[5] as bool } }, - ovpk_m: OvpkM { inner: Point { x: result[6], y: result[7], is_infinite: result[8] as bool } }, - tpk_m: TpkM { inner: Point { x: result[9], y: result[10], is_infinite: result[11] as bool } } + ivpk_m: IvpkM { + inner: Point { x: result[3], y: result[4], is_infinite: result[5] as bool }, + }, + ovpk_m: OvpkM { + inner: Point { x: result[6], y: result[7], is_infinite: result[8] as bool }, + }, + tpk_m: TpkM { + inner: Point { x: result[9], y: result[10], is_infinite: result[11] as bool }, + }, }; let partial_address = PartialAddress::from_field(result[12]); diff --git a/noir-projects/aztec-nr/aztec/src/oracle/logs.nr b/noir-projects/aztec-nr/aztec/src/oracle/logs.nr index 462a57d2f1a..85e54210bf4 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/logs.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/logs.nr @@ -2,7 +2,11 @@ use dep::protocol_types::address::AztecAddress; /// Informs the simulator that an encrypted note log has been emitted, helping it keep track of side-effects and easing /// debugging. -pub fn emit_encrypted_note_log(note_hash_counter: u32, encrypted_note: [u8; M], counter: u32) { +pub fn emit_encrypted_note_log( + note_hash_counter: u32, + encrypted_note: [u8; M], + counter: u32, +) { // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. unsafe { emit_encrypted_note_log_oracle_wrapper(note_hash_counter, encrypted_note, counter) @@ -11,10 +15,20 @@ pub fn emit_encrypted_note_log(note_hash_counter: u32, encrypted_not /// Informs the simulator that an encrypted event log has been emitted, helping it keep track of side-effects and easing /// debugging. -pub fn emit_encrypted_event_log(contract_address: AztecAddress, randomness: Field, encrypted_event: [u8; M], counter: u32) { +pub fn emit_encrypted_event_log( + contract_address: AztecAddress, + randomness: Field, + encrypted_event: [u8; M], + counter: u32, +) { // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. unsafe { - emit_encrypted_event_log_oracle_wrapper(contract_address, randomness, encrypted_event, counter) + emit_encrypted_event_log_oracle_wrapper( + contract_address, + randomness, + encrypted_event, + counter, + ) } } @@ -27,7 +41,11 @@ pub fn emit_unencrypted_log_private(contract_address: AztecAddress, message: } } -unconstrained fn emit_encrypted_note_log_oracle_wrapper(note_hash_counter: u32, encrypted_note: [u8; M], counter: u32) { +unconstrained fn emit_encrypted_note_log_oracle_wrapper( + note_hash_counter: u32, + encrypted_note: [u8; M], + counter: u32, +) { emit_encrypted_note_log_oracle(note_hash_counter, encrypted_note, counter) } @@ -35,12 +53,16 @@ unconstrained fn emit_encrypted_event_log_oracle_wrapper( contract_address: AztecAddress, randomness: Field, encrypted_event: [u8; M], - counter: u32 + counter: u32, ) { emit_encrypted_event_log_oracle(contract_address, randomness, encrypted_event, counter) } -unconstrained fn emit_unencrypted_log_private_oracle_wrapper(contract_address: AztecAddress, message: T, counter: u32) { +unconstrained fn emit_unencrypted_log_private_oracle_wrapper( + contract_address: AztecAddress, + message: T, + counter: u32, +) { let _ = emit_unencrypted_log_private_oracle(contract_address, message, counter); } @@ -49,7 +71,7 @@ unconstrained fn emit_unencrypted_log_private_oracle_wrapper(contract_address pub unconstrained fn emit_contract_class_unencrypted_log_private( contract_address: AztecAddress, message: [Field; N], - counter: u32 + counter: u32, ) -> Field { emit_contract_class_unencrypted_log_private_oracle(contract_address, message, counter) } @@ -59,7 +81,7 @@ pub unconstrained fn emit_contract_class_unencrypted_log_private( unconstrained fn emit_encrypted_note_log_oracle( _note_hash_counter: u32, _encrypted_note: [u8; M], - _counter: u32 + _counter: u32, ) {} #[oracle(emitEncryptedEventLog)] @@ -67,19 +89,19 @@ unconstrained fn emit_encrypted_event_log_oracle( _contract_address: AztecAddress, _randomness: Field, _encrypted_event: [u8; M], - _counter: u32 + _counter: u32, ) {} #[oracle(emitUnencryptedLog)] unconstrained fn emit_unencrypted_log_private_oracle( _contract_address: AztecAddress, _message: T, - _counter: u32 + _counter: u32, ) -> Field {} #[oracle(emitContractClassUnencryptedLog)] unconstrained fn emit_contract_class_unencrypted_log_private_oracle( contract_address: AztecAddress, message: [Field; N], - counter: u32 + counter: u32, ) -> Field {} diff --git a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr index c34f14463ce..90c3dcad862 100644 --- a/noir-projects/aztec-nr/aztec/src/oracle/notes.nr +++ b/noir-projects/aztec-nr/aztec/src/oracle/notes.nr @@ -9,11 +9,17 @@ pub fn notify_created_note( note_type_id: Field, serialized_note: [Field; N], note_hash: Field, - counter: u32 + counter: u32, ) { // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. unsafe { - notify_created_note_oracle_wrapper(storage_slot, note_type_id, serialized_note, note_hash, counter) + notify_created_note_oracle_wrapper( + storage_slot, + note_type_id, + serialized_note, + note_hash, + counter, + ) }; } @@ -22,9 +28,7 @@ pub fn notify_created_note( /// actual block. pub fn notify_nullified_note(nullifier: Field, note_hash: Field, counter: u32) { // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. - unsafe { - notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) - }; + unsafe { notify_nullified_note_oracle_wrapper(nullifier, note_hash, counter) }; } unconstrained fn notify_created_note_oracle_wrapper( @@ -32,9 +36,15 @@ unconstrained fn notify_created_note_oracle_wrapper( note_type_id: Field, serialized_note: [Field; N], note_hash: Field, - counter: u32 + counter: u32, ) { - let _ = notify_created_note_oracle(storage_slot, note_type_id, serialized_note, note_hash, counter); + let _ = notify_created_note_oracle( + storage_slot, + note_type_id, + serialized_note, + note_hash, + counter, + ); } #[oracle(notifyCreatedNote)] @@ -43,19 +53,23 @@ unconstrained fn notify_created_note_oracle( _note_type_id: Field, _serialized_note: [Field; N], _note_hash: Field, - _counter: u32 + _counter: u32, ) -> Field {} unconstrained fn notify_nullified_note_oracle_wrapper( nullifier: Field, note_hash: Field, - counter: u32 + counter: u32, ) { let _ = notify_nullified_note_oracle(nullifier, note_hash, counter); } #[oracle(notifyNullifiedNote)] -unconstrained fn notify_nullified_note_oracle(_nullifier: Field, _note_hash: Field, _counter: u32) -> Field {} +unconstrained fn notify_nullified_note_oracle( + _nullifier: Field, + _note_hash: Field, + _counter: u32, +) -> Field {} #[oracle(getNotes)] unconstrained fn get_notes_oracle( @@ -74,7 +88,7 @@ unconstrained fn get_notes_oracle( _offset: u32, _status: u8, _return_size: u32, - _placeholder_fields: [Field; S] + _placeholder_fields: [Field; S], ) -> [Field; S] {} unconstrained fn get_notes_oracle_wrapper( @@ -92,7 +106,7 @@ unconstrained fn get_notes_oracle_wrapper( limit: u32, offset: u32, status: u8, - mut placeholder_fields: [Field; S] + mut placeholder_fields: [Field; S], ) -> [Field; S] { let return_size = placeholder_fields.len() as u32; get_notes_oracle( @@ -111,7 +125,7 @@ unconstrained fn get_notes_oracle_wrapper( offset, status, return_size, - placeholder_fields + placeholder_fields, ) } @@ -132,8 +146,11 @@ pub unconstrained fn get_notes; S], // TODO: Remove it and use `limit` to initialize the note array. placeholder_fields: [Field; NS], // TODO: Remove it and use `limit` to initialize the note array. - _placeholder_note_length: [Field; N] // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter -) -> [Option; S] where Note: NoteInterface { + _placeholder_note_length: [Field; N], // Turbofish hack? Compiler breaks calculating read_offset unless we add this parameter +) -> [Option; S] +where + Note: NoteInterface, +{ let fields = get_notes_oracle_wrapper( storage_slot, num_selects, @@ -149,7 +166,7 @@ pub unconstrained fn get_notes(address: Field, storage_slot: Field, block_number: Field, length: Field) -> [Field; N] {} +unconstrained fn storage_read_oracle( + address: Field, + storage_slot: Field, + block_number: Field, + length: Field, +) -> [Field; N] {} pub unconstrained fn raw_storage_read( address: AztecAddress, storage_slot: Field, - block_number: u32 + block_number: u32, ) -> [Field; N] { storage_read_oracle( address.to_field(), storage_slot, block_number as Field, - N as Field + N as Field, ) } pub unconstrained fn storage_read( address: AztecAddress, storage_slot: Field, - block_number: u32 -) -> T where T: Deserialize { + block_number: u32, +) -> T +where + T: Deserialize, +{ T::deserialize(raw_storage_read(address, storage_slot, block_number)) } diff --git a/noir-projects/aztec-nr/aztec/src/prelude.nr b/noir-projects/aztec-nr/aztec/src/prelude.nr index 793550c5668..f3ba3ffbb9c 100644 --- a/noir-projects/aztec-nr/aztec/src/prelude.nr +++ b/noir-projects/aztec-nr/aztec/src/prelude.nr @@ -1,19 +1,18 @@ // docs:start:prelude pub use dep::protocol_types::{ address::{AztecAddress, EthAddress}, abis::function_selector::FunctionSelector, point::Point, - traits::{Serialize, Deserialize} + traits::{Serialize, Deserialize}, }; pub use crate::{ state_vars::{ - map::Map, private_immutable::PrivateImmutable, private_mutable::PrivateMutable, - public_immutable::PublicImmutable, public_mutable::PublicMutable, private_set::PrivateSet, - shared_immutable::SharedImmutable, shared_mutable::SharedMutable, storage::Storable -}, - context::{PrivateContext, PackedReturns, FunctionReturns}, + map::Map, private_immutable::PrivateImmutable, private_mutable::PrivateMutable, + public_immutable::PublicImmutable, public_mutable::PublicMutable, private_set::PrivateSet, + shared_immutable::SharedImmutable, shared_mutable::SharedMutable, storage::Storable, + }, context::{PrivateContext, PackedReturns, FunctionReturns}, note::{ - note_header::NoteHeader, note_interface::{NoteInterface, NullifiableNote}, - note_getter_options::NoteGetterOptions, note_viewer_options::NoteViewerOptions, - utils::compute_note_hash_and_optionally_a_nullifier as utils_compute_note_hash_and_optionally_a_nullifier -} + note_header::NoteHeader, note_interface::{NoteInterface, NullifiableNote}, + note_getter_options::NoteGetterOptions, note_viewer_options::NoteViewerOptions, + utils::compute_note_hash_and_optionally_a_nullifier as utils_compute_note_hash_and_optionally_a_nullifier, + }, }; // docs:end:prelude diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/map.nr b/noir-projects/aztec-nr/aztec/src/state_vars/map.nr index e4db34b7c18..ddb88ac8038 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/map.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/map.nr @@ -16,7 +16,7 @@ impl Map { pub fn new( context: Context, storage_slot: Field, - state_var_constructor: fn(Context, Field) -> V + state_var_constructor: fn(Context, Field) -> V, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Map { context, storage_slot, state_var_constructor } @@ -24,7 +24,10 @@ impl Map { // docs:end:new // docs:start:at - pub fn at(self, key: K) -> V where K: ToField { + pub fn at(self, key: K) -> V + where + K: ToField, + { // TODO(#1204): use a generator index for the storage slot let derived_storage_slot = derive_storage_slot_in_map(self.storage_slot, key); diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr index 7f626fc8f00..4f6ff618fae 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_immutable.nr @@ -1,10 +1,12 @@ -use dep::protocol_types::{constants::GENERATOR_INDEX__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator}; +use dep::protocol_types::{ + constants::GENERATOR_INDEX__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, +}; use crate::context::{PrivateContext, UnconstrainedContext}; use crate::note::{ lifecycle::create_note, note_getter::{get_note, view_notes}, note_interface::{NoteInterface, NullifiableNote}, note_viewer_options::NoteViewerOptions, - note_emission::NoteEmission + note_emission::NoteEmission, }; use crate::oracle::notes::check_nullifier_exists; use crate::state_vars::storage::Storage; @@ -35,17 +37,17 @@ impl PrivateImmutable { pub fn compute_initialization_nullifier(self) -> Field { poseidon2_hash_with_separator( [self.storage_slot], - GENERATOR_INDEX__INITIALIZATION_NULLIFIER + GENERATOR_INDEX__INITIALIZATION_NULLIFIER, ) } } impl PrivateImmutable { // docs:start:initialize - pub fn initialize( - self, - note: &mut Note - ) -> NoteEmission where Note: NoteInterface + NullifiableNote { + pub fn initialize(self, note: &mut Note) -> NoteEmission + where + Note: NoteInterface + NullifiableNote, + { // Nullify the storage slot. let nullifier = self.compute_initialization_nullifier(); self.context.push_nullifier(nullifier); @@ -55,7 +57,10 @@ impl PrivateImmutable { // docs:end:initialize // docs:start:get_note - pub fn get_note(self) -> Note where Note: NoteInterface + NullifiableNote { + pub fn get_note(self) -> Note + where + Note: NoteInterface + NullifiableNote, + { let storage_slot = self.storage_slot; get_note(self.context, storage_slot).0 } @@ -72,7 +77,10 @@ impl PrivateImmutable { // view_note does not actually use the context, but it calls oracles that are only available in private // docs:start:view_note - pub unconstrained fn view_note(self) -> Note where Note: NoteInterface + NullifiableNote { + pub unconstrained fn view_note(self) -> Note + where + Note: NoteInterface + NullifiableNote, + { let mut options = NoteViewerOptions::new(); view_notes(self.storage_slot, options.set_limit(1)).get(0) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr index f3a75cba580..29cc9c6b88b 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable.nr @@ -1,10 +1,12 @@ -use dep::protocol_types::{constants::GENERATOR_INDEX__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator}; +use dep::protocol_types::{ + constants::GENERATOR_INDEX__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, +}; use crate::context::{PrivateContext, UnconstrainedContext}; use crate::note::{ lifecycle::{create_note, destroy_note_unsafe}, note_getter::{get_note, view_notes}, note_interface::{NoteInterface, NullifiableNote}, note_viewer_options::NoteViewerOptions, - note_emission::NoteEmission + note_emission::NoteEmission, }; use crate::oracle::notes::check_nullifier_exists; use crate::state_vars::storage::Storage; @@ -12,7 +14,7 @@ use crate::state_vars::storage::Storage; // docs:start:struct pub struct PrivateMutable { context: Context, - storage_slot: Field + storage_slot: Field, } // docs:end:struct @@ -39,12 +41,15 @@ impl PrivateMutable { pub fn compute_initialization_nullifier(self) -> Field { poseidon2_hash_with_separator( [self.storage_slot], - GENERATOR_INDEX__INITIALIZATION_NULLIFIER + GENERATOR_INDEX__INITIALIZATION_NULLIFIER, ) } } -impl PrivateMutable where Note: NoteInterface + NullifiableNote { +impl PrivateMutable +where + Note: NoteInterface + NullifiableNote, +{ // docs:start:initialize pub fn initialize(self, note: &mut Note) -> NoteEmission { // Nullify the storage slot. @@ -57,7 +62,8 @@ impl PrivateMutable where Note: Not // docs:start:replace pub fn replace(self, new_note: &mut Note) -> NoteEmission { - let (prev_note, note_hash_for_read_request): (Note, Field) = get_note(self.context, self.storage_slot); + let (prev_note, note_hash_for_read_request): (Note, Field) = + get_note(self.context, self.storage_slot); // Nullify previous note. destroy_note_unsafe(self.context, prev_note, note_hash_for_read_request); @@ -78,9 +84,8 @@ impl PrivateMutable where Note: Not // an inclusion proof for the current note // This means that an honest oracle will assist the prover to produce a valid proof, while a malicious oracle // (i.e. one that returns an incorrect value for is_initialized) will simply fail to produce a proof. - let is_initialized = unsafe { - check_nullifier_exists(self.compute_initialization_nullifier()) - }; + let is_initialized = + unsafe { check_nullifier_exists(self.compute_initialization_nullifier()) }; if (!is_initialized) { self.initialize(note) @@ -103,7 +108,10 @@ impl PrivateMutable where Note: Not // docs:end:get_note } -impl PrivateMutable where Note: NoteInterface + NullifiableNote { +impl PrivateMutable +where + Note: NoteInterface + NullifiableNote, +{ pub unconstrained fn is_initialized(self) -> bool { let nullifier = self.compute_initialization_nullifier(); check_nullifier_exists(nullifier) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable/test.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable/test.nr index 1fd7f08ed84..4d72ba7ac33 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable/test.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_mutable/test.nr @@ -1,8 +1,8 @@ use crate::{ context::PrivateContext, state_vars::private_mutable::PrivateMutable, - oracle::execution::get_contract_address + oracle::execution::get_contract_address, }; -use crate::test::{mocks::mock_note::MockNote, helpers::{test_environment::TestEnvironment}}; +use crate::test::{mocks::mock_note::MockNote, helpers::test_environment::TestEnvironment}; use std::test::OracleMock; global storage_slot = 17; @@ -14,7 +14,9 @@ unconstrained fn setup() -> TestEnvironment { env } -unconstrained fn in_private(env: &mut TestEnvironment) -> PrivateMutable { +unconstrained fn in_private( + env: &mut TestEnvironment, +) -> PrivateMutable { let state_var = PrivateMutable::new(&mut env.private(), storage_slot); // This oracle is called for its side effects alone - it's always expected to return 0. @@ -29,7 +31,10 @@ unconstrained fn test_initialize_or_replace_without_nullifier() { let state_var = in_private(&mut env); let value = 42; - let mut note = MockNote::new(value).contract_address(get_contract_address()).storage_slot(storage_slot).build(); + let mut note = MockNote::new(value) + .contract_address(get_contract_address()) + .storage_slot(storage_slot) + .build(); let _ = OracleMock::mock("checkNullifierExists").returns(0); state_var.initialize_or_replace(&mut note).discard(); diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr b/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr index f8b78647137..da2d4926411 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr @@ -1,11 +1,13 @@ -use dep::protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, abis::read_request::ReadRequest}; +use dep::protocol_types::{ + constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, abis::read_request::ReadRequest, +}; use crate::context::{PrivateContext, PublicContext, UnconstrainedContext}; use crate::note::{ constants::MAX_NOTES_PER_PAGE, lifecycle::{create_note, create_note_hash_from_public, destroy_note_unsafe}, note_getter::{get_notes, view_notes}, note_getter_options::NoteGetterOptions, note_interface::{NoteInterface, NullifiableNote}, note_viewer_options::NoteViewerOptions, - utils::compute_note_hash_for_read_request, note_emission::NoteEmission + utils::compute_note_hash_for_read_request, note_emission::NoteEmission, }; use crate::state_vars::storage::Storage; @@ -27,7 +29,10 @@ impl PrivateSet { // docs:end:new } -impl PrivateSet where Note: NoteInterface + NullifiableNote { +impl PrivateSet +where + Note: NoteInterface + NullifiableNote, +{ // docs:start:insert_from_public pub fn insert_from_public(self, note: &mut Note) { create_note_hash_from_public(self.context, self.storage_slot, note); @@ -35,7 +40,10 @@ impl PrivateSet where Note: NoteInte // docs:end:insert_from_public } -impl PrivateSet where Note: NoteInterface + NullifiableNote + Eq { +impl PrivateSet +where + Note: NoteInterface + NullifiableNote + Eq, +{ // docs:start:insert pub fn insert(self, note: &mut Note) -> NoteEmission { create_note(self.context, self.storage_slot, note) @@ -44,7 +52,7 @@ impl PrivateSet where Note: NoteInt pub fn pop_notes( self, - options: NoteGetterOptions + options: NoteGetterOptions, ) -> BoundedVec { let (notes, note_hashes) = get_notes(self.context, self.storage_slot, options); // We iterate in a range 0..options.limit instead of 0..notes.len() because options.limit is known at compile @@ -67,7 +75,8 @@ impl PrivateSet where Note: NoteInt /// in significantly less constrains due to avoiding an extra hash and read request check. pub fn remove(self, note: Note) { let note_hash = compute_note_hash_for_read_request(note); - let has_been_read = self.context.note_hash_read_requests.any(|r: ReadRequest| r.value == note_hash); + let has_been_read = + self.context.note_hash_read_requests.any(|r: ReadRequest| r.value == note_hash); assert(has_been_read, "Can only remove a note that has been read from the set."); destroy_note_unsafe(self.context, note, note_hash); @@ -77,17 +86,20 @@ impl PrivateSet where Note: NoteInt /// in significantly less constrains due to avoiding 1 read request check. pub fn get_notes( self, - options: NoteGetterOptions + options: NoteGetterOptions, ) -> BoundedVec { get_notes(self.context, self.storage_slot, options).0 } } -impl PrivateSet where Note: NoteInterface + NullifiableNote { +impl PrivateSet +where + Note: NoteInterface + NullifiableNote, +{ // docs:start:view_notes pub unconstrained fn view_notes( self, - options: NoteViewerOptions + options: NoteViewerOptions, ) -> BoundedVec { view_notes(self.storage_slot, options) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr index 3446d4b78f5..4fac882d8a9 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -1,5 +1,7 @@ use crate::{context::{PublicContext, UnconstrainedContext}, state_vars::storage::Storage}; -use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::{Deserialize, Serialize}}; +use dep::protocol_types::{ + constants::INITIALIZATION_SLOT_SEPARATOR, traits::{Deserialize, Serialize}, +}; // Just like SharedImmutable but without the ability to read from private functions. // docs:start:public_immutable_struct @@ -16,7 +18,7 @@ impl PublicImmutable { pub fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. context: Context, - storage_slot: Field + storage_slot: Field, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); PublicImmutable { context, storage_slot } @@ -24,7 +26,10 @@ impl PublicImmutable { // docs:end:public_immutable_struct_new } -impl PublicImmutable where T: Serialize + Deserialize { +impl PublicImmutable +where + T: Serialize + Deserialize, +{ // docs:start:public_immutable_struct_write pub fn initialize(self, value: T) { // We check that the struct is not yet initialized by checking if the initialization slot is 0 @@ -46,7 +51,10 @@ impl PublicImmutable where // docs:end:public_immutable_struct_read } -impl PublicImmutablewhere T: Deserialize { +impl PublicImmutable +where + T: Deserialize, +{ pub unconstrained fn read(self) -> T { self.context.storage_read(self.storage_slot) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr index d89a65567b9..a1472db195d 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/public_mutable.nr @@ -16,7 +16,7 @@ impl PublicMutable { pub fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. context: Context, - storage_slot: Field + storage_slot: Field, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); PublicMutable { context, storage_slot } @@ -24,7 +24,10 @@ impl PublicMutable { // docs:end:public_mutable_struct_new } -impl PublicMutable where T: Serialize + Deserialize { +impl PublicMutable +where + T: Serialize + Deserialize, +{ // docs:start:public_mutable_struct_read pub fn read(self) -> T { self.context.storage_read(self.storage_slot) @@ -38,7 +41,10 @@ impl PublicMutable where T: // docs:end:public_mutable_struct_write } -impl PublicMutable where T: Deserialize { +impl PublicMutable +where + T: Deserialize, +{ pub unconstrained fn read(self) -> T { self.context.storage_read(self.storage_slot) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr index 447ed264913..8c6f3ecb9ab 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_immutable.nr @@ -1,8 +1,12 @@ -use crate::{context::{PrivateContext, PublicContext, UnconstrainedContext}, state_vars::storage::Storage}; -use dep::protocol_types::{constants::INITIALIZATION_SLOT_SEPARATOR, traits::{Deserialize, Serialize}}; +use crate::{ + context::{PrivateContext, PublicContext, UnconstrainedContext}, state_vars::storage::Storage, +}; +use dep::protocol_types::{ + constants::INITIALIZATION_SLOT_SEPARATOR, traits::{Deserialize, Serialize}, +}; // Just like PublicImmutable but with the ability to read from private functions. -pub struct SharedImmutable{ +pub struct SharedImmutable { context: Context, storage_slot: Field, } @@ -13,14 +17,17 @@ impl SharedImmutable { pub fn new( // Note: Passing the contexts to new(...) just to have an interface compatible with a Map. context: Context, - storage_slot: Field + storage_slot: Field, ) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { context, storage_slot } } } -impl SharedImmutable where T: Serialize + Deserialize { +impl SharedImmutable +where + T: Serialize + Deserialize, +{ // Intended to be only called once. pub fn initialize(self, value: T) { // We check that the struct is not yet initialized by checking if the initialization slot is 0 @@ -38,23 +45,28 @@ impl SharedImmutable where } } -impl SharedImmutable where T: Serialize + Deserialize { +impl SharedImmutable +where + T: Serialize + Deserialize, +{ pub unconstrained fn read_public(self) -> T { self.context.storage_read(self.storage_slot) } } -impl SharedImmutable where T: Serialize + Deserialize { +impl SharedImmutable +where + T: Serialize + Deserialize, +{ pub fn read_private(self) -> T { let header = self.context.get_header(); let mut fields = [0; T_SERIALIZED_LEN]; for i in 0..fields.len() { - fields[i] = - header.public_storage_historical_read( - self.storage_slot + i as Field, - (*self.context).this_address() - ); + fields[i] = header.public_storage_historical_read( + self.storage_slot + i as Field, + (*self.context).this_address(), + ); } T::deserialize(fields) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_delay_change.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_delay_change.nr index 682a04febdd..05ce69f59df 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_delay_change.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_delay_change.nr @@ -31,7 +31,6 @@ impl ScheduledDelayChange { pub fn get_current(self, current_block_number: u32) -> u32 { // The post value becomes the current one at the block of change, so any transaction that is included in the // block of change will use the post value. - if current_block_number < self.block_of_change { self.pre.unwrap_or(INITIAL_DELAY) } else { @@ -116,12 +115,11 @@ impl ScheduledDelayChange { // |----------------------------------------------------------------| // current delay at the earliest block in // which to scheduled value change - let blocks_until_change = self.block_of_change - (historical_block_number + 1); min( self.pre.unwrap_or(INITIAL_DELAY), - blocks_until_change + self.post.unwrap_or(INITIAL_DELAY) + blocks_until_change + self.post.unwrap_or(INITIAL_DELAY), ) } } @@ -132,8 +130,8 @@ impl Serialize<1> for ScheduledDelayChange Deserialize<1> for ScheduledDelayChange Deserialize<1> for ScheduledDelayChange) { // We have to do explicit type annotations because Noir lacks turbofish support. // TODO: improve syntax once https://github.com/noir-lang/noir/issues/4710 is implemented. - let converted: ScheduledDelayChange = ScheduledDelayChange::deserialize((original).serialize()); + let converted: ScheduledDelayChange = + ScheduledDelayChange::deserialize((original).serialize()); assert_eq(original, converted); // This also tests the Eq impl assert_eq(original.pre, converted.pre); @@ -19,10 +20,26 @@ unconstrained fn test_serde() { let post = 2; let block_of_change = 50; - assert_equal_after_conversion(ScheduledDelayChange::new(Option::some(pre), Option::some(post), block_of_change)); - assert_equal_after_conversion(ScheduledDelayChange::new(Option::some(pre), Option::none(), block_of_change)); - assert_equal_after_conversion(ScheduledDelayChange::new(Option::none(), Option::some(post), block_of_change)); - assert_equal_after_conversion(ScheduledDelayChange::new(Option::none(), Option::none(), block_of_change)); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::some(pre), + Option::some(post), + block_of_change, + )); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::some(pre), + Option::none(), + block_of_change, + )); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::none(), + Option::some(post), + block_of_change, + )); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::none(), + Option::none(), + block_of_change, + )); } #[test] @@ -33,16 +50,32 @@ unconstrained fn test_serde_large_values() { let post = (max_u32 - 1) as u32; let block_of_change = (max_u32 - 2) as u32; - assert_equal_after_conversion(ScheduledDelayChange::new(Option::some(pre), Option::some(post), block_of_change)); - assert_equal_after_conversion(ScheduledDelayChange::new(Option::some(pre), Option::none(), block_of_change)); - assert_equal_after_conversion(ScheduledDelayChange::new(Option::none(), Option::some(post), block_of_change)); - assert_equal_after_conversion(ScheduledDelayChange::new(Option::none(), Option::none(), block_of_change)); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::some(pre), + Option::some(post), + block_of_change, + )); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::some(pre), + Option::none(), + block_of_change, + )); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::none(), + Option::some(post), + block_of_change, + )); + assert_equal_after_conversion(ScheduledDelayChange::new( + Option::none(), + Option::none(), + block_of_change, + )); } unconstrained fn get_non_initial_delay_change( pre: u32, post: u32, - block_of_change: u32 + block_of_change: u32, ) -> ScheduledDelayChange { ScheduledDelayChange::new(Option::some(pre), Option::some(post), block_of_change) } @@ -201,12 +234,13 @@ unconstrained fn test_schedule_change_to_longer_delay_from_initial() { unconstrained fn assert_effective_minimum_delay_invariants( delay_change: &mut ScheduledDelayChange, historical_block_number: u32, - effective_minimum_delay: u32 + effective_minimum_delay: u32, ) { // The effective minimum delays guarantees the earliest block in which a scheduled value change could be made // effective. No action, even if executed immediately after the historical block, should result in a scheduled // value change having a block of change lower than this. - let expected_earliest_value_change_block = historical_block_number + 1 + effective_minimum_delay; + let expected_earliest_value_change_block = + historical_block_number + 1 + effective_minimum_delay; if delay_change.block_of_change > historical_block_number { // If a delay change is already scheduled to happen in the future, we then must consider the scenario in @@ -219,7 +253,8 @@ unconstrained fn assert_effective_minimum_delay_invariants ScheduledValueChange { // - in public, any transaction that is included in the block of change will use the post value // - in private, any transaction that includes the block of change as part of the historical state will use the // post value (barring any follow-up changes) - if block_number < self.block_of_change { self.pre } else { @@ -62,7 +61,6 @@ impl ScheduledValueChange { // (i.e. with a block number larger than the block horizon) may have a different current value. Reading the // current value in private typically requires constraining the maximum valid block number to be equal to the // block horizon. - if historical_block_number >= self.block_of_change { // Once the block of change has been mined, the current value (post) will not change unless a new value // change is scheduled. This did not happen at the historical block number (or else it would not be @@ -77,7 +75,6 @@ impl ScheduledValueChange { // ^ ^ // --------------------- // minimum delay - historical_block_number + minimum_delay } else { // If the block of change has not yet been mined however, then there are two possible scenarios. @@ -110,12 +107,11 @@ impl ScheduledValueChange { // Note that the current implementation does not allow the caller to set the block of change to an arbitrary // value, and therefore scenario a) is not currently possible. However implementing #5501 would allow for // this to happen. - // Because historical_block_number < self.block_of_change, then block_of_change > 0 and we can safely // subtract 1. min( self.block_of_change - 1, - historical_block_number + minimum_delay + historical_block_number + minimum_delay, ) } } @@ -127,7 +123,7 @@ impl ScheduledValueChange { new_value: T, current_block_number: u32, minimum_delay: u32, - block_of_change: u32 + block_of_change: u32, ) { assert(block_of_change >= current_block_number + minimum_delay); @@ -137,23 +133,32 @@ impl ScheduledValueChange { } } -impl Serialize<3> for ScheduledValueChange where T: ToField { +impl Serialize<3> for ScheduledValueChange +where + T: ToField, +{ fn serialize(self) -> [Field; 3] { [self.pre.to_field(), self.post.to_field(), self.block_of_change.to_field()] } } -impl Deserialize<3> for ScheduledValueChange where T: FromField { +impl Deserialize<3> for ScheduledValueChange +where + T: FromField, +{ fn deserialize(input: [Field; 3]) -> Self { Self { pre: FromField::from_field(input[0]), post: FromField::from_field(input[1]), - block_of_change: FromField::from_field(input[2]) + block_of_change: FromField::from_field(input[2]), } } } -impl Eq for ScheduledValueChange where T: Eq { +impl Eq for ScheduledValueChange +where + T: Eq, +{ fn eq(self, other: Self) -> bool { (self.pre == other.pre) & (self.post == other.post) diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_value_change/test.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_value_change/test.nr index c34faa7c2a6..4677830d013 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_value_change/test.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/scheduled_value_change/test.nr @@ -23,7 +23,8 @@ unconstrained fn test_get_current_at() { let post = 2; let block_of_change = 50; - let value_change: ScheduledValueChange = ScheduledValueChange::new(pre, post, block_of_change); + let value_change: ScheduledValueChange = + ScheduledValueChange::new(pre, post, block_of_change); assert_eq(value_change.get_current_at(0), pre); assert_eq(value_change.get_current_at(block_of_change - 1), pre); @@ -37,7 +38,8 @@ unconstrained fn test_get_scheduled() { let post = 2; let block_of_change = 50; - let value_change: ScheduledValueChange = ScheduledValueChange::new(pre, post, block_of_change); + let value_change: ScheduledValueChange = + ScheduledValueChange::new(pre, post, block_of_change); assert_eq(value_change.get_scheduled(), (post, block_of_change)); } @@ -45,7 +47,7 @@ unconstrained fn test_get_scheduled() { unconstrained fn assert_block_horizon_invariants( value_change: &mut ScheduledValueChange, historical_block_number: u32, - block_horizon: u32 + block_horizon: u32, ) { // The current value should not change at the block horizon (but it might later). let current_at_historical = value_change.get_current_at(historical_block_number); @@ -54,13 +56,12 @@ unconstrained fn assert_block_horizon_invariants( // The earliest a new change could be scheduled in would be the immediate next block to the historical one. This // should result in the new block of change landing *after* the block horizon, and the current value still not // changing at the previously determined block_horizon. - let new = value_change.pre + value_change.post; // Make sure it's different to both pre and post value_change.schedule_change( new, historical_block_number + 1, TEST_DELAY, - historical_block_number + 1 + TEST_DELAY + historical_block_number + 1 + TEST_DELAY, ); assert(value_change.block_of_change > block_horizon); @@ -72,7 +73,8 @@ unconstrained fn test_get_block_horizon_change_in_past() { let historical_block_number = 100; let block_of_change = 50; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(1, 2, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(1, 2, block_of_change); let block_horizon = value_change.get_block_horizon(historical_block_number, TEST_DELAY); assert_eq(block_horizon, historical_block_number + TEST_DELAY); @@ -85,7 +87,8 @@ unconstrained fn test_get_block_horizon_change_in_immediate_past() { let historical_block_number = 100; let block_of_change = 100; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(1, 2, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(1, 2, block_of_change); let block_horizon = value_change.get_block_horizon(historical_block_number, TEST_DELAY); assert_eq(block_horizon, historical_block_number + TEST_DELAY); @@ -98,7 +101,8 @@ unconstrained fn test_get_block_horizon_change_in_near_future() { let historical_block_number = 100; let block_of_change = 120; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(1, 2, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(1, 2, block_of_change); // Note that this is the only scenario in which the block of change informs the block horizon. // This may result in privacy leaks when interacting with applications that have a scheduled change @@ -114,7 +118,8 @@ unconstrained fn test_get_block_horizon_change_in_far_future() { let historical_block_number = 100; let block_of_change = 500; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(1, 2, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(1, 2, block_of_change); let block_horizon = value_change.get_block_horizon(historical_block_number, TEST_DELAY); assert_eq(block_horizon, historical_block_number + TEST_DELAY); @@ -127,7 +132,8 @@ unconstrained fn test_get_block_horizon_n0_delay() { let historical_block_number = 100; let block_of_change = 50; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(1, 2, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(1, 2, block_of_change); let block_horizon = value_change.get_block_horizon(historical_block_number, 0); // Since the block horizon equals the historical block number, it is not possible to read the current value in @@ -141,7 +147,8 @@ unconstrained fn test_schedule_change_before_change() { let post = 2; let block_of_change = 500; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(pre, post, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(pre, post, block_of_change); let new = 42; let current_block_number = block_of_change - 50; @@ -149,7 +156,7 @@ unconstrained fn test_schedule_change_before_change() { new, current_block_number, TEST_DELAY, - current_block_number + TEST_DELAY + current_block_number + TEST_DELAY, ); // Because we re-schedule before the last scheduled change takes effect, the old `post` value is lost. @@ -164,7 +171,8 @@ unconstrained fn test_schedule_change_after_change() { let post = 2; let block_of_change = 500; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(pre, post, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(pre, post, block_of_change); let new = 42; let current_block_number = block_of_change + 50; @@ -172,7 +180,7 @@ unconstrained fn test_schedule_change_after_change() { new, current_block_number, TEST_DELAY, - current_block_number + TEST_DELAY + current_block_number + TEST_DELAY, ); assert_eq(value_change.pre, post); @@ -186,7 +194,8 @@ unconstrained fn test_schedule_change_no_delay() { let post = 2; let block_of_change = 500; - let mut value_change: ScheduledValueChange = ScheduledValueChange::new(pre, post, block_of_change); + let mut value_change: ScheduledValueChange = + ScheduledValueChange::new(pre, post, block_of_change); let new = 42; let current_block_number = block_of_change + 50; diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr index 663a4613978..b07f08e552d 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/shared_mutable.nr @@ -1,12 +1,14 @@ use dep::protocol_types::{ hash::{poseidon2_hash, poseidon2_hash_with_separator}, address::AztecAddress, - traits::{FromField, ToField}, utils::arrays::array_concat + traits::{FromField, ToField}, utils::arrays::array_concat, }; use crate::context::{PrivateContext, PublicContext, UnconstrainedContext}; use crate::state_vars::{ storage::Storage, - shared_mutable::{scheduled_value_change::ScheduledValueChange, scheduled_delay_change::ScheduledDelayChange} + shared_mutable::{ + scheduled_value_change::ScheduledValueChange, scheduled_delay_change::ScheduledDelayChange, + }, }; use crate::oracle::storage::storage_read; use dep::std::mem::zeroed; @@ -43,7 +45,10 @@ impl Storage for SharedMutable SharedMutable where T: ToField + FromField + Eq { +impl SharedMutable +where + T: ToField + FromField + Eq, +{ pub fn new(context: Context, storage_slot: Field) -> Self { assert(storage_slot != 0, "Storage slot 0 not allowed. Storage slots must start from 1."); Self { context, storage_slot } @@ -70,7 +75,10 @@ impl SharedMutable SharedMutable where T: ToField + FromField + Eq { +impl SharedMutable +where + T: ToField + FromField + Eq, +{ pub fn schedule_value_change(self, new_value: T) { let mut value_change = self.read_value_change(); @@ -126,7 +134,7 @@ impl SharedMutable, - delay_change: ScheduledDelayChange + delay_change: ScheduledDelayChange, ) { // Whenever we write to public storage, we write both the value change and delay change as well as the hash of // them both. This guarantees that the hash is always kept up to date. @@ -138,19 +146,22 @@ impl SharedMutable SharedMutable where T: ToField + FromField + Eq { +impl SharedMutable +where + T: ToField + FromField + Eq, +{ pub fn get_current_value_in_private(self) -> T { // When reading the current value in private we construct a historical state proof for the public value. // However, since this value might change, we must constrain the maximum transaction block number as this proof // will only be valid for however many blocks we can ensure the value will not change, which will depend on the // current delay and any scheduled delay changes. - - let (value_change, delay_change, historical_block_number) = self.historical_read_from_public_storage(); + let (value_change, delay_change, historical_block_number) = + self.historical_read_from_public_storage(); // We use the effective minimum delay as opposed to the current delay at the historical block as this one also // takes into consideration any scheduled delay changes. @@ -159,8 +170,10 @@ impl SharedMutable SharedMutable (ScheduledValueChange, ScheduledDelayChange, u32) { + fn historical_read_from_public_storage( + self, + ) -> (ScheduledValueChange, ScheduledDelayChange, u32) { let header = self.context.get_header(); let address = self.context.this_address(); @@ -189,16 +204,22 @@ impl SharedMutable SharedMutable, - delay_change: ScheduledDelayChange + delay_change: ScheduledDelayChange, ) -> Field { - let concatenated: [Field; 4] = array_concat(value_change.serialize(), delay_change.serialize()); + let concatenated: [Field; 4] = + array_concat(value_change.serialize(), delay_change.serialize()); poseidon2_hash(concatenated) } } -impl SharedMutable where T: ToField + FromField + Eq { +impl SharedMutable +where + T: ToField + FromField + Eq, +{ pub unconstrained fn get_current_value_in_unconstrained(self) -> T { let block_number = self.context.block_number() as u32; self.read_value_change().get_current_at(block_number) @@ -228,8 +253,11 @@ impl SharedMutable( address: AztecAddress, storage_slot: Field, - block_number: u32 -) -> (ScheduledValueChange, ScheduledDelayChange) where T: ToField + FromField + Eq { + block_number: u32, +) -> (ScheduledValueChange, ScheduledDelayChange) +where + T: ToField + FromField + Eq, +{ // This function cannot be part of the &mut PrivateContext impl because that'd mean that by passing `self` we'd also // be passing a mutable reference to an unconstrained function, which is not allowed. We therefore create a dummy // state variable here so that we can access the methods to compute storage slots. This will all be removed in the @@ -237,6 +265,7 @@ unconstrained fn get_public_storage_hints( let dummy: SharedMutable = SharedMutable::new((), storage_slot); ( - storage_read(address, dummy.get_value_change_storage_slot(), block_number), storage_read(address, dummy.get_delay_change_storage_slot(), block_number) + storage_read(address, dummy.get_value_change_storage_slot(), block_number), + storage_read(address, dummy.get_delay_change_storage_slot(), block_number), ) } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr index 41964e6190b..e3850f280c8 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/shared_mutable/test.nr @@ -1,10 +1,9 @@ use crate::{ context::{PublicContext, PrivateContext, UnconstrainedContext}, state_vars::shared_mutable::{ - shared_mutable::SharedMutable, scheduled_value_change::ScheduledValueChange, - scheduled_delay_change::ScheduledDelayChange -}, - test::helpers::test_environment::TestEnvironment + shared_mutable::SharedMutable, scheduled_value_change::ScheduledValueChange, + scheduled_delay_change::ScheduledDelayChange, + }, test::helpers::test_environment::TestEnvironment, }; use dep::std::{test::OracleMock, mem::zeroed}; @@ -21,18 +20,22 @@ unconstrained fn setup() -> TestEnvironment { TestEnvironment::new() } -unconstrained fn in_public(env: TestEnvironment) -> SharedMutable { +unconstrained fn in_public( + env: TestEnvironment, +) -> SharedMutable { SharedMutable::new(&mut env.public(), storage_slot) } unconstrained fn in_private( env: &mut TestEnvironment, - historical_block_number: u32 + historical_block_number: u32, ) -> SharedMutable { SharedMutable::new(&mut env.private_at(historical_block_number), storage_slot) } -unconstrained fn in_unconstrained(env: TestEnvironment) -> SharedMutable { +unconstrained fn in_unconstrained( + env: TestEnvironment, +) -> SharedMutable { SharedMutable::new(env.unkonstrained(), storage_slot) } @@ -175,7 +178,10 @@ unconstrained fn test_get_current_value_in_private_initial() { let state_var = in_private(&mut env, historical_block_number); assert_eq(state_var.get_current_value_in_private(), zeroed()); - assert_eq(state_var.context.max_block_number.unwrap(), historical_block_number + TEST_INITIAL_DELAY); + assert_eq( + state_var.context.max_block_number.unwrap(), + historical_block_number + TEST_INITIAL_DELAY, + ); } #[test] @@ -224,7 +230,8 @@ unconstrained fn test_get_current_value_in_private_at_change() { let private_state_var = in_private(&mut env, historical_block_number); assert_eq(private_state_var.get_current_value_in_private(), new_value); assert_eq( - private_state_var.context.max_block_number.unwrap(), historical_block_number + TEST_INITIAL_DELAY + private_state_var.context.max_block_number.unwrap(), + historical_block_number + TEST_INITIAL_DELAY, ); } @@ -241,7 +248,8 @@ unconstrained fn test_get_current_value_in_private_after_change() { let private_state_var = in_private(&mut env, historical_block_number); assert_eq(private_state_var.get_current_value_in_private(), new_value); assert_eq( - private_state_var.context.max_block_number.unwrap(), historical_block_number + TEST_INITIAL_DELAY + private_state_var.context.max_block_number.unwrap(), + historical_block_number + TEST_INITIAL_DELAY, ); } @@ -264,7 +272,10 @@ unconstrained fn test_get_current_value_in_private_with_non_initial_delay() { let private_state_var = in_private(&mut env, historical_block_number); assert_eq(private_state_var.get_current_value_in_private(), new_value); - assert_eq(private_state_var.context.max_block_number.unwrap(), historical_block_number + new_delay); + assert_eq( + private_state_var.context.max_block_number.unwrap(), + historical_block_number + new_delay, + ); } #[test(should_fail_with = "Hint values do not match hash")] @@ -277,12 +288,15 @@ unconstrained fn test_get_current_value_in_private_bad_value_hints() { let schedule_block_number = env.block_number(); let private_state_var = in_private(&mut env, schedule_block_number); - let mocked: ScheduledValueChange = ScheduledValueChange::new(0, new_value + 1, schedule_block_number); - let _ = OracleMock::mock("storageRead").with_params( - ( - env.contract_address().to_field(), private_state_var.get_value_change_storage_slot(), schedule_block_number, 3 - ) - ).returns(mocked.serialize()).times(1); + let mocked: ScheduledValueChange = + ScheduledValueChange::new(0, new_value + 1, schedule_block_number); + let _ = OracleMock::mock("storageRead") + .with_params(( + env.contract_address().to_field(), private_state_var.get_value_change_storage_slot(), + schedule_block_number, 3, + )) + .returns(mocked.serialize()) + .times(1); let _ = private_state_var.get_current_value_in_private(); } @@ -297,12 +311,15 @@ unconstrained fn test_get_current_value_in_private_bad_delay_hints() { let schedule_block_number = env.block_number(); let private_state_var = in_private(&mut env, schedule_block_number); - let mocked: ScheduledDelayChange = ScheduledDelayChange::new(Option::none(), Option::some(42), schedule_block_number); - let _ = OracleMock::mock("storageRead").with_params( - ( - env.contract_address().to_field(), private_state_var.get_delay_change_storage_slot(), schedule_block_number, 1 - ) - ).returns(mocked.serialize()).times(1); + let mocked: ScheduledDelayChange = + ScheduledDelayChange::new(Option::none(), Option::some(42), schedule_block_number); + let _ = OracleMock::mock("storageRead") + .with_params(( + env.contract_address().to_field(), private_state_var.get_delay_change_storage_slot(), + schedule_block_number, 1, + )) + .returns(mocked.serialize()) + .times(1); let _ = private_state_var.get_current_value_in_private(); } @@ -315,11 +332,13 @@ unconstrained fn test_get_current_value_in_private_bad_zero_hash_value_hints() { let state_var = in_private(&mut env, historical_block_number); let mocked: ScheduledValueChange = ScheduledValueChange::new(0, new_value, 0); - let _ = OracleMock::mock("storageRead").with_params( - ( - env.contract_address().to_field(), state_var.get_value_change_storage_slot(), historical_block_number, 3 - ) - ).returns(mocked.serialize()).times(1); + let _ = OracleMock::mock("storageRead") + .with_params(( + env.contract_address().to_field(), state_var.get_value_change_storage_slot(), + historical_block_number, 3, + )) + .returns(mocked.serialize()) + .times(1); let _ = state_var.get_current_value_in_private(); } @@ -331,12 +350,15 @@ unconstrained fn test_get_current_value_in_private_bad_zero_hash_delay_hints() { let historical_block_number = env.block_number(); let state_var = in_private(&mut env, historical_block_number); - let mocked: ScheduledDelayChange = ScheduledDelayChange::new(Option::none(), Option::some(new_delay), 0); - let _ = OracleMock::mock("storageRead").with_params( - ( - env.contract_address().to_field(), state_var.get_delay_change_storage_slot(), historical_block_number, 1 - ) - ).returns(mocked.serialize()).times(1); + let mocked: ScheduledDelayChange = + ScheduledDelayChange::new(Option::none(), Option::some(new_delay), 0); + let _ = OracleMock::mock("storageRead") + .with_params(( + env.contract_address().to_field(), state_var.get_delay_change_storage_slot(), + historical_block_number, 1, + )) + .returns(mocked.serialize()) + .times(1); let _ = state_var.get_current_value_in_private(); } diff --git a/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr b/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr index 2eec5d9c1b8..c8b7b37c229 100644 --- a/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr +++ b/noir-projects/aztec-nr/aztec/src/state_vars/storage.nr @@ -1,6 +1,9 @@ use dep::protocol_types::traits::{Deserialize, Serialize}; -pub trait Storage where T: Serialize + Deserialize { +pub trait Storage +where + T: Serialize + Deserialize, +{ fn get_storage_slot(self) -> Field { self.storage_slot } diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr index a9eef7a559b..2e7a44ada8f 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/cheatcodes.nr @@ -1,6 +1,6 @@ use dep::protocol_types::{ abis::function_selector::FunctionSelector, address::AztecAddress, public_keys::PublicKeys, - constants::CONTRACT_INSTANCE_LENGTH, contract_instance::ContractInstance + constants::CONTRACT_INSTANCE_LENGTH, contract_instance::ContractInstance, }; use crate::context::inputs::PrivateContextInputs; use crate::test::helpers::utils::TestAccount; @@ -21,7 +21,9 @@ pub unconstrained fn advance_blocks_by(blocks: u32) { oracle_advance_blocks_by(blocks); } -pub unconstrained fn get_private_context_inputs(historical_block_number: u32) -> PrivateContextInputs { +pub unconstrained fn get_private_context_inputs( + historical_block_number: u32, +) -> PrivateContextInputs { oracle_get_private_context_inputs(historical_block_number) } @@ -30,13 +32,17 @@ pub unconstrained fn deploy( name: str, initializer: str

, args: [Field], - public_keys_hash: Field + public_keys_hash: Field, ) -> ContractInstance { let instance_fields = oracle_deploy(path, name, initializer, args, public_keys_hash); ContractInstance::deserialize(instance_fields) } -pub unconstrained fn direct_storage_write(contract_address: AztecAddress, storage_slot: Field, fields: [Field; N]) { +pub unconstrained fn direct_storage_write( + contract_address: AztecAddress, + storage_slot: Field, + fields: [Field; N], +) { let _hash = direct_storage_write_oracle(contract_address, storage_slot, fields); } @@ -56,7 +62,11 @@ pub unconstrained fn add_authwit(address: AztecAddress, message_hash: Field) { orable_add_authwit(address, message_hash) } -pub unconstrained fn assert_public_call_fails(target_address: AztecAddress, function_selector: FunctionSelector, args: [Field]) { +pub unconstrained fn assert_public_call_fails( + target_address: AztecAddress, + function_selector: FunctionSelector, + args: [Field], +) { oracle_assert_public_call_fails(target_address, function_selector, args) } @@ -65,14 +75,14 @@ pub unconstrained fn assert_private_call_fails( function_selector: FunctionSelector, argsHash: Field, sideEffectsCounter: Field, - isStaticCall: bool + isStaticCall: bool, ) { oracle_assert_private_call_fails( target_address, function_selector, argsHash, sideEffectsCounter, - isStaticCall + isStaticCall, ) } @@ -89,7 +99,9 @@ unconstrained fn oracle_get_side_effects_counter() -> u32 {} unconstrained fn oracle_advance_blocks_by(blocks: u32) {} #[oracle(getPrivateContextInputs)] -unconstrained fn oracle_get_private_context_inputs(historical_block_number: u32) -> PrivateContextInputs {} +unconstrained fn oracle_get_private_context_inputs( + historical_block_number: u32, +) -> PrivateContextInputs {} #[oracle(deploy)] unconstrained fn oracle_deploy( @@ -97,14 +109,14 @@ unconstrained fn oracle_deploy( name: str, initializer: str

, args: [Field], - public_keys_hash: Field + public_keys_hash: Field, ) -> [Field; CONTRACT_INSTANCE_LENGTH] {} #[oracle(directStorageWrite)] unconstrained fn direct_storage_write_oracle( _contract_address: AztecAddress, _storage_slot: Field, - _values: [Field; N] + _values: [Field; N], ) -> [Field; N] {} #[oracle(createAccount)] @@ -123,7 +135,7 @@ unconstrained fn orable_add_authwit(address: AztecAddress, message_hash: Field) unconstrained fn oracle_assert_public_call_fails( target_address: AztecAddress, function_selector: FunctionSelector, - args: [Field] + args: [Field], ) {} #[oracle(assertPrivateCallFails)] @@ -132,5 +144,5 @@ unconstrained fn oracle_assert_private_call_fails( function_selector: FunctionSelector, argsHash: Field, sideEffectsCounter: Field, - isStaticCall: bool + isStaticCall: bool, ) {} diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr index 019ce4e469d..8755aefb94a 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/test_environment.nr @@ -1,4 +1,4 @@ -use dep::protocol_types::{abis::{function_selector::FunctionSelector}, address::AztecAddress}; +use dep::protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}; use crate::context::inputs::PrivateContextInputs; use crate::context::{packed_returns::PackedReturns, call_interfaces::CallInterface}; @@ -8,7 +8,9 @@ use crate::test::helpers::{cheatcodes, utils::Deployer}; use crate::hash::hash_args; use crate::note::{note_header::NoteHeader, note_interface::{NoteInterface, NullifiableNote}}; -use crate::oracle::{execution::{get_block_number, get_contract_address}, notes::notify_created_note}; +use crate::oracle::{ + execution::{get_block_number, get_contract_address}, notes::notify_created_note, +}; use protocol_types::constants::PUBLIC_DISPATCH_SELECTOR; pub struct TestEnvironment {} @@ -45,7 +47,7 @@ impl TestEnvironment { } unconstrained fn public_with_args_hash(_self: Self, args: [Field]) -> PublicContext { - let mut context = PublicContext::new(|| {panic(f"Provide args hash manually")}); + let mut context = PublicContext::new(|| { panic(f"Provide args hash manually") }); context.args_hash = Option::some(hash_args(args)); context } @@ -91,7 +93,7 @@ impl TestEnvironment { unconstrained fn deploy( _self: Self, path: str, - name: str + name: str, ) -> Deployer { Deployer { path, name, public_keys_hash: 0 } } @@ -100,26 +102,31 @@ impl TestEnvironment { Deployer { path: "", name, public_keys_hash: 0 } } - unconstrained fn assert_public_call_fails( - _self: Self, - call_interface: C - ) where C: CallInterface { + unconstrained fn assert_public_call_fails(_self: Self, call_interface: C) + where + C: CallInterface, + { // Public functions are routed through the dispatch function. let fn_selector = FunctionSelector::from_field(PUBLIC_DISPATCH_SELECTOR); - let calldata = &[call_interface.get_selector().to_field()].append(call_interface.get_args()); - cheatcodes::assert_public_call_fails(call_interface.get_contract_address(), fn_selector, calldata); + let calldata = + &[call_interface.get_selector().to_field()].append(call_interface.get_args()); + cheatcodes::assert_public_call_fails( + call_interface.get_contract_address(), + fn_selector, + calldata, + ); } - unconstrained fn assert_private_call_fails( - _self: Self, - call_interface: C - ) where C: CallInterface { + unconstrained fn assert_private_call_fails(_self: Self, call_interface: C) + where + C: CallInterface, + { cheatcodes::assert_private_call_fails( call_interface.get_contract_address(), call_interface.get_selector(), hash_args(call_interface.get_args()), cheatcodes::get_side_effects_counter() as Field, - call_interface.get_is_static() + call_interface.get_is_static(), ); } @@ -129,8 +136,11 @@ impl TestEnvironment { _self: Self, note: &mut Note, storage_slot: Field, - contract_address: AztecAddress - ) where Note: NoteInterface + NullifiableNote { + contract_address: AztecAddress, + ) + where + Note: NoteInterface + NullifiableNote, + { let original_contract_address = get_contract_address(); cheatcodes::set_contract_address(contract_address); let note_hash_counter = cheatcodes::get_side_effects_counter(); @@ -144,7 +154,7 @@ impl TestEnvironment { Note::get_note_type_id(), serialized_note, note_hash, - note_hash_counter + note_hash_counter, ); cheatcodes::set_contract_address(original_contract_address); } diff --git a/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr b/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr index 8463f66b4cd..4b2e537386e 100644 --- a/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr +++ b/noir-projects/aztec-nr/aztec/src/test/helpers/utils.nr @@ -1,14 +1,16 @@ use dep::protocol_types::{ traits::{Deserialize, Serialize}, address::AztecAddress, - public_keys::{PublicKeys, PUBLIC_KEYS_LENGTH}, abis::{function_selector::FunctionSelector}, - contract_instance::ContractInstance + public_keys::{PublicKeys, PUBLIC_KEYS_LENGTH}, abis::function_selector::FunctionSelector, + contract_instance::ContractInstance, }; -use crate::context::{PrivateContext, PublicContext, UnconstrainedContext, inputs::PrivateContextInputs}; +use crate::context::{ + PrivateContext, PublicContext, UnconstrainedContext, inputs::PrivateContextInputs, +}; use crate::context::call_interfaces::{PublicCallInterface, CallInterface}; use crate::test::helpers::cheatcodes; -use crate::oracle::{execution::{get_block_number, get_contract_address}}; +use crate::oracle::execution::{get_block_number, get_contract_address}; use protocol_types::constants::PUBLIC_DISPATCH_SELECTOR; use crate::context::gas::GasOpts; use crate::context::call_interfaces::PublicVoidCallInterface; @@ -18,20 +20,23 @@ use crate::oracle::arguments::pack_arguments; pub struct Deployer { path: str, name: str, - public_keys_hash: Field + public_keys_hash: Field, } impl Deployer { pub unconstrained fn with_private_initializer( self, - call_interface: C - ) -> ContractInstance where C: CallInterface

{ + call_interface: C, + ) -> ContractInstance + where + C: CallInterface

, + { let instance = cheatcodes::deploy( self.path, self.name, call_interface.get_name(), call_interface.get_args(), - self.public_keys_hash + self.public_keys_hash, ); cheatcodes::advance_blocks_by(1); let inputs = cheatcodes::get_private_context_inputs(get_block_number() - 1); @@ -43,7 +48,7 @@ impl Deployer { instance.to_address(), call_interface.get_selector(), args_hash, - call_interface.get_is_static() + call_interface.get_is_static(), ); instance @@ -51,50 +56,61 @@ impl Deployer { pub unconstrained fn with_public_void_initializer( self, - call_interface: C - ) -> ContractInstance where C: CallInterface

{ + call_interface: C, + ) -> ContractInstance + where + C: CallInterface

, + { let instance = cheatcodes::deploy( self.path, self.name, call_interface.get_name(), call_interface.get_args(), - self.public_keys_hash + self.public_keys_hash, ); cheatcodes::advance_blocks_by(1); - let mut public_context = PublicContext::new(|| {panic( f"Provide args hash manually")}); + let mut public_context = PublicContext::new(|| { panic(f"Provide args hash manually") }); - public_context.call_public_function( - instance.to_address(), - call_interface.get_selector(), - call_interface.get_args(), - GasOpts::default() - ).assert_empty(); + public_context + .call_public_function( + instance.to_address(), + call_interface.get_selector(), + call_interface.get_args(), + GasOpts::default(), + ) + .assert_empty(); instance } pub unconstrained fn with_public_initializer( self, - call_interface: C - ) -> ContractInstance where C: CallInterface

, T: Deserialize<_> { + call_interface: C, + ) -> ContractInstance + where + C: CallInterface

, + T: Deserialize<_>, + { let instance = cheatcodes::deploy( self.path, self.name, call_interface.get_name(), call_interface.get_args(), - self.public_keys_hash + self.public_keys_hash, ); cheatcodes::advance_blocks_by(1); - let mut public_context = PublicContext::new(|| {panic( f"Provide args hash manually")}); + let mut public_context = PublicContext::new(|| { panic(f"Provide args hash manually") }); - let _: T = public_context.call_public_function( - instance.to_address(), - call_interface.get_selector(), - call_interface.get_args(), - GasOpts::default() - ).deserialize_into(); + let _: T = public_context + .call_public_function( + instance.to_address(), + call_interface.get_selector(), + call_interface.get_args(), + GasOpts::default(), + ) + .deserialize_into(); instance } @@ -109,7 +125,7 @@ global TEST_ACCOUNT_LENGTH = PUBLIC_KEYS_LENGTH + 1; pub struct TestAccount { address: AztecAddress, - keys: PublicKeys + keys: PublicKeys, } impl Serialize for TestAccount { @@ -119,7 +135,7 @@ impl Serialize for TestAccount { output[0] = self.address.to_field(); for i in 0..PUBLIC_KEYS_LENGTH { - output[i+1] = self.keys.serialize()[i]; + output[i + 1] = self.keys.serialize()[i]; } output } @@ -130,7 +146,7 @@ impl Deserialize for TestAccount { let address = AztecAddress::from_field(input[0]); let mut key_buffer = [0; PUBLIC_KEYS_LENGTH]; for i in 0..PUBLIC_KEYS_LENGTH { - key_buffer[i] = input[i+1]; + key_buffer[i] = input[i + 1]; } let keys = PublicKeys::deserialize(key_buffer); diff --git a/noir-projects/aztec-nr/aztec/src/test/mocks/mock_note.nr b/noir-projects/aztec-nr/aztec/src/test/mocks/mock_note.nr index eb1456b49be..4991710182f 100644 --- a/noir-projects/aztec-nr/aztec/src/test/mocks/mock_note.nr +++ b/noir-projects/aztec-nr/aztec/src/test/mocks/mock_note.nr @@ -1,26 +1,36 @@ use crate::{ context::PrivateContext, generators::Ga1 as G_val, - note::{note_header::NoteHeader, note_interface::NoteInterface, utils::compute_note_hash_for_nullify} + note::{ + note_header::NoteHeader, note_interface::NoteInterface, + utils::compute_note_hash_for_nullify, + }, }; -use dep::protocol_types::{address::AztecAddress, constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}; +use dep::protocol_types::{ + address::AztecAddress, constants::GENERATOR_INDEX__NOTE_NULLIFIER, + hash::poseidon2_hash_with_separator, +}; use dep::std::{embedded_curve_ops::multi_scalar_mul, hash::from_field_unsafe}; use crate::note::note_interface::NullifiableNote; global MOCK_NOTE_LENGTH: u32 = 1; pub(crate) struct MockNote { - header: NoteHeader, - value: Field, + header: NoteHeader, + value: Field, } impl NullifiableNote for MockNote { - fn compute_nullifier(_self: Self, _context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + _self: Self, + _context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { // We don't use any kind of secret here since this is only a mock note and having it here would make tests // more cumbersome poseidon2_hash_with_separator( [note_hash_for_nullify], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -30,7 +40,7 @@ impl NullifiableNote for MockNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); poseidon2_hash_with_separator( [note_hash_for_nullify], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } @@ -80,7 +90,10 @@ impl NoteInterface for MockNote { } fn compute_note_hash(self: Self) -> Field { - assert(self.header.storage_slot != 0, "Storage slot must be set before computing note hash"); + assert( + self.header.storage_slot != 0, + "Storage slot must be set before computing note hash", + ); // We use the unsafe version because the multi_scalar_mul will constrain the scalars. let value_scalar = from_field_unsafe(self.value); multi_scalar_mul([G_val], [value_scalar]).x diff --git a/noir-projects/aztec-nr/aztec/src/unencrypted_logs/unencrypted_event_emission.nr b/noir-projects/aztec-nr/aztec/src/unencrypted_logs/unencrypted_event_emission.nr index f8bdcf3d53e..d57bdc43a5d 100644 --- a/noir-projects/aztec-nr/aztec/src/unencrypted_logs/unencrypted_event_emission.nr +++ b/noir-projects/aztec-nr/aztec/src/unencrypted_logs/unencrypted_event_emission.nr @@ -1,10 +1,12 @@ use crate::{context::PublicContext, event::event_interface::EventInterface}; -use dep::protocol_types::{traits::Serialize}; +use dep::protocol_types::traits::Serialize; -fn emit( - context: &mut PublicContext, - event: Event -) where Event: EventInterface, Event: Serialize, [Field; N]: LensForEventSelector { +fn emit(context: &mut PublicContext, event: Event) +where + Event: EventInterface, + Event: Serialize, + [Field; N]: LensForEventSelector, +{ let selector = Event::get_event_type_id(); let serialized_event = event.serialize(); @@ -20,13 +22,15 @@ fn emit( context.emit_unencrypted_log(emitted_log); } -pub fn encode_event(context: &mut PublicContext) -> fn[(&mut PublicContext,)](Event) -> () where Event: EventInterface, Event: Serialize, [Field; N]: LensForEventSelector { - | e: Event | { - emit( - context, - e, - ); - } +pub fn encode_event( + context: &mut PublicContext, +) -> fn[(&mut PublicContext,)](Event) -> () +where + Event: EventInterface, + Event: Serialize, + [Field; N]: LensForEventSelector, +{ + |e: Event| { emit(context, e); } } trait LensForEventSelector { diff --git a/noir-projects/aztec-nr/aztec/src/utils/collapse_array.nr b/noir-projects/aztec-nr/aztec/src/utils/collapse_array.nr index a8e879f2d54..ff5bc2adb82 100644 --- a/noir-projects/aztec-nr/aztec/src/utils/collapse_array.nr +++ b/noir-projects/aztec-nr/aztec/src/utils/collapse_array.nr @@ -3,15 +3,16 @@ // input: [some(3), none(), some(1)] // this returns // collapsed: [3, 1] -pub fn collapse_array(input: [Option; N]) -> BoundedVec where T: Eq { +pub fn collapse_array(input: [Option; N]) -> BoundedVec +where + T: Eq, +{ // Computing the collpased BoundedVec would result in a very large number of constraints, since we'd need to loop // over the input array and conditionally write to a dynamic vec index, which is a very unfriendly pattern to the // proving backend. // Instead, we use an unconstrained function to produce the final collapsed array, along with some hints, and then // verify that the input and collapsed arrays are equivalent. - let (collapsed, collapsed_to_input_index_mapping) = unsafe { - get_collapse_hints(input) - }; + let (collapsed, collapsed_to_input_index_mapping) = unsafe { get_collapse_hints(input) }; verify_collapse_hints(input, collapsed, collapsed_to_input_index_mapping); collapsed } @@ -19,11 +20,13 @@ pub fn collapse_array(input: [Option; N]) -> BoundedVec pub(crate) fn verify_collapse_hints( input: [Option; N], collapsed: BoundedVec, - collapsed_to_input_index_mapping: BoundedVec -) where T: Eq { + collapsed_to_input_index_mapping: BoundedVec, +) +where + T: Eq, +{ // collapsed should be a BoundedVec with all the non-none elements in input, in the same order. We need to lay down // multiple constraints to guarantee this. - // First we check that the number of elements is correct let mut count = 0; for i in 0..N { @@ -41,7 +44,11 @@ pub(crate) fn verify_collapse_hints( // - collapsed: [3, 1] // - collapsed_to_input_index_mapping: [0, 2] // These two arrays should therefore have the same length. - assert_eq(collapsed.len(), collapsed_to_input_index_mapping.len(), "Collapse hint vec length mismatch"); + assert_eq( + collapsed.len(), + collapsed_to_input_index_mapping.len(), + "Collapse hint vec length mismatch", + ); // We now look at each collapsed entry and check that there is a valid equal entry in the input array. let mut last_index = Option::none(); @@ -50,7 +57,11 @@ pub(crate) fn verify_collapse_hints( let input_index = collapsed_to_input_index_mapping.get_unchecked(i); assert(input_index < N, "Out of bounds index hint"); - assert_eq(collapsed.get_unchecked(i), input[input_index].unwrap(), "Wrong collapsed vec content"); + assert_eq( + collapsed.get_unchecked(i), + input[input_index].unwrap(), + "Wrong collapsed vec content", + ); // By requiring increasing input indices, we both guarantee that we're not looking at the same input // element more than once, and that we're going over them in the original order. @@ -61,7 +72,11 @@ pub(crate) fn verify_collapse_hints( } else { // BoundedVec assumes that the unused parts of the storage are zeroed out (e.g. in the Eq impl), so we make // sure that this property holds. - assert_eq(collapsed.get_unchecked(i), std::mem::zeroed(), "Dirty collapsed vec storage"); + assert_eq( + collapsed.get_unchecked(i), + std::mem::zeroed(), + "Dirty collapsed vec storage", + ); } } // We now know that: @@ -72,7 +87,9 @@ pub(crate) fn verify_collapse_hints( // Therefore, the collapsed array is correct. } -unconstrained fn get_collapse_hints(input: [Option; N]) -> (BoundedVec, BoundedVec) { +unconstrained fn get_collapse_hints( + input: [Option; N], +) -> (BoundedVec, BoundedVec) { let mut collapsed: BoundedVec = BoundedVec::new(); let mut collapsed_to_input_index_mapping: BoundedVec = BoundedVec::new(); diff --git a/noir-projects/aztec-nr/aztec/src/utils/comparison.nr b/noir-projects/aztec-nr/aztec/src/utils/comparison.nr index 32ab067b96c..d3ec8c4f612 100644 --- a/noir-projects/aztec-nr/aztec/src/utils/comparison.nr +++ b/noir-projects/aztec-nr/aztec/src/utils/comparison.nr @@ -7,14 +7,7 @@ struct ComparatorEnum { GTE: u8, } -global Comparator = ComparatorEnum { - EQ: 1, - NEQ: 2, - LT: 3, - LTE: 4, - GT: 5, - GTE: 6, -}; +global Comparator = ComparatorEnum { EQ: 1, NEQ: 2, LT: 3, LTE: 4, GT: 5, GTE: 6 }; pub fn compare(lhs: Field, operation: u8, rhs: Field) -> bool { // Values are computed ahead of time because circuits evaluate all branches @@ -66,11 +59,17 @@ mod test { let lhs = 10; let rhs = 10; - assert(compare(lhs, Comparator.GTE, rhs), "Expected lhs to be greater than or equal to rhs"); + assert( + compare(lhs, Comparator.GTE, rhs), + "Expected lhs to be greater than or equal to rhs", + ); let lhs = 11; let rhs = 10; - assert(compare(lhs, Comparator.GTE, rhs), "Expected lhs to be greater than or equal to rhs"); + assert( + compare(lhs, Comparator.GTE, rhs), + "Expected lhs to be greater than or equal to rhs", + ); let lhs = 10; let rhs = 11; @@ -86,7 +85,10 @@ mod test { let lhs = 11; let rhs = 10; - assert(!compare(lhs, Comparator.LTE, rhs), "Expected lhs to not be less than or equal to rhs"); + assert( + !compare(lhs, Comparator.LTE, rhs), + "Expected lhs to not be less than or equal to rhs", + ); let lhs = 10; let rhs = 10; @@ -94,10 +96,16 @@ mod test { let lhs = 10; let rhs = 11; - assert(!compare(lhs, Comparator.GTE, rhs), "Expected lhs to not be greater than or equal to rhs"); + assert( + !compare(lhs, Comparator.GTE, rhs), + "Expected lhs to not be greater than or equal to rhs", + ); let lhs = 10; let rhs = 11; - assert(!compare(lhs, Comparator.GTE, rhs), "Expected lhs to not be greater than or equal to rhs"); + assert( + !compare(lhs, Comparator.GTE, rhs), + "Expected lhs to not be greater than or equal to rhs", + ); } } diff --git a/noir-projects/aztec-nr/aztec/src/utils/point.nr b/noir-projects/aztec-nr/aztec/src/utils/point.nr index 22fb675663c..ecfb802dd48 100644 --- a/noir-projects/aztec-nr/aztec/src/utils/point.nr +++ b/noir-projects/aztec-nr/aztec/src/utils/point.nr @@ -2,7 +2,8 @@ use dep::protocol_types::point::Point; // I am storing the modulus divided by 2 plus 1 here because full modulus would throw "String literal too large" error // Full modulus is 21888242871839275222246405745257275088548364400416034343698204186575808495617 -global BN254_FR_MODULUS_DIV_2: Field = 10944121435919637611123202872628637544274182200208017171849102093287904247808; +global BN254_FR_MODULUS_DIV_2: Field = + 10944121435919637611123202872628637544274182200208017171849102093287904247808; /// Converts a public key to a byte array. /// @@ -39,13 +40,14 @@ mod test { let p = Point { x: 0x1af41f5de96446dc3776a1eb2d98bb956b7acd9979a67854bec6fa7c2973bd73, y: 0x07fc22c7f2c7057571f137fe46ea9c95114282bc95d37d71ec4bfb88de457d4a, - is_infinite: false + is_infinite: false, }; let compressed_point = point_to_bytes(p); let expected_compressed_point_positive_sign = [ - 154, 244, 31, 93, 233, 100, 70, 220, 55, 118, 161, 235, 45, 152, 187, 149, 107, 122, 205, 153, 121, 166, 120, 84, 190, 198, 250, 124, 41, 115, 189, 115 + 154, 244, 31, 93, 233, 100, 70, 220, 55, 118, 161, 235, 45, 152, 187, 149, 107, 122, + 205, 153, 121, 166, 120, 84, 190, 198, 250, 124, 41, 115, 189, 115, ]; assert_eq(expected_compressed_point_positive_sign, compressed_point); } @@ -55,13 +57,14 @@ mod test { let p = Point { x: 0x247371652e55dd74c9af8dbe9fb44931ba29a9229994384bd7077796c14ee2b5, y: 0x26441aec112e1ae4cee374f42556932001507ad46e255ffb27369c7e3766e5c0, - is_infinite: false + is_infinite: false, }; let compressed_point = point_to_bytes(p); let expected_compressed_point_negative_sign = [ - 36, 115, 113, 101, 46, 85, 221, 116, 201, 175, 141, 190, 159, 180, 73, 49, 186, 41, 169, 34, 153, 148, 56, 75, 215, 7, 119, 150, 193, 78, 226, 181 + 36, 115, 113, 101, 46, 85, 221, 116, 201, 175, 141, 190, 159, 180, 73, 49, 186, 41, 169, + 34, 153, 148, 56, 75, 215, 7, 119, 150, 193, 78, 226, 181, ]; assert_eq(expected_compressed_point_negative_sign, compressed_point); diff --git a/noir-projects/aztec-nr/aztec/src/utils/test.nr b/noir-projects/aztec-nr/aztec/src/utils/test.nr index 7919429d1bc..c201e480a07 100644 --- a/noir-projects/aztec-nr/aztec/src/utils/test.nr +++ b/noir-projects/aztec-nr/aztec/src/utils/test.nr @@ -30,7 +30,8 @@ unconstrained fn collapse_sparse_array() { #[test] unconstrained fn collapse_array_front_padding() { - let original = [Option::none(), Option::none(), Option::some(7), Option::none(), Option::some(3)]; + let original = + [Option::none(), Option::none(), Option::some(7), Option::none(), Option::some(3)]; let collapsed = collapse_array(original); assert_eq(collapsed.len(), 2); @@ -40,7 +41,8 @@ unconstrained fn collapse_array_front_padding() { #[test] unconstrained fn collapse_array_back_padding() { - let original = [Option::some(7), Option::none(), Option::some(3), Option::none(), Option::none()]; + let original = + [Option::some(7), Option::none(), Option::some(3), Option::none(), Option::none()]; let collapsed = collapse_array(original); assert_eq(collapsed.len(), 2); diff --git a/noir-projects/aztec-nr/compressed-string/src/compressed_string.nr b/noir-projects/aztec-nr/compressed-string/src/compressed_string.nr index 8321c3f4b27..6c209bf9c17 100644 --- a/noir-projects/aztec-nr/compressed-string/src/compressed_string.nr +++ b/noir-projects/aztec-nr/compressed-string/src/compressed_string.nr @@ -5,7 +5,7 @@ use dep::aztec::protocol_types::{utils::field::field_from_bytes, traits::{Serial // Can be used for longer strings that don't fit in a single field. // Each field can store 31 characters, so N should be M/31 rounded up. pub struct CompressedString { - value: [Field; N] + value: [Field; N], } impl CompressedString { @@ -68,7 +68,7 @@ impl Deserialize for CompressedString { unconstrained fn test_short_string() { let i = "Hello world"; let b = i.as_bytes(); - let name: CompressedString<1,11> = CompressedString::from_string(i); + let name: CompressedString<1, 11> = CompressedString::from_string(i); let p = b == name.to_bytes(); assert(p, "invalid recover"); } @@ -77,7 +77,7 @@ unconstrained fn test_short_string() { unconstrained fn test_long_string() { let i = "Hello world. I'm setting up a very long text of blibbablubb such that we can see if works as planned for longer names."; let b = i.as_bytes(); - let name: CompressedString<4,118> = CompressedString::from_string(i); + let name: CompressedString<4, 118> = CompressedString::from_string(i); let p = b == name.to_bytes(); assert(p, "invalid recover"); } @@ -86,7 +86,7 @@ unconstrained fn test_long_string() { unconstrained fn test_long_string_work_with_too_many_fields() { let i = "Hello world. I'm setting up a very long text of blibbablubb such that we can see if works as planned for longer names."; let b = i.as_bytes(); - let name: CompressedString<5,118> = CompressedString::from_string(i); + let name: CompressedString<5, 118> = CompressedString::from_string(i); let p = b == name.to_bytes(); assert(p, "invalid recover"); } @@ -94,7 +94,7 @@ unconstrained fn test_long_string_work_with_too_many_fields() { #[test] unconstrained fn test_serde() { let i = "Hello world. I'm setting up a very long text of blibbablubb such that we can see if works as planned for longer names."; - let name: CompressedString<5,118> = CompressedString::from_string(i); + let name: CompressedString<5, 118> = CompressedString::from_string(i); assert_eq(name, CompressedString::deserialize(name.serialize())); } @@ -103,7 +103,7 @@ unconstrained fn test_serde() { unconstrained fn test_long_string_fail_with_too_few_fields() { let i = "Hello world. I'm setting up a very long text of blibbablubb such that we can see if works as planned for longer names."; let b = i.as_bytes(); - let name: CompressedString<3,118> = CompressedString::from_string(i); + let name: CompressedString<3, 118> = CompressedString::from_string(i); let p = b == name.to_bytes(); assert(p, "invalid recover"); } diff --git a/noir-projects/aztec-nr/compressed-string/src/field_compressed_string.nr b/noir-projects/aztec-nr/compressed-string/src/field_compressed_string.nr index 9ee35aa9099..54675974958 100644 --- a/noir-projects/aztec-nr/compressed-string/src/field_compressed_string.nr +++ b/noir-projects/aztec-nr/compressed-string/src/field_compressed_string.nr @@ -2,8 +2,8 @@ use dep::aztec::protocol_types::{utils::field::field_from_bytes, traits::{Serial // A Fixedsize Compressed String. // Essentially a special version of Compressed String for practical use. -pub struct FieldCompressedString{ - value: Field +pub struct FieldCompressedString { + value: Field, } impl Serialize<1> for FieldCompressedString { diff --git a/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr b/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr index 2bf133a7f25..ec014ecd026 100644 --- a/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr +++ b/noir-projects/aztec-nr/easy-private-state/src/easy_private_uint.nr @@ -1,7 +1,8 @@ use dep::aztec::{ - context::PrivateContext, protocol_types::{address::AztecAddress}, + context::PrivateContext, protocol_types::address::AztecAddress, note::note_getter_options::NoteGetterOptions, state_vars::PrivateSet, - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + keys::getters::get_public_keys, }; use dep::value_note::{filter::filter_notes_min_sum, value_note::ValueNote}; @@ -30,14 +31,12 @@ impl EasyPrivateUint<&mut PrivateContext> { // Insert the new note to the owner's set of notes. // docs:start:insert - self.set.insert(&mut addend_note).emit( - encode_and_encrypt_note( - self.context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + self.set.insert(&mut addend_note).emit(encode_and_encrypt_note( + self.context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); // docs:end:insert } @@ -50,7 +49,6 @@ impl EasyPrivateUint<&mut PrivateContext> { let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend as Field); let notes = self.set.pop_notes(options); // docs:end:pop_notes - let mut minuend: u64 = 0; for i in 0..options.limit { if i < notes.len() { @@ -65,13 +63,11 @@ impl EasyPrivateUint<&mut PrivateContext> { // Creates change note for the owner. let result_value = minuend - subtrahend; let mut result_note = ValueNote::new(result_value as Field, owner_keys.npk_m.hash()); - self.set.insert(&mut result_note).emit( - encode_and_encrypt_note( - self.context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + self.set.insert(&mut result_note).emit(encode_and_encrypt_note( + self.context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } } diff --git a/noir-projects/aztec-nr/uint-note/src/uint_note.nr b/noir-projects/aztec-nr/uint-note/src/uint_note.nr index 8e4485a8f09..4552c980c64 100644 --- a/noir-projects/aztec-nr/uint-note/src/uint_note.nr +++ b/noir-projects/aztec-nr/uint-note/src/uint_note.nr @@ -1,7 +1,8 @@ use dep::aztec::{ prelude::{NullifiableNote, PrivateContext}, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - note::utils::compute_note_hash_for_nullify, keys::getters::get_nsk_app, macros::notes::note + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + }, note::utils::compute_note_hash_for_nullify, keys::getters::get_nsk_app, macros::notes::note, }; #[note] @@ -15,14 +16,15 @@ pub struct UintNote { } impl NullifiableNote for UintNote { - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -31,7 +33,7 @@ impl NullifiableNote for UintNote { let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( [note_hash_for_nullify, secret], - GENERATOR_INDEX__NOTE_NULLIFIER + GENERATOR_INDEX__NOTE_NULLIFIER, ) } } diff --git a/noir-projects/aztec-nr/value-note/src/balance_utils.nr b/noir-projects/aztec-nr/value-note/src/balance_utils.nr index c5aa44fcb4a..35254d99943 100644 --- a/noir-projects/aztec-nr/value-note/src/balance_utils.nr +++ b/noir-projects/aztec-nr/value-note/src/balance_utils.nr @@ -1,4 +1,7 @@ -use dep::aztec::{context::UnconstrainedContext, state_vars::PrivateSet, note::{note_viewer_options::NoteViewerOptions}}; +use dep::aztec::{ + context::UnconstrainedContext, state_vars::PrivateSet, + note::note_viewer_options::NoteViewerOptions, +}; use crate::value_note::ValueNote; pub unconstrained fn get_balance(set: PrivateSet) -> Field { @@ -7,7 +10,7 @@ pub unconstrained fn get_balance(set: PrivateSet, - offset: u32 + offset: u32, ) -> Field { let mut balance = 0; // docs:start:view_notes diff --git a/noir-projects/aztec-nr/value-note/src/filter.nr b/noir-projects/aztec-nr/value-note/src/filter.nr index 8024414d4e5..fb24074a0d9 100644 --- a/noir-projects/aztec-nr/value-note/src/filter.nr +++ b/noir-projects/aztec-nr/value-note/src/filter.nr @@ -3,7 +3,7 @@ use crate::value_note::ValueNote; pub fn filter_notes_min_sum( notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - min_sum: Field + min_sum: Field, ) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] { let mut selected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; diff --git a/noir-projects/aztec-nr/value-note/src/utils.nr b/noir-projects/aztec-nr/value-note/src/utils.nr index 3efc118588b..e5cedaf9dcb 100644 --- a/noir-projects/aztec-nr/value-note/src/utils.nr +++ b/noir-projects/aztec-nr/value-note/src/utils.nr @@ -6,8 +6,13 @@ use crate::{filter::filter_notes_min_sum, value_note::{ValueNote, VALUE_NOTE_LEN // Sort the note values (0th field) in descending order. // Pick the fewest notes whose sum is equal to or greater than `amount`. -pub fn create_note_getter_options_for_decreasing_balance(amount: Field) -> NoteGetterOptions { - NoteGetterOptions::with_filter(filter_notes_min_sum, amount).sort(ValueNote::properties().value, SortOrder.DESC) +pub fn create_note_getter_options_for_decreasing_balance( + amount: Field, +) -> NoteGetterOptions { + NoteGetterOptions::with_filter(filter_notes_min_sum, amount).sort( + ValueNote::properties().value, + SortOrder.DESC, + ) } // Creates a new note for the recipient. @@ -17,21 +22,19 @@ pub fn increment( balance: PrivateSet, amount: Field, recipient: AztecAddress, - outgoing_viewer: AztecAddress // docs:end:increment_args + outgoing_viewer: AztecAddress, // docs:end:increment_args ) { let recipient_keys = get_public_keys(recipient); let outgoing_viewer_ovpk_m = get_public_keys(outgoing_viewer).ovpk_m; let mut note = ValueNote::new(amount, recipient_keys.npk_m.hash()); // Insert the new note to the owner's set of notes and emit the log if value is non-zero. - balance.insert(&mut note).emit( - encode_and_encrypt_note( - balance.context, - outgoing_viewer_ovpk_m, - recipient_keys.ivpk_m, - recipient - ) - ); + balance.insert(&mut note).emit(encode_and_encrypt_note( + balance.context, + outgoing_viewer_ovpk_m, + recipient_keys.ivpk_m, + recipient, + )); } // Find some of the `owner`'s notes whose values add up to the `amount`. @@ -42,7 +45,7 @@ pub fn decrement( balance: PrivateSet, amount: Field, owner: AztecAddress, - outgoing_viewer: AztecAddress + outgoing_viewer: AztecAddress, ) { let sum = decrement_by_at_most(balance, amount, owner, outgoing_viewer); assert(sum == amount, "Balance too low"); @@ -60,7 +63,7 @@ pub fn decrement_by_at_most( balance: PrivateSet, max_amount: Field, owner: AztecAddress, - outgoing_viewer: AztecAddress + outgoing_viewer: AztecAddress, ) -> Field { let options = create_note_getter_options_for_decreasing_balance(max_amount); let notes = balance.pop_notes(options); diff --git a/noir-projects/aztec-nr/value-note/src/value_note.nr b/noir-projects/aztec-nr/value-note/src/value_note.nr index c749cf4f399..69d6cd68dbf 100644 --- a/noir-projects/aztec-nr/value-note/src/value_note.nr +++ b/noir-projects/aztec-nr/value-note/src/value_note.nr @@ -1,8 +1,12 @@ use dep::aztec::{ - protocol_types::{traits::Serialize, constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - macros::notes::note, - note::{note_header::NoteHeader, note_interface::NullifiableNote, utils::compute_note_hash_for_nullify}, - oracle::random::random, keys::getters::get_nsk_app, context::PrivateContext + protocol_types::{ + traits::Serialize, constants::GENERATOR_INDEX__NOTE_NULLIFIER, + hash::poseidon2_hash_with_separator, + }, macros::notes::note, + note::{ + note_header::NoteHeader, note_interface::NullifiableNote, + utils::compute_note_hash_for_nullify, + }, oracle::random::random, keys::getters::get_nsk_app, context::PrivateContext, }; global VALUE_NOTE_LEN: u32 = 3; // 3 plus a header. @@ -14,7 +18,7 @@ global VALUE_NOTE_LEN: u32 = 3; // 3 plus a header. #[derive(Serialize)] pub struct ValueNote { value: Field, - // The nullifying public key hash is used with the nsk_app to ensure that the note can be privately spent. + // The nullifying public key hash is used with the nsk_app to ensure that the note can be privately spent. npk_m_hash: Field, randomness: Field, } @@ -23,14 +27,15 @@ pub struct ValueNote { impl NullifiableNote for ValueNote { // docs:start:nullifier - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -40,11 +45,8 @@ impl NullifiableNote for ValueNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } @@ -55,9 +57,7 @@ impl ValueNote { // malicious sender could use non-random values to make the note less private. But they already know the full // note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can // therefore assume that the sender will cooperate in the random value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; let header = NoteHeader::empty(); ValueNote { value, npk_m_hash, randomness, header } } diff --git a/noir-projects/mock-protocol-circuits/crates/app-reader/src/main.nr b/noir-projects/mock-protocol-circuits/crates/app-reader/src/main.nr index 11d179ec6a7..a6624c769d6 100644 --- a/noir-projects/mock-protocol-circuits/crates/app-reader/src/main.nr +++ b/noir-projects/mock-protocol-circuits/crates/app-reader/src/main.nr @@ -2,7 +2,9 @@ use dep::mock_types::{AppPublicInputs, MAX_COMMITMENT_READ_REQUESTS_PER_CALL}; // Mock app for testing that reads the commitments (generates read requests) the user commands. // Note: A zero read is a null read. -fn main(commitments_to_read: [Field; MAX_COMMITMENT_READ_REQUESTS_PER_CALL]) -> return_data AppPublicInputs { +fn main( + commitments_to_read: [Field; MAX_COMMITMENT_READ_REQUESTS_PER_CALL], +) -> return_data AppPublicInputs { let mut result = AppPublicInputs::default(); result.read_requests = commitments_to_read; result diff --git a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-init/src/main.nr b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-init/src/main.nr index d2585336fdb..4721892e815 100644 --- a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-init/src/main.nr +++ b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-init/src/main.nr @@ -1,8 +1,10 @@ -use dep::mock_types::{TxRequest, PrivateKernelPublicInputs, PrivateKernelPublicInputsBuilder, AppPublicInputs}; +use dep::mock_types::{ + TxRequest, PrivateKernelPublicInputs, PrivateKernelPublicInputsBuilder, AppPublicInputs, +}; fn main( tx: TxRequest, - app_inputs: call_data(1) AppPublicInputs + app_inputs: call_data(1) AppPublicInputs, ) -> return_data PrivateKernelPublicInputs { let mut private_kernel_inputs = PrivateKernelPublicInputsBuilder::from_tx(tx); private_kernel_inputs.ingest_app_inputs(app_inputs); diff --git a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-inner/src/main.nr b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-inner/src/main.nr index 0a6b4c11761..db3f1b6b965 100644 --- a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-inner/src/main.nr +++ b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-inner/src/main.nr @@ -2,9 +2,10 @@ use dep::mock_types::{PrivateKernelPublicInputs, PrivateKernelPublicInputsBuilde fn main( prev_kernel_public_inputs: call_data(0) PrivateKernelPublicInputs, - app_inputs: call_data(1) AppPublicInputs + app_inputs: call_data(1) AppPublicInputs, ) -> return_data PrivateKernelPublicInputs { - let mut private_kernel_inputs = PrivateKernelPublicInputsBuilder::from_previous_kernel(prev_kernel_public_inputs); + let mut private_kernel_inputs = + PrivateKernelPublicInputsBuilder::from_previous_kernel(prev_kernel_public_inputs); private_kernel_inputs.ingest_app_inputs(app_inputs); private_kernel_inputs.finish() } diff --git a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-reset/src/main.nr b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-reset/src/main.nr index f4e49af46d7..bfe1fed3b81 100644 --- a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-reset/src/main.nr +++ b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-reset/src/main.nr @@ -1,15 +1,18 @@ -use dep::mock_types::{PrivateKernelPublicInputs, MAX_COMMITMENT_READ_REQUESTS_PER_TX, MAX_COMMITMENTS_PER_TX}; +use dep::mock_types::{ + PrivateKernelPublicInputs, MAX_COMMITMENT_READ_REQUESTS_PER_TX, MAX_COMMITMENTS_PER_TX, +}; // Mock reset kernel that reset read requests. // It needs hints to locate the commitment that matches the read requests. fn main( mut prev_kernel_public_inputs: call_data(0) PrivateKernelPublicInputs, - commitment_read_hints: [u32; MAX_COMMITMENT_READ_REQUESTS_PER_TX] + commitment_read_hints: [u32; MAX_COMMITMENT_READ_REQUESTS_PER_TX], ) -> return_data PrivateKernelPublicInputs { for i in 0..MAX_COMMITMENT_READ_REQUESTS_PER_TX { if commitment_read_hints[i] != MAX_COMMITMENTS_PER_TX { assert_eq( - prev_kernel_public_inputs.commitments[commitment_read_hints[i]], prev_kernel_public_inputs.read_requests[i] + prev_kernel_public_inputs.commitments[commitment_read_hints[i]], + prev_kernel_public_inputs.read_requests[i], ); prev_kernel_public_inputs.read_requests[i] = 0; } diff --git a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-tail/src/main.nr b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-tail/src/main.nr index 93bd23cf813..fe978c813ab 100644 --- a/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-tail/src/main.nr +++ b/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-tail/src/main.nr @@ -1,7 +1,11 @@ -use dep::mock_types::{PrivateKernelPublicInputs, KernelPublicInputs, MAX_COMMITMENT_READ_REQUESTS_PER_TX}; +use dep::mock_types::{ + PrivateKernelPublicInputs, KernelPublicInputs, MAX_COMMITMENT_READ_REQUESTS_PER_TX, +}; // The tail kernel finishes the client IVC chain exposing the final public inputs with no remaining calls or unfulfilled read requests. -fn main(prev_kernel_public_inputs: call_data(0) PrivateKernelPublicInputs) -> pub KernelPublicInputs { +fn main( + prev_kernel_public_inputs: call_data(0) PrivateKernelPublicInputs, +) -> pub KernelPublicInputs { assert_eq(prev_kernel_public_inputs.remaining_calls, 0); for i in 0..MAX_COMMITMENT_READ_REQUESTS_PER_TX { assert_eq(prev_kernel_public_inputs.read_requests[i], 0); diff --git a/noir-projects/mock-protocol-circuits/crates/mock-public-kernel/src/main.nr b/noir-projects/mock-protocol-circuits/crates/mock-public-kernel/src/main.nr index 5f99389e499..21db8524f23 100644 --- a/noir-projects/mock-protocol-circuits/crates/mock-public-kernel/src/main.nr +++ b/noir-projects/mock-protocol-circuits/crates/mock-public-kernel/src/main.nr @@ -1,13 +1,19 @@ use dep::types::constants::{ - AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS, AVM_PROOF_LENGTH_IN_FIELDS, AVM_PUBLIC_INPUTS_FLATTENED_SIZE, - PROOF_TYPE_AVM + AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS, AVM_PROOF_LENGTH_IN_FIELDS, + AVM_PUBLIC_INPUTS_FLATTENED_SIZE, PROOF_TYPE_AVM, }; fn main( verification_key: [Field; AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS], proof: [Field; AVM_PROOF_LENGTH_IN_FIELDS], - pub_cols_flattened: [Field; AVM_PUBLIC_INPUTS_FLATTENED_SIZE] + pub_cols_flattened: [Field; AVM_PUBLIC_INPUTS_FLATTENED_SIZE], ) -> pub u8 { - std::verify_proof_with_type(verification_key, proof, pub_cols_flattened, 0, PROOF_TYPE_AVM); + std::verify_proof_with_type( + verification_key, + proof, + pub_cols_flattened, + 0, + PROOF_TYPE_AVM, + ); 1 // Dummy value to return for the mock kernel as void function creates some pain. } diff --git a/noir-projects/mock-protocol-circuits/crates/mock-types/src/lib.nr b/noir-projects/mock-protocol-circuits/crates/mock-types/src/lib.nr index 46936a79499..f9cecca0a4a 100644 --- a/noir-projects/mock-protocol-circuits/crates/mock-types/src/lib.nr +++ b/noir-projects/mock-protocol-circuits/crates/mock-types/src/lib.nr @@ -14,7 +14,10 @@ struct AppPublicInputs { impl Default for AppPublicInputs { fn default() -> Self { - Self { commitments: [0; MAX_COMMITMENTS_PER_CALL], read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_CALL] } + Self { + commitments: [0; MAX_COMMITMENTS_PER_CALL], + read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_CALL], + } } } @@ -29,7 +32,7 @@ impl Default for PrivateKernelPublicInputs { Self { remaining_calls: 0, commitments: [0; MAX_COMMITMENTS_PER_TX], - read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_TX] + read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_TX], } } } @@ -42,14 +45,18 @@ struct PrivateKernelPublicInputsBuilder { impl PrivateKernelPublicInputsBuilder { fn from_tx(tx: TxRequest) -> Self { - Self { remaining_calls: tx.number_of_calls, commitments: BoundedVec::new(), read_requests: BoundedVec::new() } + Self { + remaining_calls: tx.number_of_calls, + commitments: BoundedVec::new(), + read_requests: BoundedVec::new(), + } } fn from_previous_kernel(prev_kernel_public_inputs: PrivateKernelPublicInputs) -> Self { let mut builder = PrivateKernelPublicInputsBuilder { remaining_calls: prev_kernel_public_inputs.remaining_calls, commitments: BoundedVec::new(), - read_requests: BoundedVec::new() + read_requests: BoundedVec::new(), }; for i in 0..MAX_COMMITMENTS_PER_TX { if prev_kernel_public_inputs.commitments[i] != 0 { @@ -84,7 +91,7 @@ impl PrivateKernelPublicInputsBuilder { PrivateKernelPublicInputs { remaining_calls: self.remaining_calls, commitments: self.commitments.storage, - read_requests: self.read_requests.storage + read_requests: self.read_requests.storage, } } } diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr index 87ac7c518d0..46946dac5eb 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/dapp_payload.nr @@ -1,7 +1,7 @@ use dep::aztec::prelude::{PrivateContext, AztecAddress}; use dep::aztec::protocol_types::{ constants::GENERATOR_INDEX__SIGNATURE_PAYLOAD, hash::poseidon2_hash_with_separator, - traits::{Hash, Serialize} + traits::{Hash, Serialize}, }; use dep::authwit::entrypoint::function_call::FunctionCall; @@ -15,8 +15,8 @@ global DAPP_PAYLOAD_SIZE_IN_BYTES: u32 = 130; // Note: If you change the following struct you have to update default_entrypoint.ts // docs:start:app-payload-struct pub struct DAppPayload { - function_calls: [FunctionCall; DAPP_MAX_CALLS], - nonce: Field, + function_calls: [FunctionCall; DAPP_MAX_CALLS], + nonce: Field, } // docs:end:app-payload-struct @@ -63,14 +63,14 @@ impl DAppPayload { call.target_address, call.function_selector, call.args_hash, - call.is_static + call.is_static, ); } else { let _result = context.call_private_function_with_packed_args( call.target_address, call.function_selector, call.args_hash, - call.is_static + call.is_static, ); } } diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index dfd2f5480ab..29890944b7f 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -8,10 +8,11 @@ contract AppSubscription { use crate::{dapp_payload::DAppPayload, subscription_note::SubscriptionNote}; use aztec::{ - prelude::{AztecAddress, Map, PrivateMutable, SharedImmutable}, keys::getters::get_public_keys, - protocol_types::constants::MAX_FIELD_VALUE, utils::comparison::Comparator, + prelude::{AztecAddress, Map, PrivateMutable, SharedImmutable}, + keys::getters::get_public_keys, protocol_types::constants::MAX_FIELD_VALUE, + utils::comparison::Comparator, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, - macros::{storage::storage, functions::{public, initializer, private}} + macros::{storage::storage, functions::{public, initializer, private}}, }; use authwit::auth::assert_current_call_valid_authwit; use token::Token; @@ -47,7 +48,12 @@ contract AppSubscription { // We are emitting both the outgoing and the incoming logs to the subscriber here because passing a separate // outgoing_viewer arg to entrypoint function is impractical and the outgoing are not so valuable here. let keys = get_public_keys(user_address); - storage.subscriptions.at(user_address).replace(&mut note).emit(encode_and_encrypt_note(&mut context, keys.ovpk_m, keys.ivpk_m, user_address)); + storage.subscriptions.at(user_address).replace(&mut note).emit(encode_and_encrypt_note( + &mut context, + keys.ovpk_m, + keys.ivpk_m, + user_address, + )); context.set_as_fee_payer(); @@ -70,7 +76,7 @@ contract AppSubscription { subscription_recipient_address: AztecAddress, subscription_token_address: AztecAddress, subscription_price: Field, - fee_juice_limit_per_tx: Field + fee_juice_limit_per_tx: Field, ) { storage.target_address.initialize(target_address); storage.subscription_token_address.initialize(subscription_token_address); @@ -80,35 +86,43 @@ contract AppSubscription { } #[private] - fn subscribe(subscriber: AztecAddress, nonce: Field, expiry_block_number: Field, tx_count: Field) { + fn subscribe( + subscriber: AztecAddress, + nonce: Field, + expiry_block_number: Field, + tx_count: Field, + ) { assert(tx_count as u64 <= SUBSCRIPTION_TXS as u64); - Token::at(storage.subscription_token_address.read_private()).transfer_from( - context.msg_sender(), - storage.subscription_recipient_address.read_private(), - storage.subscription_price.read_private(), - nonce - ).call(&mut context); + Token::at(storage.subscription_token_address.read_private()) + .transfer_from( + context.msg_sender(), + storage.subscription_recipient_address.read_private(), + storage.subscription_price.read_private(), + nonce, + ) + .call(&mut context); // Assert that the `current_block_number > expiry_block_number - SUBSCRIPTION_DURATION_IN_BLOCKS`. // --> We do that via the router contract to conceal which contract is performing the check. privately_check_block_number( Comparator.GT, expiry_block_number - SUBSCRIPTION_DURATION_IN_BLOCKS, - &mut context + &mut context, ); let subscriber_keys = get_public_keys(subscriber); let msg_sender_ovpk_m = get_public_keys(context.msg_sender()).ovpk_m; - let mut subscription_note = SubscriptionNote::new(subscriber_keys.npk_m.hash(), expiry_block_number, tx_count); + let mut subscription_note = + SubscriptionNote::new(subscriber_keys.npk_m.hash(), expiry_block_number, tx_count); storage.subscriptions.at(subscriber).initialize_or_replace(&mut subscription_note).emit( encode_and_encrypt_note( &mut context, msg_sender_ovpk_m, subscriber_keys.ivpk_m, - subscriber - ) + subscriber, + ), ); } diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr index 58a0101880d..815c512544e 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/subscription_note.nr @@ -2,7 +2,7 @@ use dep::aztec::{ hash::poseidon2_hash_with_separator, note::utils::compute_note_hash_for_nullify, keys::getters::get_nsk_app, oracle::random::random, prelude::{PrivateContext, NoteHeader, NullifiableNote}, - protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, macros::notes::note + protocol_types::constants::GENERATOR_INDEX__NOTE_NULLIFIER, macros::notes::note, }; #[note] @@ -16,14 +16,15 @@ pub struct SubscriptionNote { } impl NullifiableNote for SubscriptionNote { - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -31,11 +32,8 @@ impl NullifiableNote for SubscriptionNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } @@ -46,9 +44,13 @@ impl SubscriptionNote { // malicious sender could use non-random values to make the note less private. But they already know the full // note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can // therefore assume that the sender will cooperate in the random value generation. - let randomness = unsafe { - random() - }; - Self { npk_m_hash, expiry_block_number, remaining_txs, randomness, header: NoteHeader::empty() } + let randomness = unsafe { random() }; + Self { + npk_m_hash, + expiry_block_number, + remaining_txs, + randomness, + header: NoteHeader::empty(), + } } } diff --git a/noir-projects/noir-contracts/contracts/auth_contract/src/main.nr b/noir-projects/noir-contracts/contracts/auth_contract/src/main.nr index 18f4cd0aebb..cf5c1d9c089 100644 --- a/noir-projects/noir-contracts/contracts/auth_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/auth_contract/src/main.nr @@ -8,7 +8,7 @@ use dep::aztec::macros::aztec; contract Auth { use dep::aztec::{ protocol_types::address::AztecAddress, state_vars::{PublicImmutable, SharedMutable}, - macros::{storage::storage, functions::{private, public, initializer, view}} + macros::{storage::storage, functions::{private, public, initializer, view}}, }; // Authorizing a new address has a certain block delay before it goes into effect. @@ -52,7 +52,8 @@ contract Auth { #[view] fn get_scheduled_authorized() -> AztecAddress { // docs:start:shared_mutable_get_scheduled_public - let (scheduled_value, _block_of_change): (AztecAddress, u32) = storage.authorized.get_scheduled_value_in_public(); + let (scheduled_value, _block_of_change): (AztecAddress, u32) = + storage.authorized.get_scheduled_value_in_public(); // docs:end:shared_mutable_get_scheduled_public scheduled_value } diff --git a/noir-projects/noir-contracts/contracts/auth_contract/src/test/main.nr b/noir-projects/noir-contracts/contracts/auth_contract/src/test/main.nr index e6caadb3e9b..93b094faa70 100644 --- a/noir-projects/noir-contracts/contracts/auth_contract/src/test/main.nr +++ b/noir-projects/noir-contracts/contracts/auth_contract/src/test/main.nr @@ -29,7 +29,8 @@ unconstrained fn main() { Auth::at(auth_contract_address).set_authorized(to_authorize).call(&mut env.public()); env.advance_block_by(1); - let scheduled_authorized = Auth::at(auth_contract_address).get_scheduled_authorized().view(&mut env.public()); + let scheduled_authorized = + Auth::at(auth_contract_address).get_scheduled_authorized().view(&mut env.public()); assert_eq(scheduled_authorized, to_authorize); }; admin_sets_authorized(); @@ -51,7 +52,8 @@ unconstrained fn main() { let authorized = Auth::at(auth_contract_address).get_authorized().view(&mut env.public()); assert_eq(authorized, to_authorize); - let authorized_in_private: AztecAddress = Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); + let authorized_in_private: AztecAddress = + Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); assert_eq(authorized_in_private, AztecAddress::zero()); // We need to always advance the block one more time to get the current value in private, compared to the value in public. @@ -73,7 +75,8 @@ unconstrained fn main() { // ^ // get_authorized() (private) called here with block_number = 8 env.advance_block_by(1); - let authorized_in_private_again = Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); + let authorized_in_private_again = + Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); assert_eq(authorized_in_private_again, to_authorize); Auth::at(auth_contract_address).do_private_authorized_thing().call(&mut env.private()); @@ -85,10 +88,12 @@ unconstrained fn main() { Auth::at(auth_contract_address).set_authorized(other).call(&mut env.public()); env.advance_block_by(1); - let scheduled_authorized = Auth::at(auth_contract_address).get_scheduled_authorized().view(&mut env.public()); + let scheduled_authorized = + Auth::at(auth_contract_address).get_scheduled_authorized().view(&mut env.public()); assert_eq(scheduled_authorized, other); - let authorized: AztecAddress = Auth::at(auth_contract_address).get_authorized().view(&mut env.public()); + let authorized: AztecAddress = + Auth::at(auth_contract_address).get_authorized().view(&mut env.public()); assert_eq(authorized, to_authorize); env.impersonate(to_authorize); @@ -107,11 +112,13 @@ unconstrained fn main() { let authorized = Auth::at(auth_contract_address).get_authorized().view(&mut env.public()); assert_eq(authorized, other); - let authorized_in_private = Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); + let authorized_in_private = + Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); assert_eq(authorized_in_private, to_authorize); env.advance_block_by(1); - let authorized_in_private_again = Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); + let authorized_in_private_again = + Auth::at(auth_contract_address).get_authorized_in_private().view(&mut env.private()); assert_eq(authorized_in_private_again, other); env.assert_private_call_fails(Auth::at(auth_contract_address).do_private_authorized_thing()); diff --git a/noir-projects/noir-contracts/contracts/auth_contract/src/test/utils.nr b/noir-projects/noir-contracts/contracts/auth_contract/src/test/utils.nr index 9b1d920a2a1..3ba53d12941 100644 --- a/noir-projects/noir-contracts/contracts/auth_contract/src/test/utils.nr +++ b/noir-projects/noir-contracts/contracts/auth_contract/src/test/utils.nr @@ -11,7 +11,8 @@ pub unconstrained fn setup() -> (&mut TestEnvironment, AztecAddress, AztecAddres let initializer_call_interface = Auth::interface().constructor(admin); - let auth_contract = env.deploy_self("Auth").with_public_void_initializer(initializer_call_interface); + let auth_contract = + env.deploy_self("Auth").with_public_void_initializer(initializer_call_interface); let auth_contract_address = auth_contract.to_address(); env.advance_block_by(1); (&mut env, auth_contract_address, admin, to_authorize, other) diff --git a/noir-projects/noir-contracts/contracts/auth_registry_contract/src/main.nr b/noir-projects/noir-contracts/contracts/auth_registry_contract/src/main.nr index 74e7e14cd0e..e21398eefcc 100644 --- a/noir-projects/noir-contracts/contracts/auth_registry_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/auth_registry_contract/src/main.nr @@ -4,15 +4,17 @@ use dep::aztec::macros::aztec; contract AuthRegistry { use dep::aztec::{ state_vars::{PublicMutable, Map}, protocol_types::address::AztecAddress, - macros::{storage::storage, functions::{private, public, internal, view}} + macros::{storage::storage, functions::{private, public, internal, view}}, + }; + use dep::authwit::auth::{ + IS_VALID_SELECTOR, compute_authwit_message_hash, assert_current_call_valid_authwit, }; - use dep::authwit::auth::{IS_VALID_SELECTOR, compute_authwit_message_hash, assert_current_call_valid_authwit}; #[storage] struct Storage { - reject_all: Map, Context>, - // on_behalf_of => authwit hash => authorized - approved_actions: Map, Context>, Context>, + reject_all: Map, Context>, + // on_behalf_of => authwit hash => authorized + approved_actions: Map, Context>, Context>, } /** @@ -56,7 +58,7 @@ contract AuthRegistry { context.msg_sender(), context.chain_id(), context.version(), - inner_hash + inner_hash, ); let authorized = storage.approved_actions.at(on_behalf_of).at(message_hash).read(); @@ -81,7 +83,9 @@ contract AuthRegistry { #[private] fn set_authorized_private(approver: AztecAddress, message_hash: Field, authorize: bool) { assert_current_call_valid_authwit(&mut context, approver); - AuthRegistry::at(context.this_address())._set_authorized(approver, message_hash, authorize).enqueue(&mut context); + AuthRegistry::at(context.this_address()) + ._set_authorized(approver, message_hash, authorize) + .enqueue(&mut context); } /** @@ -123,7 +127,10 @@ contract AuthRegistry { storage.approved_actions.at(on_behalf_of).at(message_hash).read() } - unconstrained fn unconstrained_is_consumable(on_behalf_of: AztecAddress, message_hash: Field) -> pub bool { + unconstrained fn unconstrained_is_consumable( + on_behalf_of: AztecAddress, + message_hash: Field, + ) -> pub bool { storage.approved_actions.at(on_behalf_of).at(message_hash).read() } } diff --git a/noir-projects/noir-contracts/contracts/auth_wit_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/auth_wit_test_contract/src/main.nr index 8fbf2ba8c82..eb317769c20 100644 --- a/noir-projects/noir-contracts/contracts/auth_wit_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/auth_wit_test_contract/src/main.nr @@ -2,9 +2,11 @@ use dep::aztec::macros::aztec; #[aztec] contract AuthWitTest { - use dep::aztec::{protocol_types::address::AztecAddress, macros::{functions::{private, public}}}; + use dep::aztec::{protocol_types::address::AztecAddress, macros::functions::{private, public}}; - use dep::authwit::auth::{assert_inner_hash_valid_authwit, assert_inner_hash_valid_authwit_public}; + use dep::authwit::auth::{ + assert_inner_hash_valid_authwit, assert_inner_hash_valid_authwit_public, + }; #[private] fn consume(on_behalf_of: AztecAddress, inner_hash: Field) { diff --git a/noir-projects/noir-contracts/contracts/avm_initializer_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_initializer_test_contract/src/main.nr index 8c74544a783..463e17c5030 100644 --- a/noir-projects/noir-contracts/contracts/avm_initializer_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_initializer_test_contract/src/main.nr @@ -3,7 +3,9 @@ use dep::aztec::macros::aztec; #[aztec] contract AvmInitializerTest { // Libs - use dep::aztec::{state_vars::PublicImmutable, macros::{storage::storage, functions::{initializer, public}}}; + use dep::aztec::{ + state_vars::PublicImmutable, macros::{storage::storage, functions::{initializer, public}}, + }; #[storage] struct Storage { diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index 0beac70ca72..ff31737f6ab 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -25,16 +25,23 @@ contract AvmTest { global big_field_128_bits: Field = 0x001234567890abcdef1234567890abcdef; global big_field_136_bits: Field = 0x991234567890abcdef1234567890abcdef; - global big_field_254_bits: Field = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef; + global big_field_254_bits: Field = + 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef; // Libs use std::embedded_curve_ops::{multi_scalar_mul, EmbeddedCurvePoint}; use dep::aztec::protocol_types::constants::CONTRACT_INSTANCE_LENGTH; use dep::aztec::prelude::Map; use dep::aztec::state_vars::PublicMutable; - use dep::aztec::protocol_types::{address::{AztecAddress, EthAddress}, point::Point, scalar::Scalar}; - use dep::aztec::oracle::get_contract_instance::{get_contract_instance_avm, get_contract_instance_internal_avm}; - use dep::aztec::protocol_types::{abis::function_selector::FunctionSelector, storage::map::derive_storage_slot_in_map}; + use dep::aztec::protocol_types::{ + address::{AztecAddress, EthAddress}, point::Point, scalar::Scalar, + }; + use dep::aztec::oracle::get_contract_instance::{ + get_contract_instance_avm, get_contract_instance_internal_avm, + }; + use dep::aztec::protocol_types::{ + abis::function_selector::FunctionSelector, storage::map::derive_storage_slot_in_map, + }; use dep::compressed_string::CompressedString; use dep::aztec::macros::{storage::storage, functions::{public, private}}; use dep::aztec::context::gas::GasOpts; @@ -152,7 +159,11 @@ contract AvmTest { #[public] fn elliptic_curve_add_and_double() -> Point { - let g = Point { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let g = Point { + x: 1, + y: 17631683881184975370165255887551781615748388533673675138860, + is_infinite: false, + }; let doubled = g + g; let added = g + doubled; @@ -161,7 +172,11 @@ contract AvmTest { #[public] fn variable_base_msm() -> Point { - let g = Point { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let g = Point { + x: 1, + y: 17631683881184975370165255887551781615748388533673675138860, + is_infinite: false, + }; let scalar = Scalar { lo: 3, hi: 0 }; let scalar2 = Scalar { lo: 20, hi: 0 }; let triple_g = multi_scalar_mul([g, g], [scalar, scalar2]); @@ -193,7 +208,7 @@ contract AvmTest { #[public] fn to_radix_le(input: Field) -> [u8; 10] { - input.to_le_radix(/*base=*/ 2) + input.to_le_radix( /*base=*/ 2) } // Helper functions to demonstrate an internal call stack in error messages @@ -267,7 +282,7 @@ contract AvmTest { #[public] fn pedersen_hash_with_index(data: [Field; 10]) -> Field { - std::hash::pedersen_hash_with_separator(data, /*index=*/ 20) + std::hash::pedersen_hash_with_separator(data, /*index=*/ 20) } /************************************************************************ @@ -375,9 +390,8 @@ contract AvmTest { #[public] fn check_selector() { assert( - context.selector() == comptime { - FunctionSelector::from_signature("check_selector()") - }, "Unexpected selector!" + context.selector() == comptime { FunctionSelector::from_signature("check_selector()") }, + "Unexpected selector!", ); } @@ -388,10 +402,11 @@ contract AvmTest { #[public] fn emit_unencrypted_log() { - context.emit_unencrypted_log(/*message=*/ [10, 20, 30]); - context.emit_unencrypted_log(/*message=*/ "Hello, world!"); - let s: CompressedString<2,44> = CompressedString::from_string("A long time ago, in a galaxy far far away..."); - context.emit_unencrypted_log(/*message=*/ s); + context.emit_unencrypted_log( /*message=*/ [10, 20, 30]); + context.emit_unencrypted_log( /*message=*/ "Hello, world!"); + let s: CompressedString<2, 44> = + CompressedString::from_string("A long time ago, in a galaxy far far away..."); + context.emit_unencrypted_log( /*message=*/ s); } #[public] @@ -419,7 +434,10 @@ contract AvmTest { #[public] fn assert_nullifier_exists(nullifier: Field) { - assert(context.nullifier_exists(nullifier, context.this_address()), "Nullifier doesn't exist!"); + assert( + context.nullifier_exists(nullifier, context.this_address()), + "Nullifier doesn't exist!", + ); } // Use the standard context interface to emit a new nullifier @@ -456,9 +474,12 @@ contract AvmTest { arg_a: Field, arg_b: Field, l2_gas: Field, - da_gas: Field + da_gas: Field, ) -> pub Field { - AvmTest::at(context.this_address()).add_args_return(arg_a, arg_b).with_gas(GasOpts::new(l2_gas, da_gas)).call(&mut context) + AvmTest::at(context.this_address()) + .add_args_return(arg_a, arg_b) + .with_gas(GasOpts::new(l2_gas, da_gas)) + .call(&mut context) } // Use the `call_public_function` wrapper to initiate a nested call to the add function diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr index 9d00224d299..ded14bb8b76 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/cards.nr @@ -2,9 +2,10 @@ use dep::aztec::prelude::{AztecAddress, PrivateContext, NoteGetterOptions, NoteV use dep::aztec::{ context::UnconstrainedContext, - protocol_types::{traits::{ToField, Serialize, FromField}, constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL}, - encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, - state_vars::PrivateSet, note::constants::MAX_NOTES_PER_PAGE + protocol_types::{ + traits::{ToField, Serialize, FromField}, constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, + }, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + keys::getters::get_public_keys, state_vars::PrivateSet, note::constants::MAX_NOTES_PER_PAGE, }; use dep::value_note::value_note::ValueNote; @@ -70,7 +71,7 @@ pub struct Deck { pub fn filter_cards( notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - desired_cards: [Card; N] + desired_cards: [Card; N], ) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] { let mut selected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; @@ -112,7 +113,12 @@ impl Deck<&mut PrivateContext> { let mut inserted_cards = &[]; for card in cards { let mut card_note = CardNote::from_card(card, owner_npk_m_hash); - self.set.insert(&mut card_note.note).emit(encode_and_encrypt_note(self.set.context, msg_sender_ovpk_m, owner_ivpk_m, owner)); + self.set.insert(&mut card_note.note).emit(encode_and_encrypt_note( + self.set.context, + msg_sender_ovpk_m, + owner_ivpk_m, + owner, + )); inserted_cards = inserted_cards.push_back(card_note); } @@ -148,7 +154,7 @@ global PACK_CARDS = 3; // Limited by number of write requests (max 4) pub fn get_pack_cards( seed: Field, owner: AztecAddress, - context: &mut PrivateContext + context: &mut PrivateContext, ) -> [Card; PACK_CARDS] { let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); @@ -164,19 +170,12 @@ pub fn get_pack_cards( for i in 0..PACK_CARDS { let strength = (random_bytes[i] as u32) + (random_bytes[i + 1] as u32) * 256; let points = (random_bytes[i + 2] as u32) + (random_bytes[i + 3] as u32) * 256; - cards[i] = Card { - strength, points - }; + cards[i] = Card { strength, points }; } cards } pub fn compute_deck_strength(cards: [Card; N]) -> Field { - cards.fold( - 0, - |acc, card: Card| { - acc + card.strength as Field - } - ) + cards.fold(0, |acc, card: Card| { acc + card.strength as Field }) } diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/game.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/game.nr index 49c55c12c32..01991ddf74d 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/game.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/game.nr @@ -67,7 +67,7 @@ impl Serialize for Game { game.finished as Field, game.claimed as Field, game.current_player as Field, - game.current_round as Field + game.current_round as Field, ] } } @@ -79,8 +79,10 @@ impl Deserialize for Game { let players = [player1, player2]; let rounds_cards = [ - Card::from_field(fields[6]), Card::from_field(fields[7]), - Card::from_field(fields[8]), Card::from_field(fields[9]) + Card::from_field(fields[6]), + Card::from_field(fields[7]), + Card::from_field(fields[8]), + Card::from_field(fields[9]), ]; Game { players, @@ -89,7 +91,7 @@ impl Deserialize for Game { finished: fields[11] as bool, claimed: fields[12] as bool, current_player: fields[13] as u32, - current_round: fields[14] as u32 + current_round: fields[14] as u32, } } } @@ -117,7 +119,9 @@ impl Game { let entry = self.players[i]; assert(entry.is_initialized(), "Game not full"); } - let sorted_by_deck_strength = self.players.sort_via(|a: PlayerEntry, b: PlayerEntry| a.deck_strength < b.deck_strength); + let sorted_by_deck_strength = self.players.sort_via(|a: PlayerEntry, b: PlayerEntry| { + a.deck_strength < b.deck_strength + }); self.players = sorted_by_deck_strength; self.started = true; } diff --git a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr index 095f870193b..2cdb926ac63 100644 --- a/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/card_game_contract/src/main.nr @@ -22,7 +22,8 @@ contract CardGame { } #[private] - fn buy_pack(seed: Field // The randomness used to generate the cards. Passed in for now. + fn buy_pack( + seed: Field, // The randomness used to generate the cards. Passed in for now. ) { let buyer = context.msg_sender(); let mut cards = get_pack_cards(seed, buyer, &mut context); @@ -42,7 +43,9 @@ contract CardGame { let mut game_deck = storage.game_decks.at(game as Field).at(player); let _added_to_game_deck = game_deck.add_cards(cards, player); let strength = compute_deck_strength(cards); - CardGame::at(context.this_address()).on_game_joined(game, player, strength as u32).enqueue(&mut context); + CardGame::at(context.this_address()).on_game_joined(game, player, strength as u32).enqueue( + &mut context, + ); } #[public] @@ -51,7 +54,10 @@ contract CardGame { let game_storage = storage.games.at(game as Field); let mut game_data = game_storage.read(); - assert(game_data.add_player(PlayerEntry { address: player, deck_strength, points: 0 }), "Game full"); + assert( + game_data.add_player(PlayerEntry { address: player, deck_strength, points: 0 }), + "Game full", + ); game_storage.write(game_data); } @@ -73,7 +79,9 @@ contract CardGame { game_deck.remove_cards([card]); // docs:start:call_public_function - CardGame::at(context.this_address()).on_card_played(game, player, card.to_field()).enqueue(&mut context); + CardGame::at(context.this_address()).on_card_played(game, player, card.to_field()).enqueue( + &mut context, + ); // docs:end:call_public_function } @@ -99,7 +107,9 @@ contract CardGame { let mut collection = storage.collections.at(player); let _inserted_cards = collection.add_cards(cards, player); - CardGame::at(context.this_address()).on_cards_claimed(game, player, pedersen_hash(cards_fields, 0)).enqueue(&mut context); + CardGame::at(context.this_address()) + .on_cards_claimed(game, player, pedersen_hash(cards_fields, 0)) + .enqueue(&mut context); } #[public] @@ -111,7 +121,10 @@ contract CardGame { assert(!game_data.claimed, "Already claimed"); game_data.claimed = true; - assert_eq(cards_hash, pedersen_hash(game_data.rounds_cards.map(|card: Card| card.to_field()), 0)); + assert_eq( + cards_hash, + pedersen_hash(game_data.rounds_cards.map(|card: Card| card.to_field()), 0), + ); let winner = game_data.winner(); assert(player.eq(winner.address), "Not the winner"); @@ -119,12 +132,19 @@ contract CardGame { game_storage.write(game_data); } - unconstrained fn view_collection_cards(owner: AztecAddress, offset: u32) -> pub BoundedVec { + unconstrained fn view_collection_cards( + owner: AztecAddress, + offset: u32, + ) -> pub BoundedVec { let collection = storage.collections.at(owner); collection.view_cards(offset) } - unconstrained fn view_game_cards(game: u32, player: AztecAddress, offset: u32) -> pub BoundedVec { + unconstrained fn view_game_cards( + game: u32, + player: AztecAddress, + offset: u32, + ) -> pub BoundedVec { let game_deck = storage.game_decks.at(game as Field).at(player); game_deck.view_cards(offset) diff --git a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr index 04a90c9a08d..7e97d112e5f 100644 --- a/noir-projects/noir-contracts/contracts/child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/child_contract/src/main.nr @@ -6,10 +6,10 @@ contract Child { use dep::aztec::prelude::{AztecAddress, PublicMutable, PrivateSet, Map}; use dep::aztec::{ - note::{note_getter_options::NoteGetterOptions}, + note::note_getter_options::NoteGetterOptions, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, utils::comparison::Comparator, - macros::{storage::storage, functions::{private, public, internal}} + macros::{storage::storage, functions::{private, public, internal}}, }; use dep::value_note::value_note::ValueNote; @@ -58,7 +58,12 @@ contract Child { let owner_keys = get_public_keys(owner); let mut note = ValueNote::new(new_value, owner_keys.npk_m.hash()); - storage.a_map_with_private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note(&mut context, owner_keys.ovpk_m, owner_keys.ivpk_m, owner)); + storage.a_map_with_private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + owner_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); new_value } diff --git a/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr b/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr index 93d42b7e9ee..0d7259d168c 100644 --- a/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/claim_contract/src/main.nr @@ -5,17 +5,17 @@ contract Claim { use dep::aztec::{ note::utils::compute_note_hash_for_nullify, protocol_types::address::AztecAddress, state_vars::SharedImmutable, - macros::{storage::storage, functions::{private, public, initializer}} + macros::{storage::storage, functions::{private, public, initializer}}, }; use dep::value_note::value_note::ValueNote; use token::Token; #[storage] struct Storage { - // Address of a contract based on whose notes we distribute the rewards - target_contract: SharedImmutable, - // Token to be distributed as a reward when claiming - reward_token: SharedImmutable, + // Address of a contract based on whose notes we distribute the rewards + target_contract: SharedImmutable, + // Token to be distributed as a reward when claiming + reward_token: SharedImmutable, } #[public] @@ -30,7 +30,8 @@ contract Claim { // 1) Check that the note corresponds to the target contract and belongs to the sender let target_address = storage.target_contract.read_private(); assert( - target_address == proof_note.header.contract_address, "Note does not correspond to the target contract" + target_address == proof_note.header.contract_address, + "Note does not correspond to the target contract", ); // 2) Prove that the note hash exists in the note hash tree @@ -49,6 +50,8 @@ contract Claim { context.push_nullifier(nullifier); // 4) Finally we mint the reward token to the sender of the transaction - Token::at(storage.reward_token.read_private()).mint_public(recipient, proof_note.value).enqueue(&mut context); + Token::at(storage.reward_token.read_private()) + .mint_public(recipient, proof_note.value) + .enqueue(&mut context); } } diff --git a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/capsule.nr b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/capsule.nr index 8b5ef24bbda..0e4d3a9c44c 100644 --- a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/capsule.nr +++ b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/capsule.nr @@ -8,4 +8,4 @@ unconstrained fn pop_capsule_oracle() -> [Field; N] {} pub unconstrained fn pop_capsule() -> [Field; N] { pop_capsule_oracle() } -// docs:end:pop_capsule \ No newline at end of file +// docs:end:pop_capsule diff --git a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/class_registered.nr b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/class_registered.nr index 3a67ffbf2e0..f89db47b7bd 100644 --- a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/class_registered.nr +++ b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/class_registered.nr @@ -1,7 +1,8 @@ use dep::aztec::protocol_types::{ contract_class_id::ContractClassId, - constants::{MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE}, - traits::Serialize + constants::{ + MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE, + }, traits::Serialize, }; // #[event] diff --git a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr index b9889efc89d..7a542059f9b 100644 --- a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr +++ b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/events/private_function_broadcasted.nr @@ -2,12 +2,11 @@ use dep::aztec::prelude::FunctionSelector; use dep::aztec::protocol_types::{ contract_class_id::ContractClassId, constants::{ - FUNCTION_TREE_HEIGHT, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, - MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE, - REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS -}, - traits::Serialize + FUNCTION_TREE_HEIGHT, ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, + MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE, + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS, + }, traits::Serialize, }; pub struct InnerPrivateFunction { @@ -30,7 +29,9 @@ pub struct PrivateFunction { } impl Serialize for PrivateFunction { - fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + 3] { + fn serialize( + self: Self, + ) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + 3] { let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + 3]; packed[0] = self.selector.to_field(); packed[1] = self.metadata_hash; @@ -51,13 +52,17 @@ pub struct ClassPrivateFunctionBroadcasted { private_function_tree_leaf_index: Field, artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT], artifact_function_tree_leaf_index: Field, - function: PrivateFunction + function: PrivateFunction, } impl Serialize for ClassPrivateFunctionBroadcasted { - fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] { - let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS - + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS]; + fn serialize( + self: Self, + ) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] { + let mut packed = [ + 0; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS + + REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS + ]; packed[0] = REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE; packed[1] = self.contract_class_id.to_field(); packed[2] = self.artifact_metadata_hash; @@ -69,10 +74,12 @@ impl Serialize for UnconstrainedFunction { - fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + 2] { + fn serialize( + self: Self, + ) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + 2] { let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + 2]; packed[0] = self.selector.to_field(); packed[1] = self.metadata_hash; @@ -45,13 +47,17 @@ pub struct ClassUnconstrainedFunctionBroadcasted { private_functions_artifact_tree_root: Field, artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT], artifact_function_tree_leaf_index: Field, - function: UnconstrainedFunction + function: UnconstrainedFunction, } impl Serialize for ClassUnconstrainedFunctionBroadcasted { - fn serialize(self: Self) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] { - let mut packed = [0; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS - + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS]; + fn serialize( + self: Self, + ) -> [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS] { + let mut packed = [ + 0; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS + + REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS + ]; packed[0] = REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE; packed[1] = self.contract_class_id.to_field(); packed[2] = self.artifact_metadata_hash; diff --git a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/main.nr b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/main.nr index 3112cd5dbcf..4a20582ea6e 100644 --- a/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/main.nr @@ -8,23 +8,27 @@ contract ContractClassRegisterer { use dep::aztec::protocol_types::{ contract_class_id::ContractClassId, constants::{ - ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, FUNCTION_TREE_HEIGHT, - MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, - MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS, - MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS - }, - abis::log_hash::LogHash + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, FUNCTION_TREE_HEIGHT, + MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS, + MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS, + MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, + }, abis::log_hash::LogHash, }; use dep::aztec::{ context::PrivateContext, oracle::logs::emit_contract_class_unencrypted_log_private, - macros::functions::private + macros::functions::private, }; use crate::events::{ class_registered::ContractClassRegistered, - private_function_broadcasted::{ClassPrivateFunctionBroadcasted, PrivateFunction, InnerPrivateFunction}, - unconstrained_function_broadcasted::{ClassUnconstrainedFunctionBroadcasted, UnconstrainedFunction, InnerUnconstrainedFunction} + private_function_broadcasted::{ + ClassPrivateFunctionBroadcasted, PrivateFunction, InnerPrivateFunction, + }, + unconstrained_function_broadcasted::{ + ClassUnconstrainedFunctionBroadcasted, UnconstrainedFunction, + InnerUnconstrainedFunction, + }, }; // docs:start:import_pop_capsule @@ -32,34 +36,43 @@ contract ContractClassRegisterer { // docs:end:import_pop_capsule #[private] - fn register(artifact_hash: Field, private_functions_root: Field, public_bytecode_commitment: Field) { + fn register( + artifact_hash: Field, + private_functions_root: Field, + public_bytecode_commitment: Field, + ) { // TODO: Validate public_bytecode_commitment is the correct commitment of packed_public_bytecode // TODO: Validate packed_public_bytecode is legit public bytecode - // docs:start:pop_capsule - let packed_public_bytecode: [Field; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS] = pop_capsule(); + let packed_public_bytecode: [Field; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS] = + pop_capsule(); // docs:end:pop_capsule - // Compute contract class id from preimage let contract_class_id = ContractClassId::compute( artifact_hash, private_functions_root, - public_bytecode_commitment + public_bytecode_commitment, ); // Emit the contract class id as a nullifier to be able to prove that this class has been (not) registered - let event = ContractClassRegistered { contract_class_id, version: 1, artifact_hash, private_functions_root, packed_public_bytecode }; + let event = ContractClassRegistered { + contract_class_id, + version: 1, + artifact_hash, + private_functions_root, + packed_public_bytecode, + }; context.push_nullifier(contract_class_id.to_field()); // Broadcast class info including public bytecode dep::aztec::oracle::debug_log::debug_log_format( "ContractClassRegistered: {}", [ - contract_class_id.to_field(), - artifact_hash, - private_functions_root, - public_bytecode_commitment - ] + contract_class_id.to_field(), + artifact_hash, + private_functions_root, + public_bytecode_commitment, + ], ); emit_contract_class_unencrypted_log(&mut context, event.serialize()); } @@ -73,9 +86,10 @@ contract ContractClassRegisterer { private_function_tree_leaf_index: Field, artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT], artifact_function_tree_leaf_index: Field, - function_data: InnerPrivateFunction + function_data: InnerPrivateFunction, ) { - let private_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS] = pop_capsule(); + let private_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS] = + pop_capsule(); let event = ClassPrivateFunctionBroadcasted { contract_class_id, @@ -89,19 +103,19 @@ contract ContractClassRegisterer { selector: function_data.selector, metadata_hash: function_data.metadata_hash, vk_hash: function_data.vk_hash, - bytecode: private_bytecode - } + bytecode: private_bytecode, + }, }; dep::aztec::oracle::debug_log::debug_log_format( "ClassPrivateFunctionBroadcasted: {}", [ - contract_class_id.to_field(), - artifact_metadata_hash, - unconstrained_functions_artifact_tree_root, - function_data.selector.to_field(), - function_data.vk_hash, - function_data.metadata_hash - ] + contract_class_id.to_field(), + artifact_metadata_hash, + unconstrained_functions_artifact_tree_root, + function_data.selector.to_field(), + function_data.vk_hash, + function_data.metadata_hash, + ], ); emit_contract_class_unencrypted_log(&mut context, event.serialize()); } @@ -113,9 +127,10 @@ contract ContractClassRegisterer { private_functions_artifact_tree_root: Field, artifact_function_tree_sibling_path: [Field; ARTIFACT_FUNCTION_TREE_MAX_HEIGHT], artifact_function_tree_leaf_index: Field, - function_data: InnerUnconstrainedFunction + function_data: InnerUnconstrainedFunction, ) { - let unconstrained_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS] = pop_capsule(); + let unconstrained_bytecode: [Field; MAX_PACKED_BYTECODE_SIZE_PER_UNCONSTRAINED_FUNCTION_IN_FIELDS] = + pop_capsule(); let event = ClassUnconstrainedFunctionBroadcasted { contract_class_id, artifact_metadata_hash, @@ -125,24 +140,27 @@ contract ContractClassRegisterer { function: UnconstrainedFunction { selector: function_data.selector, metadata_hash: function_data.metadata_hash, - bytecode: unconstrained_bytecode - } + bytecode: unconstrained_bytecode, + }, }; dep::aztec::oracle::debug_log::debug_log_format( "ClassUnconstrainedFunctionBroadcasted: {}", [ - contract_class_id.to_field(), - artifact_metadata_hash, - private_functions_artifact_tree_root, - function_data.selector.to_field(), - function_data.metadata_hash - ] + contract_class_id.to_field(), + artifact_metadata_hash, + private_functions_artifact_tree_root, + function_data.selector.to_field(), + function_data.metadata_hash, + ], ); emit_contract_class_unencrypted_log(&mut context, event.serialize()); } #[contract_library_method] - fn emit_contract_class_unencrypted_log(context: &mut PrivateContext, log: [Field; N]) { + fn emit_contract_class_unencrypted_log( + context: &mut PrivateContext, + log: [Field; N], + ) { let contract_address = context.this_address(); let counter = context.next_counter(); @@ -159,6 +177,8 @@ contract ContractClassRegisterer { let log_hash = emit_contract_class_unencrypted_log_private(contract_address, log, counter); // 40 = addr (32) + raw log len (4) + processed log len (4) - context.unencrypted_logs_hashes.push(LogHash { value: log_hash, counter, length: 40 + (N as Field) * 32 }); + context.unencrypted_logs_hashes.push( + LogHash { value: log_hash, counter, length: 40 + (N as Field) * 32 }, + ); } } diff --git a/noir-projects/noir-contracts/contracts/contract_instance_deployer_contract/src/main.nr b/noir-projects/noir-contracts/contracts/contract_instance_deployer_contract/src/main.nr index 545365fa956..6ffb083f264 100644 --- a/noir-projects/noir-contracts/contracts/contract_instance_deployer_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/contract_instance_deployer_contract/src/main.nr @@ -4,12 +4,13 @@ use dep::aztec::macros::aztec; contract ContractInstanceDeployer { use dep::aztec::protocol_types::{ address::{AztecAddress, PublicKeysHash, PartialAddress}, public_keys::PublicKeys, - contract_class_id::ContractClassId, constants::DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE, - abis::log_hash::LogHash, traits::Serialize + contract_class_id::ContractClassId, + constants::DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE, abis::log_hash::LogHash, + traits::Serialize, }; use dep::aztec::{ hash::compute_unencrypted_log_hash, oracle::logs::emit_unencrypted_log_private, - macros::{events::event, functions::private}, utils::to_bytes::arr_to_be_bytes_arr + macros::{events::event, functions::private}, utils::to_bytes::arr_to_be_bytes_arr, }; use std::meta::derive; @@ -70,7 +71,7 @@ contract ContractInstanceDeployer { self.public_keys.ovpk_m.serialize()[1], self.public_keys.tpk_m.serialize()[0], self.public_keys.tpk_m.serialize()[1], - self.deployer.to_field() + self.deployer.to_field(), ] } } @@ -81,17 +82,17 @@ contract ContractInstanceDeployer { contract_class_id: ContractClassId, initialization_hash: Field, public_keys: PublicKeys, - universal_deploy: bool + universal_deploy: bool, ) { // TODO(@spalladino): assert nullifier_exists silo(contract_class_id, ContractClassRegisterer) - let deployer = if universal_deploy { AztecAddress::zero() } else { context.msg_sender() }; - let partial_address = PartialAddress::compute(contract_class_id, salt, initialization_hash, deployer); + let partial_address = + PartialAddress::compute(contract_class_id, salt, initialization_hash, deployer); let address = AztecAddress::compute(public_keys.hash(), partial_address); @@ -107,7 +108,7 @@ contract ContractInstanceDeployer { initialization_hash, salt, deployer, - version: 1 + version: 1, }; let payload = event.serialize(); diff --git a/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr b/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr index eea5601b734..ba0824ab138 100644 --- a/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/counter_contract/src/main.nr @@ -32,7 +32,10 @@ contract Counter { #[private] fn increment(owner: AztecAddress, outgoing_viewer: AztecAddress) { unsafe { - dep::aztec::oracle::debug_log::debug_log_format("Incrementing counter for owner {0}", [owner.to_field()]); + dep::aztec::oracle::debug_log::debug_log_format( + "Incrementing counter for owner {0}", + [owner.to_field()], + ); } let counters = storage.counters; counters.at(owner).add(1, owner, outgoing_viewer); @@ -46,7 +49,7 @@ contract Counter { // docs:end:get_counter // docs:start:test_imports - use dep::aztec::test::{helpers::{cheatcodes, test_environment::TestEnvironment}}; + use dep::aztec::test::helpers::{cheatcodes, test_environment::TestEnvironment}; use dep::aztec::protocol_types::storage::map::derive_storage_slot_in_map; use dep::aztec::note::note_getter::{MAX_NOTES_PER_PAGE, view_notes}; use dep::aztec::note::note_viewer_options::NoteViewerOptions; @@ -61,7 +64,8 @@ contract Counter { let initial_value: Field = 5; env.impersonate(owner); // Deploy contract and initialize - let initializer = Counter::interface().initialize(initial_value as u64, owner, outgoing_viewer); + let initializer = + Counter::interface().initialize(initial_value as u64, owner, outgoing_viewer); let counter_contract = env.deploy_self("Counter").with_private_initializer(initializer); let contract_address = counter_contract.to_address(); // docs:start:txe_test_read_notes @@ -73,7 +77,8 @@ contract Counter { let notes: BoundedVec = view_notes(owner_slot, options); let initial_note_value = notes.get(0).value; assert( - initial_note_value == initial_value, f"Expected {initial_value} but got {initial_note_value}" + initial_note_value == initial_value, + f"Expected {initial_value} but got {initial_note_value}", ); // docs:end:txe_test_read_notes // Increment the counter @@ -82,7 +87,8 @@ contract Counter { let current_value_for_owner = get_counter(owner); let expected_current_value = initial_value + 1; assert( - expected_current_value == current_value_for_owner, f"Expected {expected_current_value} but got {current_value_for_owner}" + expected_current_value == current_value_for_owner, + f"Expected {expected_current_value} but got {current_value_for_owner}", ); } // docs:end:txe_test_increment diff --git a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr index a6c6b183041..a2304487c59 100644 --- a/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/crowdfunding_contract/src/main.nr @@ -10,8 +10,9 @@ contract Crowdfunding { encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, prelude::{AztecAddress, PrivateSet, SharedImmutable}, utils::comparison::Comparator, unencrypted_logs::unencrypted_event_emission::encode_event, - macros::{storage::storage, events::event, functions::{public, initializer, private, internal}}, - protocol_types::traits::Serialize + macros::{ + storage::storage, events::event, functions::{public, initializer, private, internal}, + }, protocol_types::traits::Serialize, }; use std::meta::derive; // docs:start:import_valuenote @@ -67,20 +68,25 @@ contract Crowdfunding { let deadline = storage.deadline.read_private(); privately_check_timestamp(Comparator.LT, deadline, &mut context); // docs:end:call-check-deadline - // docs:start:do-transfer // 2) Transfer the donation tokens from donor to this contract let donor = context.msg_sender(); - Token::at(storage.donation_token.read_private()).transfer_from(donor, context.this_address(), amount as Field, 0).call(&mut context); + Token::at(storage.donation_token.read_private()) + .transfer_from(donor, context.this_address(), amount as Field, 0) + .call(&mut context); // docs:end:do-transfer - // 3) Create a value note for the donor so that he can later on claim a rewards token in the Claim // contract by proving that the hash of this note exists in the note hash tree. let donor_keys = get_public_keys(donor); // docs:start:valuenote_new let mut note = ValueNote::new(amount as Field, donor_keys.npk_m.hash()); // docs:end:valuenote_new - storage.donation_receipts.insert(&mut note).emit(encode_and_encrypt_note(&mut context, donor_keys.ovpk_m, donor_keys.ivpk_m, donor)); + storage.donation_receipts.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + donor_keys.ovpk_m, + donor_keys.ivpk_m, + donor, + )); } // docs:end:donate @@ -93,9 +99,13 @@ contract Crowdfunding { assert(context.msg_sender() == operator_address, "Not an operator"); // 2) Transfer the donation tokens from this contract to the operator - Token::at(storage.donation_token.read_private()).transfer(operator_address, amount as Field).call(&mut context); + Token::at(storage.donation_token.read_private()) + .transfer(operator_address, amount as Field) + .call(&mut context); // 3) Emit an unencrypted event so that anyone can audit how much the operator has withdrawn - Crowdfunding::at(context.this_address())._publish_donation_receipts(amount, operator_address).enqueue(&mut context); + Crowdfunding::at(context.this_address()) + ._publish_donation_receipts(amount, operator_address) + .enqueue(&mut context); } // docs:end:operator-withdrawals diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index 99d6bb7a666..fd3e0194d57 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -18,12 +18,12 @@ contract DocsExample { // how to import dependencies defined in your workspace use dep::aztec::prelude::{ AztecAddress, NoteViewerOptions, PrivateContext, Map, PublicMutable, PublicImmutable, - PrivateMutable, PrivateImmutable, PrivateSet, SharedImmutable + PrivateMutable, PrivateImmutable, PrivateSet, SharedImmutable, }; use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, - macros::{storage::{storage, storage_no_init}, functions::{public, private, internal, view}} + macros::{storage::{storage, storage_no_init}, functions::{public, private, internal, view}}, }; // how to import methods from other files/folders within your workspace @@ -73,9 +73,7 @@ contract DocsExample { profiles: Map::new( context, 4, - |context, slot| { - PrivateMutable::new(context, slot) - } + |context, slot| { PrivateMutable::new(context, slot) }, ), // docs:end:state_vars-MapPrivateMutable // docs:start:storage-set-init @@ -87,13 +85,11 @@ contract DocsExample { minters: Map::new( context, 8, - |context, slot| { - PublicMutable::new(context, slot) - } + |context, slot| { PublicMutable::new(context, slot) }, ), // docs:end:storage-minters-init // docs:start:storage-public-immutable - public_immutable: PublicImmutable::new(context, 9)// docs:end:storage-public-immutable + public_immutable: PublicImmutable::new(context, 9), // docs:end:storage-public-immutable } } } @@ -119,7 +115,9 @@ contract DocsExample { // and returns the response. // Used to test that we can retrieve values through calls and // correctly return them in the simulation - let mut leader = DocsExample::at(context.this_address()).get_shared_immutable_constrained_private().view(&mut context); + let mut leader = DocsExample::at(context.this_address()) + .get_shared_immutable_constrained_private() + .view(&mut context); leader.points += 1; leader } @@ -130,7 +128,9 @@ contract DocsExample { // and returns the response. // Used to test that we can retrieve values through calls and // correctly return them in the simulation - let mut leader = DocsExample::at(context.this_address()).get_shared_immutable_constrained_public().view(&mut context); + let mut leader = DocsExample::at(context.this_address()) + .get_shared_immutable_constrained_public() + .view(&mut context); leader.points += 1; leader } @@ -177,14 +177,12 @@ contract DocsExample { let msg_sender_keys = get_public_keys(context.msg_sender()); let mut new_card = CardNote::new(points, randomness, msg_sender_keys.npk_m.hash()); - storage.private_immutable.initialize(&mut new_card).emit( - encode_and_encrypt_note( - &mut context, - msg_sender_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) - ); + storage.private_immutable.initialize(&mut new_card).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); } // docs:end:initialize-private-mutable @@ -195,14 +193,12 @@ contract DocsExample { let mut legendary_card = CardNote::new(points, randomness, msg_sender_keys.npk_m.hash()); // create and broadcast note - storage.legendary_card.initialize(&mut legendary_card).emit( - encode_and_encrypt_note( - &mut context, - msg_sender_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) - ); + storage.legendary_card.initialize(&mut legendary_card).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); } #[private] @@ -211,14 +207,12 @@ contract DocsExample { for i in 0..amounts.len() { let mut note = CardNote::new(amounts[i], 1, msg_sender_keys.npk_m.hash()); - storage.set.insert(&mut note).emit( - encode_and_encrypt_note( - &mut context, - msg_sender_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) - ); + storage.set.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); } } #[private] @@ -226,14 +220,12 @@ contract DocsExample { let msg_sender_keys = get_public_keys(context.msg_sender()); let mut note = CardNote::new(amount, randomness, msg_sender_keys.npk_m.hash()); - storage.set.insert(&mut note).emit( - encode_and_encrypt_note( - &mut context, - msg_sender_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) - ); + storage.set.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); } // docs:start:state_vars-NoteGetterOptionsComparatorExampleNoir unconstrained fn read_note(comparator: u8, amount: Field) -> BoundedVec { @@ -246,21 +238,20 @@ contract DocsExample { let msg_sender_keys = get_public_keys(context.msg_sender()); let mut new_card = CardNote::new(points, randomness, msg_sender_keys.npk_m.hash()); - storage.legendary_card.replace(&mut new_card).emit( - encode_and_encrypt_note( - &mut context, - msg_sender_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) + storage.legendary_card.replace(&mut new_card).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); + DocsExample::at(context.this_address()).update_leader(context.msg_sender(), points).enqueue( + &mut context, ); - DocsExample::at(context.this_address()).update_leader(context.msg_sender(), points).enqueue(&mut context); } #[private] fn increase_legendary_points() { // Ensure `points` > current value // Also serves as a e2e test that you can `get_note()` and then `replace()` - let msg_sender_keys = get_public_keys(context.msg_sender()); // docs:start:state_vars-PrivateMutableGet @@ -269,16 +260,16 @@ contract DocsExample { let points = card.points + 1; let mut new_card = CardNote::new(points, card.randomness, msg_sender_keys.npk_m.hash()); // docs:start:state_vars-PrivateMutableReplace - storage.legendary_card.replace(&mut new_card).emit( - encode_and_encrypt_note( - &mut context, - msg_sender_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) - ); + storage.legendary_card.replace(&mut new_card).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); // docs:end:state_vars-PrivateMutableReplace - DocsExample::at(context.this_address()).update_leader(context.msg_sender(), points).enqueue(&mut context); + DocsExample::at(context.this_address()).update_leader(context.msg_sender(), points).enqueue( + &mut context, + ); } #[private] #[view] @@ -337,7 +328,7 @@ contract DocsExample { // ************************************************************ // Our original inputs! a: Field, - b: Field // The actual return type of our circuit is the PrivateCircuitPublicInputs struct, this will be the + b: Field, // The actual return type of our circuit is the PrivateCircuitPublicInputs struct, this will be the // input to our kernel! // docs:start:context-example-return ) -> pub PrivateCircuitPublicInputs { diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/options.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/options.nr index b0216a98b51..928e5fbf71a 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/options.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/options.nr @@ -9,14 +9,13 @@ use dep::aztec::{note::note_getter_options::SortOrder, utils::comparison::Compar // docs:start:state_vars-NoteGetterOptionsSelectSortOffset pub fn create_npk_card_getter_options( account_npk_m_hash: Field, - offset: u32 + offset: u32, ) -> NoteGetterOptions { let mut options = NoteGetterOptions::new(); - options.select( - CardNote::properties().npk_m_hash, - Comparator.EQ, - account_npk_m_hash - ).sort(CardNote::properties().points, SortOrder.DESC).set_offset(offset) + options + .select(CardNote::properties().npk_m_hash, Comparator.EQ, account_npk_m_hash) + .sort(CardNote::properties().points, SortOrder.DESC) + .set_offset(offset) } // docs:end:state_vars-NoteGetterOptionsSelectSortOffset @@ -24,21 +23,20 @@ pub fn create_npk_card_getter_options( pub fn create_exact_card_getter_options( points: u8, secret: Field, - account_npk_m_hash: Field + account_npk_m_hash: Field, ) -> NoteGetterOptions { let mut options = NoteGetterOptions::new(); - options.select(CardNote::properties().points, Comparator.EQ, points as Field).select(CardNote::properties().randomness, Comparator.EQ, secret).select( - CardNote::properties().npk_m_hash, - Comparator.EQ, - account_npk_m_hash - ) + options + .select(CardNote::properties().points, Comparator.EQ, points as Field) + .select(CardNote::properties().randomness, Comparator.EQ, secret) + .select(CardNote::properties().npk_m_hash, Comparator.EQ, account_npk_m_hash) } // docs:end:state_vars-NoteGetterOptionsMultiSelects // docs:start:state_vars-OptionFilter pub fn filter_min_points( cards: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - min_points: u8 + min_points: u8, ) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] { let mut selected_cards = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; let mut num_selected = 0; @@ -53,8 +51,13 @@ pub fn filter_min_points( // docs:end:state_vars-OptionFilter // docs:start:state_vars-NoteGetterOptionsFilter -pub fn create_cards_with_min_points_getter_options(min_points: u8) -> NoteGetterOptions { - NoteGetterOptions::with_filter(filter_min_points, min_points).sort(CardNote::properties().points, SortOrder.ASC) +pub fn create_cards_with_min_points_getter_options( + min_points: u8, +) -> NoteGetterOptions { + NoteGetterOptions::with_filter(filter_min_points, min_points).sort( + CardNote::properties().points, + SortOrder.ASC, + ) } // docs:end:state_vars-NoteGetterOptionsFilter diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr index 4b4dd746b8d..c1d2fbf4e95 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr @@ -1,8 +1,10 @@ use dep::aztec::prelude::{NullifiableNote, PrivateContext, NoteHeader}; use dep::aztec::{ - note::{utils::compute_note_hash_for_nullify}, keys::getters::get_nsk_app, - protocol_types::{traits::Serialize, constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - macros::notes::note + note::utils::compute_note_hash_for_nullify, keys::getters::get_nsk_app, + protocol_types::{ + traits::Serialize, constants::GENERATOR_INDEX__NOTE_NULLIFIER, + hash::poseidon2_hash_with_separator, + }, macros::notes::note, }; // docs:start:state_vars-CardNote @@ -27,14 +29,15 @@ impl CardNote { // docs:start:note_interface impl NullifiableNote for CardNote { - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -42,11 +45,8 @@ impl NullifiableNote for CardNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } diff --git a/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr index 8e118629ed8..e2a94ae71ee 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_token_contract/src/main.nr @@ -38,7 +38,7 @@ contract EasyPrivateToken { amount: u64, sender: AztecAddress, recipient: AztecAddress, - outgoing_viewer: AztecAddress + outgoing_viewer: AztecAddress, ) { let balances = storage.balances; diff --git a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr index 5d65675ab8a..5e0b77265fe 100644 --- a/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/easy_private_voting_contract/src/main.nr @@ -6,7 +6,7 @@ contract EasyPrivateVoting { use dep::aztec::prelude::{AztecAddress, Map, PublicMutable, SharedImmutable}; use dep::aztec::{ keys::getters::get_public_keys, - macros::{storage::storage, functions::{public, initializer, private, internal}} + macros::{storage::storage, functions::{public, initializer, private, internal}}, }; // docs:end:imports // docs:start:storage_struct @@ -39,7 +39,9 @@ contract EasyPrivateVoting { let secret = context.request_nsk_app(msg_sender_npk_m_hash); // get secret key of caller of function let nullifier = std::hash::pedersen_hash([context.msg_sender().to_field(), secret]); // derive nullifier from sender and secret context.push_nullifier(nullifier); - EasyPrivateVoting::at(context.this_address()).add_to_tally_public(candidate).enqueue(&mut context); + EasyPrivateVoting::at(context.this_address()).add_to_tally_public(candidate).enqueue( + &mut context, + ); } // docs:end:cast_vote diff --git a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr index 3e3b9c0405d..1e6fe084acb 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr @@ -8,12 +8,12 @@ contract EcdsaKAccount { use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, - macros::{storage::storage, functions::{private, initializer, view, noinitcheck}} + macros::{storage::storage, functions::{private, initializer, view, noinitcheck}}, }; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, - auth_witness::get_auth_witness + auth_witness::get_auth_witness, }; use dep::ecdsa_public_key_note::EcdsaPublicKeyNote; @@ -32,9 +32,14 @@ contract EcdsaKAccount { // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. - - let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); - storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note(&mut context, this_keys.ovpk_m, this_keys.ivpk_m, this)); + let mut pub_key_note = + EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); + storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note( + &mut context, + this_keys.ovpk_m, + this_keys.ivpk_m, + this, + )); } // Note: If you globally change the entrypoint signature don't forget to update account_entrypoint.ts @@ -59,9 +64,7 @@ contract EcdsaKAccount { let public_key = storage.public_key.get_note(); // Load auth witness - let witness: [Field; 64] = unsafe { - get_auth_witness(outer_hash) - }; + let witness: [Field; 64] = unsafe { get_auth_witness(outer_hash) }; let mut signature: [u8; 64] = [0; 64]; for i in 0..64 { signature[i] = witness[i] as u8; @@ -71,7 +74,12 @@ contract EcdsaKAccount { // Note that noir expects the hash of the message/challenge as input to the ECDSA verification. let outer_hash_bytes: [u8; 32] = outer_hash.to_be_bytes(); let hashed_message: [u8; 32] = std::hash::sha256(outer_hash_bytes); - std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, hashed_message) + std::ecdsa_secp256k1::verify_signature( + public_key.x, + public_key.y, + signature, + hashed_message, + ) } } diff --git a/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr index be0c4d14ccb..bf47165081e 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_r_account_contract/src/main.nr @@ -7,12 +7,12 @@ contract EcdsaRAccount { use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, - macros::{storage::storage, functions::{private, initializer, view, noinitcheck}} + macros::{storage::storage, functions::{private, initializer, view, noinitcheck}}, }; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, - auth_witness::get_auth_witness + auth_witness::get_auth_witness, }; use dep::ecdsa_public_key_note::EcdsaPublicKeyNote; @@ -31,9 +31,14 @@ contract EcdsaRAccount { // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. - - let mut pub_key_note = EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); - storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note(&mut context, this_keys.ovpk_m, this_keys.ivpk_m, this)); + let mut pub_key_note = + EcdsaPublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); + storage.public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note( + &mut context, + this_keys.ovpk_m, + this_keys.ivpk_m, + this, + )); } // Note: If you globally change the entrypoint signature don't forget to update account_entrypoint.ts @@ -58,9 +63,7 @@ contract EcdsaRAccount { let public_key = storage.public_key.get_note(); // Load auth witness - let witness: [Field; 64] = unsafe { - get_auth_witness(outer_hash) - }; + let witness: [Field; 64] = unsafe { get_auth_witness(outer_hash) }; let mut signature: [u8; 64] = [0; 64]; for i in 0..64 { signature[i] = witness[i] as u8; @@ -70,6 +73,11 @@ contract EcdsaRAccount { // Note that noir expects the hash of the message/challenge as input to the ECDSA verification. let outer_hash_bytes: [u8; 32] = outer_hash.to_be_bytes(); let hashed_message: [u8; 32] = std::hash::sha256(outer_hash_bytes); - std::ecdsa_secp256r1::verify_signature(public_key.x, public_key.y, signature, hashed_message) + std::ecdsa_secp256r1::verify_signature( + public_key.x, + public_key.y, + signature, + hashed_message, + ) } } diff --git a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr index 785f6dbcfc1..59fd82197f7 100644 --- a/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/escrow_contract/src/main.nr @@ -6,7 +6,8 @@ contract Escrow { use dep::aztec::prelude::{AztecAddress, PrivateImmutable}; use dep::aztec::{ encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, - keys::getters::get_public_keys, macros::{storage::storage, functions::{private, initializer}} + keys::getters::get_public_keys, + macros::{storage::storage, functions::{private, initializer}}, }; // docs:start:addressnote_import @@ -28,7 +29,12 @@ contract Escrow { // docs:start:addressnote_new let mut note = AddressNote::new(owner, owner_keys.npk_m.hash()); // docs:end:addressnote_new - storage.owner.initialize(&mut note).emit(encode_and_encrypt_note(&mut context, msg_sender_keys.ovpk_m, owner_keys.ivpk_m, owner)); + storage.owner.initialize(&mut note).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } // Withdraws balance. Requires that msg.sender is the owner. diff --git a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr index 910cd957ca8..2f4129a84de 100644 --- a/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fee_juice_contract/src/main.nr @@ -7,7 +7,7 @@ contract FeeJuice { use dep::aztec::{ protocol_types::{address::{AztecAddress, EthAddress}, constants::FEE_JUICE_INITIAL_MINT}, state_vars::{SharedImmutable, PublicMutable, Map}, - macros::{storage::storage, functions::{private, public, view, internal}} + macros::{storage::storage, functions::{private, public, view, internal}}, }; use crate::lib::get_bridge_gas_msg_hash; @@ -28,7 +28,9 @@ contract FeeJuice { let self = context.this_address(); // Increase self balance and set as fee payer, and end setup - FeeJuice::at(self)._increase_public_balance(self, FEE_JUICE_INITIAL_MINT).enqueue(&mut context); + FeeJuice::at(self)._increase_public_balance(self, FEE_JUICE_INITIAL_MINT).enqueue( + &mut context, + ); context.set_as_fee_payer(); context.end_setup(); @@ -56,8 +58,9 @@ contract FeeJuice { // TODO(palla/gas) Emit an unencrypted log to announce which L1 to L2 message has been claimed // Otherwise, we cannot trace L1 deposits to their corresponding claims on L2 - - FeeJuice::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); + FeeJuice::at(context.this_address())._increase_public_balance(to, amount).enqueue( + &mut context, + ); } #[public] diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr index 1af0c18152e..e9aad0aeb73 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/lib.nr @@ -2,6 +2,9 @@ use dep::aztec::context::PublicContext; pub fn compute_rebate(context: PublicContext, initial_amount: Field) -> Field { let actual_fee = context.transaction_fee(); - assert(!initial_amount.lt(actual_fee), "Initial amount paid to the paymaster does not cover actual fee"); + assert( + !initial_amount.lt(actual_fee), + "Initial amount paid to the paymaster does not cover actual fee", + ); initial_amount - actual_fee } diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr index aee2342072e..7b3900f8c4e 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr @@ -7,7 +7,7 @@ contract FPC { use dep::aztec::{ protocol_types::{abis::function_selector::FunctionSelector, address::AztecAddress}, state_vars::SharedImmutable, - macros::{storage::storage, functions::{private, public, initializer, internal}} + macros::{storage::storage, functions::{private, public, initializer, internal}}, }; use dep::token::Token; use crate::lib::compute_rebate; @@ -24,33 +24,42 @@ contract FPC { } #[private] - fn fee_entrypoint_private(amount: Field, asset: AztecAddress, secret_hash: Field, nonce: Field) { + fn fee_entrypoint_private( + amount: Field, + asset: AztecAddress, + secret_hash: Field, + nonce: Field, + ) { assert(asset == storage.other_asset.read_private()); - Token::at(asset).unshield(context.msg_sender(), context.this_address(), amount, nonce).call(&mut context); + Token::at(asset).unshield(context.msg_sender(), context.this_address(), amount, nonce).call( + &mut context, + ); context.set_as_fee_payer(); // Would like to get back to // FPC::at(context.this_address()).pay_refund_with_shielded_rebate(amount, asset, secret_hash).set_public_teardown_function(&mut context); context.set_public_teardown_function( context.this_address(), comptime { - FunctionSelector::from_signature("pay_refund_with_shielded_rebate(Field,(Field),Field)") - }, - [amount, asset.to_field(), secret_hash] + FunctionSelector::from_signature( + "pay_refund_with_shielded_rebate(Field,(Field),Field)", + ) + }, + [amount, asset.to_field(), secret_hash], ); } #[private] fn fee_entrypoint_public(amount: Field, asset: AztecAddress, nonce: Field) { - FPC::at(context.this_address()).prepare_fee(context.msg_sender(), amount, asset, nonce).enqueue(&mut context); + FPC::at(context.this_address()) + .prepare_fee(context.msg_sender(), amount, asset, nonce) + .enqueue(&mut context); context.set_as_fee_payer(); // TODO(#6277) for improving interface: // FPC::at(context.this_address()).pay_refund(context.msg_sender(), amount, asset).set_public_teardown_function(&mut context); context.set_public_teardown_function( context.this_address(), - comptime { - FunctionSelector::from_signature("pay_refund((Field),Field,(Field))") - }, - [context.msg_sender().to_field(), amount, asset.to_field()] + comptime { FunctionSelector::from_signature("pay_refund((Field),Field,(Field))") }, + [context.msg_sender().to_field(), amount, asset.to_field()], ); } @@ -58,7 +67,9 @@ contract FPC { #[internal] fn prepare_fee(from: AztecAddress, amount: Field, asset: AztecAddress, nonce: Field) { // docs:start:public_call - Token::at(asset).transfer_public(from, context.this_address(), amount, nonce).call(&mut context); + Token::at(asset).transfer_public(from, context.this_address(), amount, nonce).call( + &mut context, + ); // docs:end:public_call } @@ -67,7 +78,9 @@ contract FPC { fn pay_refund(refund_address: AztecAddress, amount: Field, asset: AztecAddress) { // Just do public refunds for the present let refund = compute_rebate(context, amount); - Token::at(asset).transfer_public(context.this_address(), refund_address, refund, 0).call(&mut context); + Token::at(asset).transfer_public(context.this_address(), refund_address, refund, 0).call( + &mut context, + ); } #[public] diff --git a/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr index 6f5a19f3fda..3a3b7ec8b68 100644 --- a/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/import_test_contract/src/main.nr @@ -16,23 +16,25 @@ contract ImportTest { // See yarn-project/end-to-end/src/e2e_nested_contract.test.ts #[private] fn main_contract(target: AztecAddress) -> Field { - Test::at(target).test_code_gen( - 1, - true, - 1 as u32, - [1, 2], - DummyNote { amount: 1, secret_hash: 2 }, - DeepStruct { - a_field: 1, - a_bool: true, - a_note: DummyNote { amount: 1, secret_hash: 2 }, - many_notes: [ + Test::at(target) + .test_code_gen( + 1, + true, + 1 as u32, + [1, 2], DummyNote { amount: 1, secret_hash: 2 }, - DummyNote { amount: 1, secret_hash: 2 }, - DummyNote { amount: 1, secret_hash: 2 } - ] - } - ).call(&mut context) + DeepStruct { + a_field: 1, + a_bool: true, + a_note: DummyNote { amount: 1, secret_hash: 2 }, + many_notes: [ + DummyNote { amount: 1, secret_hash: 2 }, + DummyNote { amount: 1, secret_hash: 2 }, + DummyNote { amount: 1, secret_hash: 2 }, + ], + }, + ) + .call(&mut context) } // Calls the get_this_address on the Test contract at the target address diff --git a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr index 971162f2d7e..2c96b03771b 100644 --- a/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr @@ -4,11 +4,14 @@ use dep::aztec::macros::aztec; #[aztec] contract InclusionProofs { use dep::aztec::prelude::{AztecAddress, NoteGetterOptions, Map, PrivateSet, PublicMutable}; - use dep::aztec::{encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys}; + use dep::aztec::{ + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, + keys::getters::get_public_keys, + }; use dep::aztec::{ note::note_getter_options::NoteStatus, - macros::{storage::storage, functions::{private, public, initializer}} + macros::{storage::storage, functions::{private, public, initializer}}, }; // docs:start:value_note_imports use dep::value_note::value_note::ValueNote; @@ -34,7 +37,12 @@ contract InclusionProofs { let owner_keys = get_public_keys(owner); let mut note = ValueNote::new(value, owner_keys.npk_m.hash()); - storage.private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note(&mut context, msg_sender_keys.ovpk_m, owner_keys.ivpk_m, owner)); + storage.private_values.at(owner).insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } // docs:end:create_note @@ -43,7 +51,7 @@ contract InclusionProofs { owner: AztecAddress, use_block_number: bool, block_number: u32, // The block at which we'll prove that the note exists - nullified: bool + nullified: bool, ) { // docs:start:get_note_from_pxe // 1) Get the note from PXE. @@ -55,7 +63,6 @@ contract InclusionProofs { } let note = private_values.get_notes(options).get(0); // docs:end:get_note_from_pxe - // docs:start:prove_note_inclusion // 2) Prove the note inclusion let header = if (use_block_number) { @@ -72,7 +79,7 @@ contract InclusionProofs { fn test_note_inclusion_fail_case( owner: AztecAddress, use_block_number: bool, - block_number: u32 // The block at which we'll prove that the note exists + block_number: u32, // The block at which we'll prove that the note exists ) { let header = context.get_header(); let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); @@ -96,7 +103,7 @@ contract InclusionProofs { // Value below is only used when the note is not found --> used to test the nullifier non-inclusion failure // case (it allows me to pass in random value of note nullifier - I cannot add and fetch a random note from PXE // because PXE performs note commitment inclusion check when you add a new note). - fail_case: bool + fail_case: bool, ) { // 1) Get the note from PXE let private_values = storage.private_values.at(owner); @@ -122,7 +129,7 @@ contract InclusionProofs { owner: AztecAddress, use_block_number: bool, block_number: u32, // The block at which we'll prove that the note exists and is not nullified - nullified: bool + nullified: bool, ) { // 1) Get the note from PXE. let private_values = storage.private_values.at(owner); @@ -162,7 +169,7 @@ contract InclusionProofs { fn test_nullifier_inclusion( nullifier: Field, use_block_number: bool, - block_number: u32 // The block at which we'll prove that the nullifier exists in the nullifier tree + block_number: u32, // The block at which we'll prove that the nullifier exists in the nullifier tree ) { let header = if (use_block_number) { context.get_header_at(block_number) @@ -186,15 +193,17 @@ contract InclusionProofs { } #[private] - fn test_storage_historical_read_unset_slot(block_number: u32 // The block at which we'll read the public storage value + fn test_storage_historical_read_unset_slot( + block_number: u32, // The block at which we'll read the public storage value ) { let header = context.get_header_at(block_number); // docs:start:public_storage_historical_read assert_eq( header.public_storage_historical_read( storage.public_unused_value.storage_slot, - context.this_address() - ), 0 + context.this_address(), + ), + 0, ); // docs:end:public_storage_historical_read } @@ -203,7 +212,7 @@ contract InclusionProofs { fn test_storage_historical_read( expected: Field, use_block_number: bool, - block_number: u32 // The block at which we'll read the public storage value + block_number: u32, // The block at which we'll read the public storage value ) { let header = if (use_block_number) { context.get_header_at(block_number) @@ -211,7 +220,10 @@ contract InclusionProofs { context.get_header() }; - let actual = header.public_storage_historical_read(storage.public_value.storage_slot, context.this_address()); + let actual = header.public_storage_historical_read( + storage.public_value.storage_slot, + context.this_address(), + ); assert_eq(actual, expected, "Actual public value does not match expected"); } @@ -222,7 +234,7 @@ contract InclusionProofs { contract_address: AztecAddress, block_number: u32, test_deployment: bool, - test_initialization: bool + test_initialization: bool, ) { let header = context.get_header_at(block_number); @@ -244,7 +256,7 @@ contract InclusionProofs { contract_address: AztecAddress, block_number: u32, test_deployment: bool, - test_initialization: bool + test_initialization: bool, ) { let header = context.get_header_at(block_number); diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr index bbee9ba545e..e8ec7af56aa 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/asset.nr @@ -23,7 +23,7 @@ impl Serialize for Asset { Asset.last_updated_ts as Field, Asset.loan_to_value.lo, Asset.loan_to_value.hi, - Asset.oracle.to_field() + Asset.oracle.to_field(), ] } } diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/helpers.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/helpers.nr index c5e537e88ed..0d186db0d60 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/helpers.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/helpers.nr @@ -18,7 +18,7 @@ pub fn covered_by_collateral( loan_to_value: U128, collateral: U128, increase: U128, - decrease: U128 + decrease: U128, ) -> U128 { let price_precision = U128::from_integer(1000000000); let ltv_precision = U128::from_integer(10000); @@ -49,7 +49,7 @@ pub fn debt_updates( interest_accumulator: U128, static_debt: U128, increase: U128, - decrease: U128 + decrease: U128, ) -> DebtReturn { assert(interest_accumulator > U128::from_integer(0)); let accumulator_precision = U128::from_integer(1000000000); diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr index a9619d6782a..3066eb5b04b 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/main.nr @@ -23,7 +23,9 @@ contract Lending { use dep::token::Token; use dep::price_feed::PriceFeed; - use dep::aztec::macros::{storage::storage, functions::{private, public, initializer, internal, view}}; + use dep::aztec::macros::{ + storage::storage, functions::{private, public, initializer, internal, view}, + }; // Storage structure, containing all storage, and specifying what slots they use. #[storage] @@ -38,15 +40,14 @@ contract Lending { // Constructs the contract. #[private] #[initializer] - fn constructor( - ) {} + fn constructor() {} #[public] fn init( oracle: AztecAddress, loan_to_value: Field, collateral_asset: AztecAddress, - stable_coin: AztecAddress + stable_coin: AztecAddress, ) { let asset_loc = storage.assets.at(0); let asset: Asset = asset_loc.read(); @@ -60,7 +61,12 @@ contract Lending { let last_updated_ts = context.timestamp(); asset_loc.write( - Asset { interest_accumulator: U128::from_integer(1000000000), last_updated_ts, loan_to_value, oracle } + Asset { + interest_accumulator: U128::from_integer(1000000000), + last_updated_ts, + loan_to_value, + oracle, + }, ); storage.collateral_asset.write(collateral_asset); @@ -100,27 +106,33 @@ contract Lending { nonce: Field, secret: Field, on_behalf_of: Field, - collateral_asset: AztecAddress + collateral_asset: AztecAddress, ) { - let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); - let _res = Token::at(collateral_asset).unshield(from, context.this_address(), amount, nonce).call(&mut context); + let on_behalf_of = + compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); + let _res = Token::at(collateral_asset) + .unshield(from, context.this_address(), amount, nonce) + .call(&mut context); // docs:start:enqueue_public - Lending::at(context.this_address())._deposit( - AztecAddress::from_field(on_behalf_of), - amount, - collateral_asset - ).enqueue(&mut context); + Lending::at(context.this_address()) + ._deposit(AztecAddress::from_field(on_behalf_of), amount, collateral_asset) + .enqueue(&mut context); // docs:end:enqueue_public } #[public] - fn deposit_public(amount: Field, nonce: Field, on_behalf_of: Field, collateral_asset: AztecAddress) { - let _ = Token::at(collateral_asset).transfer_public(context.msg_sender(), context.this_address(), amount, nonce).call(&mut context); - let _ = Lending::at(context.this_address())._deposit( - AztecAddress::from_field(on_behalf_of), - amount, - collateral_asset - ).call(&mut context); + fn deposit_public( + amount: Field, + nonce: Field, + on_behalf_of: Field, + collateral_asset: AztecAddress, + ) { + let _ = Token::at(collateral_asset) + .transfer_public(context.msg_sender(), context.this_address(), amount, nonce) + .call(&mut context); + let _ = Lending::at(context.this_address()) + ._deposit(AztecAddress::from_field(on_behalf_of), amount, collateral_asset) + .call(&mut context); } #[public] @@ -139,12 +151,16 @@ contract Lending { #[private] fn withdraw_private(secret: Field, to: AztecAddress, amount: Field) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().to_field()); - Lending::at(context.this_address())._withdraw(AztecAddress::from_field(on_behalf_of), to, amount).enqueue(&mut context); + Lending::at(context.this_address()) + ._withdraw(AztecAddress::from_field(on_behalf_of), to, amount) + .enqueue(&mut context); } #[public] fn withdraw_public(to: AztecAddress, amount: Field) { - let _ = Lending::at(context.this_address())._withdraw(context.msg_sender(), to, amount).call(&mut context); + let _ = Lending::at(context.this_address()) + ._withdraw(context.msg_sender(), to, amount) + .call(&mut context); } #[public] @@ -166,13 +182,13 @@ contract Lending { asset.loan_to_value, U128::from_integer(collateral), U128::from_integer(0), - U128::from_integer(amount) + U128::from_integer(amount), ); let debt_returns = debt_updates( asset.interest_accumulator, U128::from_integer(static_debt), U128::from_integer(0), - U128::from_integer(0) + U128::from_integer(0), ); assert(debt_returns.debt_value < debt_covered); @@ -181,18 +197,24 @@ contract Lending { // @todo @LHerskind Support both shielding and transfers (for now just transfer) let collateral_asset = storage.collateral_asset.read(); - let _ = Token::at(collateral_asset).transfer_public(context.this_address(), recipient, amount, 0).call(&mut context); + let _ = Token::at(collateral_asset) + .transfer_public(context.this_address(), recipient, amount, 0) + .call(&mut context); } #[private] fn borrow_private(secret: Field, to: AztecAddress, amount: Field) { let on_behalf_of = compute_identifier(secret, 0, context.msg_sender().to_field()); - let _ = Lending::at(context.this_address())._borrow(AztecAddress::from_field(on_behalf_of), to, amount).enqueue(&mut context); + let _ = Lending::at(context.this_address()) + ._borrow(AztecAddress::from_field(on_behalf_of), to, amount) + .enqueue(&mut context); } #[public] fn borrow_public(to: AztecAddress, amount: Field) { - let _ = Lending::at(context.this_address())._borrow(context.msg_sender(), to, amount).call(&mut context); + let _ = Lending::at(context.this_address())._borrow(context.msg_sender(), to, amount).call( + &mut context, + ); } #[public] @@ -210,13 +232,13 @@ contract Lending { asset.loan_to_value, collateral, U128::from_integer(0), - U128::from_integer(0) + U128::from_integer(0), ); let debt_returns = debt_updates( asset.interest_accumulator, static_debt, U128::from_integer(amount), - U128::from_integer(0) + U128::from_integer(0), ); assert(debt_returns.debt_value < debt_covered); @@ -235,19 +257,26 @@ contract Lending { nonce: Field, secret: Field, on_behalf_of: Field, - stable_coin: AztecAddress + stable_coin: AztecAddress, ) { - let on_behalf_of = compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); + let on_behalf_of = + compute_identifier(secret, on_behalf_of, context.msg_sender().to_field()); // docs:start:private_call let _ = Token::at(stable_coin).burn(from, amount, nonce).call(&mut context); // docs:end:private_call - let _ = Lending::at(context.this_address())._repay(AztecAddress::from_field(on_behalf_of), amount, stable_coin).enqueue(&mut context); + let _ = Lending::at(context.this_address()) + ._repay(AztecAddress::from_field(on_behalf_of), amount, stable_coin) + .enqueue(&mut context); } #[public] fn repay_public(amount: Field, nonce: Field, owner: AztecAddress, stable_coin: AztecAddress) { - let _ = Token::at(stable_coin).burn_public(context.msg_sender(), amount, nonce).call(&mut context); - let _ = Lending::at(context.this_address())._repay(owner, amount, stable_coin).call(&mut context); + let _ = Token::at(stable_coin).burn_public(context.msg_sender(), amount, nonce).call( + &mut context, + ); + let _ = Lending::at(context.this_address())._repay(owner, amount, stable_coin).call( + &mut context, + ); } #[public] @@ -263,7 +292,7 @@ contract Lending { asset.interest_accumulator, static_debt, U128::from_integer(0), - U128::from_integer(amount) + U128::from_integer(amount), ); storage.static_debt.at(owner).write(debt_returns.static_debt.to_integer()); @@ -283,8 +312,9 @@ contract Lending { let asset: Asset = storage.assets.at(0).read(); let debt = debt_value( U128::from_integer(static_debt), - U128::from_integer(asset.interest_accumulator) - ).to_integer(); + U128::from_integer(asset.interest_accumulator), + ) + .to_integer(); Position { collateral, static_debt, debt } } diff --git a/noir-projects/noir-contracts/contracts/lending_contract/src/position.nr b/noir-projects/noir-contracts/contracts/lending_contract/src/position.nr index 052f935d025..15144b6e722 100644 --- a/noir-projects/noir-contracts/contracts/lending_contract/src/position.nr +++ b/noir-projects/noir-contracts/contracts/lending_contract/src/position.nr @@ -10,11 +10,7 @@ global POSITION_SERIALIZED_LEN: u32 = 3; impl Serialize for Position { fn serialize(position: Position) -> [Field; POSITION_SERIALIZED_LEN] { - [ - position.collateral.to_field(), - position.static_debt.to_field(), - position.debt.to_field() - ] + [position.collateral.to_field(), position.static_debt.to_field(), position.debt.to_field()] } } diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr index 6ec923ba8c2..3d142c4fb95 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/main.nr @@ -10,14 +10,24 @@ contract NFT { use dep::compressed_string::FieldCompressedString; use dep::aztec::{ oracle::random::random, - prelude::{NoteGetterOptions, NoteViewerOptions, Map, PublicMutable, SharedImmutable, PrivateSet, AztecAddress}, - encrypted_logs::{encrypted_note_emission::{encode_and_encrypt_note, encrypt_and_emit_partial_log}}, - hash::pedersen_hash, keys::getters::get_public_keys, note::constants::MAX_NOTES_PER_PAGE, + prelude::{ + NoteGetterOptions, NoteViewerOptions, Map, PublicMutable, SharedImmutable, PrivateSet, + AztecAddress, + }, + encrypted_logs::encrypted_note_emission::{ + encode_and_encrypt_note, encrypt_and_emit_partial_log, + }, hash::pedersen_hash, keys::getters::get_public_keys, note::constants::MAX_NOTES_PER_PAGE, protocol_types::traits::is_empty, utils::comparison::Comparator, protocol_types::{point::Point, traits::Serialize}, - macros::{storage::storage, events::event, functions::{private, public, view, internal, initializer}} + macros::{ + storage::storage, events::event, + functions::{private, public, view, internal, initializer}, + }, + }; + use dep::authwit::auth::{ + assert_current_call_valid_authwit, assert_current_call_valid_authwit_public, + compute_authwit_nullifier, }; - use dep::authwit::auth::{assert_current_call_valid_authwit, assert_current_call_valid_authwit_public, compute_authwit_nullifier}; use std::{embedded_curve_ops::EmbeddedCurvePoint, meta::derive}; use crate::types::nft_note::NFTNote; @@ -142,7 +152,7 @@ contract NFT { fn prepare_transfer_to_private( from: AztecAddress, to: AztecAddress, - transient_storage_slot_randomness: Field + transient_storage_slot_randomness: Field, ) { let to_keys = get_public_keys(to); let to_npk_m_hash = to_keys.npk_m.hash(); @@ -151,10 +161,9 @@ contract NFT { // We create a partial NFT note hiding point with unpopulated/zero token id for 'to' // TODO(#7775): Manually fetching the randomness here is not great. If we decide to include randomness in all // notes we could just inject it in macros. - let note_randomness = unsafe { - random() - }; - let note_setup_payload = NFTNote::setup_payload().new(to_npk_m_hash, note_randomness, to_note_slot); + let note_randomness = unsafe { random() }; + let note_setup_payload = + NFTNote::setup_payload().new(to_npk_m_hash, note_randomness, to_note_slot); // We encrypt and emit the partial note log encrypt_and_emit_partial_log(&mut context, note_setup_payload.log_plaintext, to_keys, to); @@ -163,16 +172,18 @@ contract NFT { // non-sender's slots let transfer_preparer_storage_slot_commitment: Field = pedersen_hash( [context.msg_sender().to_field(), transient_storage_slot_randomness], - TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX + TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX, ); // Then we hash the transfer preparer storage slot commitment with `from` and use that as the final slot // --> by hashing it with a `from` we ensure that `from` cannot interfere with slots not assigned to him. let slot: Field = pedersen_hash( [from.to_field(), transfer_preparer_storage_slot_commitment], - TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX + TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX, ); - NFT::at(context.this_address())._store_point_in_transient_storage(note_setup_payload.hiding_point, slot).enqueue(&mut context); + NFT::at(context.this_address()) + ._store_point_in_transient_storage(note_setup_payload.hiding_point, slot) + .enqueue(&mut context); } #[public] @@ -190,7 +201,7 @@ contract NFT { #[public] fn finalize_transfer_to_private( token_id: Field, - transfer_preparer_storage_slot_commitment: Field + transfer_preparer_storage_slot_commitment: Field, ) { // We don't need to support authwit here because `prepare_transfer_to_private` allows us to set arbitrary // `from` and `from` will always be the msg sender here. @@ -202,7 +213,7 @@ contract NFT { // as `from` in this function) let hiding_point_slot = pedersen_hash( [from.to_field(), transfer_preparer_storage_slot_commitment], - TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX + TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX, ); // Read the hiding point from "transient" storage and check it's not empty to ensure the transfer was prepared @@ -247,16 +258,21 @@ contract NFT { let nfts = storage.private_nfts; - let notes = nfts.at(from).pop_notes( - NoteGetterOptions::new().select(NFTNote::properties().token_id, Comparator.EQ, token_id).set_limit(1) - ); + let notes = nfts.at(from).pop_notes(NoteGetterOptions::new() + .select(NFTNote::properties().token_id, Comparator.EQ, token_id) + .set_limit(1)); assert(notes.len() == 1, "NFT not found when transferring"); let from_ovpk_m = get_public_keys(from).ovpk_m; let to_keys = get_public_keys(to); let mut new_note = NFTNote::new(token_id, to_keys.npk_m.hash()); - nfts.at(to).insert(&mut new_note).emit(encode_and_encrypt_note(&mut context, from_ovpk_m, to_keys.ivpk_m, to)); + nfts.at(to).insert(&mut new_note).emit(encode_and_encrypt_note( + &mut context, + from_ovpk_m, + to_keys.ivpk_m, + to, + )); } #[private] @@ -267,12 +283,14 @@ contract NFT { assert(nonce == 0, "invalid nonce"); } - let notes = storage.private_nfts.at(from).pop_notes( - NoteGetterOptions::new().select(NFTNote::properties().token_id, Comparator.EQ, token_id).set_limit(1) - ); + let notes = storage.private_nfts.at(from).pop_notes(NoteGetterOptions::new() + .select(NFTNote::properties().token_id, Comparator.EQ, token_id) + .set_limit(1)); assert(notes.len() == 1, "NFT not found when transferring to public"); - NFT::at(context.this_address())._finish_transfer_to_public(to, token_id).enqueue(&mut context); + NFT::at(context.this_address())._finish_transfer_to_public(to, token_id).enqueue( + &mut context, + ); } #[public] @@ -292,7 +310,10 @@ contract NFT { /// Returns an array of token IDs owned by `owner` in private and a flag indicating whether a page limit was /// reached. Starts getting the notes from page with index `page_index`. Zero values in the array are placeholder /// values for non-existing notes. - unconstrained fn get_private_nfts(owner: AztecAddress, page_index: u32) -> pub ([Field; MAX_NOTES_PER_PAGE], bool) { + unconstrained fn get_private_nfts( + owner: AztecAddress, + page_index: u32, + ) -> pub ([Field; MAX_NOTES_PER_PAGE], bool) { let offset = page_index * MAX_NOTES_PER_PAGE; let mut options = NoteViewerOptions::new(); let notes = storage.private_nfts.at(owner).view_notes(options.set_offset(offset)); diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/access_control.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/access_control.nr index b74c646dc3b..e787bf643cb 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/access_control.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/access_control.nr @@ -4,7 +4,8 @@ use crate::NFT; #[test] unconstrained fn access_control() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, owner, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, nft_contract_address, owner, recipient) = + utils::setup( /* with_account_contracts */ false); // Set a new admin NFT::at(nft_contract_address).set_admin(recipient).call(&mut env.public()); diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/minting.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/minting.nr index 1cb34b43203..79730309e9a 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/minting.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/minting.nr @@ -4,7 +4,7 @@ use crate::NFT; #[test] unconstrained fn mint_success() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, owner, _) = utils::setup(/* with_account_contracts */ false); + let (env, nft_contract_address, owner, _) = utils::setup( /* with_account_contracts */ false); let token_id = 10000; NFT::at(nft_contract_address).mint(owner, token_id).call(&mut env.public()); @@ -15,7 +15,8 @@ unconstrained fn mint_success() { #[test] unconstrained fn mint_failures() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, owner, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, nft_contract_address, owner, recipient) = + utils::setup( /* with_account_contracts */ false); // MINTING AS A NON-MINTER let token_id = 10000; diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_private.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_private.nr index 0d11bef5441..d80a77b38f1 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_private.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_private.nr @@ -7,10 +7,13 @@ use crate::NFT; #[test] unconstrained fn transfer_in_private() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); // Transfer the NFT to the recipient - NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 0).call( + &mut env.private(), + ); // Recipient should have the note in their private nfts utils::assert_owns_private_nft(nft_contract_address, recipient, token_id); @@ -19,10 +22,13 @@ unconstrained fn transfer_in_private() { #[test] unconstrained fn transfer_in_private_to_self() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, owner, _, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, owner, _, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); // Transfer the NFT back to the owner - NFT::at(nft_contract_address).transfer_in_private(owner, owner, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_in_private(owner, owner, token_id, 0).call( + &mut env.private(), + ); // NFT owner should stay the same utils::assert_owns_private_nft(nft_contract_address, owner, token_id); @@ -31,11 +37,14 @@ unconstrained fn transfer_in_private_to_self() { #[test] unconstrained fn transfer_in_private_to_non_deployed_account() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, sender, _, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, _, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); let not_deployed = cheatcodes::create_account(); // Transfer the NFT to the recipient - NFT::at(nft_contract_address).transfer_in_private(sender, not_deployed.address, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address) + .transfer_in_private(sender, not_deployed.address, token_id, 0) + .call(&mut env.private()); // Owner of the private NFT should be the not_deployed account utils::assert_owns_private_nft(nft_contract_address, not_deployed.address, token_id); @@ -44,11 +53,17 @@ unconstrained fn transfer_in_private_to_non_deployed_account() { #[test] unconstrained fn transfer_in_private_on_behalf_of_other() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ true); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ true); // Transfer the NFT to the recipient - let transfer_in_private_call_interface = NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1); - authwit_cheatcodes::add_private_authwit_from_call_interface(sender, recipient, transfer_in_private_call_interface); + let transfer_in_private_call_interface = + NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1); + authwit_cheatcodes::add_private_authwit_from_call_interface( + sender, + recipient, + transfer_in_private_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); @@ -62,10 +77,13 @@ unconstrained fn transfer_in_private_on_behalf_of_other() { #[test(should_fail_with = "NFT not found when transferring")] unconstrained fn transfer_in_private_failure_not_an_owner() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, owner, not_owner, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, owner, not_owner, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); // Try transferring the NFT from not_owner env.impersonate(not_owner); - NFT::at(nft_contract_address).transfer_in_private(not_owner, owner, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_in_private(not_owner, owner, token_id, 0).call( + &mut env.private(), + ); } #[test(should_fail_with = "invalid nonce")] @@ -73,13 +91,16 @@ unconstrained fn transfer_in_private_failure_on_behalf_of_self_non_zero_nonce() // Setup without account contracts. We are not using authwits here, so dummy accounts are enough. // The nonce check is in the beginning so we don't need to waste time on minting the NFT and transferring // it to private. - let (env, nft_contract_address, sender, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, recipient) = + utils::setup( /* with_account_contracts */ false); // We set random value for the token_id as the nonce check is before we use the value. let token_id = random(); // Try transferring the NFT - NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1).call( + &mut env.private(), + ); } #[test(should_fail_with = "Authorization not found for message hash")] @@ -87,7 +108,8 @@ unconstrained fn transfer_in_private_failure_on_behalf_of_other_without_approval // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. // The authwit check is in the beginning so we don't need to waste time on minting the NFT and transferring // it to private. - let (env, nft_contract_address, sender, recipient) = utils::setup(/* with_account_contracts */ true); + let (env, nft_contract_address, sender, recipient) = + utils::setup( /* with_account_contracts */ true); // We set random value for the token_id as the nonce check is before we use the value. let token_id = random(); @@ -95,7 +117,9 @@ unconstrained fn transfer_in_private_failure_on_behalf_of_other_without_approval // Impersonate recipient to perform the call env.impersonate(recipient); // Try transferring the NFT - NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1).call( + &mut env.private(), + ); } #[test(should_fail_with = "Authorization not found for message hash")] @@ -103,13 +127,19 @@ unconstrained fn transfer_in_private_failure_on_behalf_of_other_wrong_caller() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. // The authwit check is in the beginning so we don't need to waste time on minting the NFT and transferring // it to private. - let (env, nft_contract_address, sender, recipient) = utils::setup(/* with_account_contracts */ true); + let (env, nft_contract_address, sender, recipient) = + utils::setup( /* with_account_contracts */ true); // We set random value for the token_id as the nonce check is before we use the value. let token_id = random(); - let transfer_in_private_from_call_interface = NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1); - authwit_cheatcodes::add_private_authwit_from_call_interface(sender, sender, transfer_in_private_from_call_interface); + let transfer_in_private_from_call_interface = + NFT::at(nft_contract_address).transfer_in_private(sender, recipient, token_id, 1); + authwit_cheatcodes::add_private_authwit_from_call_interface( + sender, + sender, + transfer_in_private_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Try transferring the NFT diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_public.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_public.nr index ac8eb37d978..b5fb7c59698 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_public.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_in_public.nr @@ -6,10 +6,13 @@ use crate::NFT; #[test] unconstrained fn transfer_in_public() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer the NFT - NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 0).call(&mut env.public()); + NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 0).call( + &mut env.public(), + ); utils::assert_owns_public_nft(env, nft_contract_address, recipient, token_id); } @@ -17,7 +20,8 @@ unconstrained fn transfer_in_public() { #[test] unconstrained fn transfer_in_public_to_self() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, user, _, token_id) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, nft_contract_address, user, _, token_id) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer the NFT NFT::at(nft_contract_address).transfer_in_public(user, user, token_id, 0).call(&mut env.public()); @@ -29,10 +33,16 @@ unconstrained fn transfer_in_public_to_self() { #[test] unconstrained fn transfer_in_public_on_behalf_of_other() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_and_mint(/* with_account_contracts */ true); - - let transfer_in_public_from_call_interface = NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 1); - authwit_cheatcodes::add_public_authwit_from_call_interface(sender, recipient, transfer_in_public_from_call_interface); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_and_mint( /* with_account_contracts */ true); + + let transfer_in_public_from_call_interface = + NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 1); + authwit_cheatcodes::add_public_authwit_from_call_interface( + sender, + recipient, + transfer_in_public_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Transfer the NFT @@ -47,42 +57,57 @@ unconstrained fn transfer_in_public_failure_on_behalf_of_self_non_zero_nonce() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough. // The authwit check is in the beginning so we don't need to waste time on minting the NFT and transferring // it to private.. - let (env, nft_contract_address, sender, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, recipient) = + utils::setup( /* with_account_contracts */ false); // We set random value for the token_id as the nonce check is before we use the value. let token_id = random(); // Try to transfer the NFT - NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, random()).call(&mut env.public()); + NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, random()).call( + &mut env.public(), + ); } #[test(should_fail_with = "invalid owner")] unconstrained fn transfer_in_public_non_existent_nft() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, sender, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, recipient) = + utils::setup( /* with_account_contracts */ false); // Try to transfer the NFT let token_id = 612; - NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 0).call(&mut env.public()); + NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 0).call( + &mut env.public(), + ); } #[test(should_fail_with = "unauthorized")] unconstrained fn transfer_in_public_failure_on_behalf_of_other_without_approval() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_and_mint( /* with_account_contracts */ true); // Impersonate recipient to perform the call env.impersonate(recipient); // Try to transfer tokens - NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 1).call(&mut env.public()); + NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 1).call( + &mut env.public(), + ); } #[test(should_fail_with = "unauthorized")] unconstrained fn transfer_in_public_failure_on_behalf_of_other_wrong_caller() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_and_mint(/* with_account_contracts */ true); - let transfer_in_public_from_call_interface = NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 1); - authwit_cheatcodes::add_public_authwit_from_call_interface(sender, sender, transfer_in_public_from_call_interface); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_and_mint( /* with_account_contracts */ true); + let transfer_in_public_from_call_interface = + NFT::at(nft_contract_address).transfer_in_public(sender, recipient, token_id, 1); + authwit_cheatcodes::add_public_authwit_from_call_interface( + sender, + sender, + transfer_in_public_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Try to transfer tokens diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr index 1e061b338e2..c9a0bc9e460 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_private.nr @@ -1,7 +1,7 @@ use crate::{test::utils, types::nft_note::NFTNote, NFT}; use dep::aztec::{ hash::pedersen_hash, keys::getters::get_public_keys, prelude::{AztecAddress, NoteHeader}, - oracle::random::random, protocol_types::storage::map::derive_storage_slot_in_map + oracle::random::random, protocol_types::storage::map::derive_storage_slot_in_map, }; use std::test::OracleMock; @@ -9,9 +9,9 @@ use std::test::OracleMock; unconstrained fn transfer_to_private_to_self() { // The transfer to private to self is done in `utils::setup_mint_and_transfer_to_private` and for this reason // in this test we just call it and check the outcome. - // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, user, _, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, user, _, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); // User should have the note in their private nfts utils::assert_owns_private_nft(nft_contract_address, user, token_id); @@ -23,34 +23,45 @@ unconstrained fn transfer_to_private_to_self() { #[test] unconstrained fn transfer_to_private_to_a_different_account() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_and_mint( /* with_account_contracts */ false); let note_randomness = random(); let transient_storage_slot_randomness = random(); // Sender will be the msg_sender/transfer_preparer in prepare_transfer_to_private let transfer_preparer_storage_slot_commitment = pedersen_hash( [sender.to_field(), transient_storage_slot_randomness], - NFT::TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX + NFT::TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX, ); // We mock the Oracle to return the note randomness such that later on we can manually add the note let _ = OracleMock::mock("getRandomField").returns(note_randomness); // We prepare the transfer - NFT::at(nft_contract_address).prepare_transfer_to_private(sender, recipient, transient_storage_slot_randomness).call(&mut env.private()); + NFT::at(nft_contract_address) + .prepare_transfer_to_private(sender, recipient, transient_storage_slot_randomness) + .call(&mut env.private()); // Finalize the transfer of the NFT - NFT::at(nft_contract_address).finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment).call(&mut env.public()); + NFT::at(nft_contract_address) + .finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment) + .call(&mut env.public()); // TODO(#8771): We need to manually add the note because in the partial notes flow `notify_created_note_oracle` // is not called and we don't have a `NoteProcessor` in TXE. let recipient_npk_m_hash = get_public_keys(recipient).npk_m.hash(); - let private_nfts_recipient_slot = derive_storage_slot_in_map(NFT::storage_layout().private_nfts.slot, recipient); + let private_nfts_recipient_slot = + derive_storage_slot_in_map(NFT::storage_layout().private_nfts.slot, recipient); env.add_note( - &mut NFTNote { token_id, npk_m_hash: recipient_npk_m_hash, randomness: note_randomness, header: NoteHeader::empty() }, + &mut NFTNote { + token_id, + npk_m_hash: recipient_npk_m_hash, + randomness: note_randomness, + header: NoteHeader::empty(), + }, private_nfts_recipient_slot, - nft_contract_address + nft_contract_address, ); // Recipient should have the note in their private nfts @@ -63,20 +74,23 @@ unconstrained fn transfer_to_private_to_a_different_account() { #[test(should_fail_with = "transfer not prepared")] unconstrained fn transfer_to_private_to_self_transfer_not_prepared() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, _, _, token_id) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, nft_contract_address, _, _, token_id) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer was not prepared so we can use random value for the commitment let transfer_preparer_storage_slot_commitment = random(); // Try finalizing the transfer without preparing it - - NFT::at(nft_contract_address).finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment).call(&mut env.public()) + NFT::at(nft_contract_address) + .finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment) + .call(&mut env.public()) } #[test(should_fail_with = "transfer not prepared")] unconstrained fn transfer_to_private_finalizing_from_incorrect_sender() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, incorrect_sender, recipient, token_id) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, nft_contract_address, incorrect_sender, recipient, token_id) = + utils::setup_and_mint( /* with_account_contracts */ false); let correct_sender = AztecAddress::from_field(9); @@ -84,24 +98,29 @@ unconstrained fn transfer_to_private_finalizing_from_incorrect_sender() { // Sender will be the msg_sender/transfer_preparer in prepare_transfer_to_private let transfer_preparer_storage_slot_commitment = pedersen_hash( [correct_sender.to_field(), transient_storage_slot_randomness], - NFT::TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX + NFT::TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX, ); // We prepare the transfer - NFT::at(nft_contract_address).prepare_transfer_to_private(correct_sender, recipient, transient_storage_slot_randomness).call(&mut env.private()); + NFT::at(nft_contract_address) + .prepare_transfer_to_private(correct_sender, recipient, transient_storage_slot_randomness) + .call(&mut env.private()); // We impersonate incorrect sender and try to finalize the transfer of the NFT. The incorrect sender owns the NFT // but tries to consume a prepared transfer not belonging to him. For this reason the test should fail with // "transfer not prepared". env.impersonate(incorrect_sender); - NFT::at(nft_contract_address).finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment).call(&mut env.public()); + NFT::at(nft_contract_address) + .finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment) + .call(&mut env.public()); } #[test(should_fail_with = "invalid NFT owner")] unconstrained fn transfer_to_private_failure_not_an_owner() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, _, not_owner, token_id) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, nft_contract_address, _, not_owner, token_id) = + utils::setup_and_mint( /* with_account_contracts */ false); // We set random value for the commitment as the NFT owner check is before we use the value let transfer_preparer_storage_slot_commitment = random(); @@ -109,5 +128,7 @@ unconstrained fn transfer_to_private_failure_not_an_owner() { // Try transferring someone else's public NFT env.impersonate(not_owner); - NFT::at(nft_contract_address).finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment).call(&mut env.public()); + NFT::at(nft_contract_address) + .finalize_transfer_to_private(token_id, transfer_preparer_storage_slot_commitment) + .call(&mut env.public()); } diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_public.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_public.nr index 14604c18aaf..b386a4c0454 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_public.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/transfer_to_public.nr @@ -6,9 +6,12 @@ use crate::NFT; #[test] unconstrained fn transfer_to_public() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); - NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0).call( + &mut env.private(), + ); // Recipient should be the public owner utils::assert_owns_public_nft(env, nft_contract_address, recipient, token_id); @@ -17,9 +20,12 @@ unconstrained fn transfer_to_public() { #[test] unconstrained fn transfer_to_public_to_self() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, user, _, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, user, _, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); - NFT::at(nft_contract_address).transfer_to_public(user, user, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_to_public(user, user, token_id, 0).call( + &mut env.private(), + ); // Check the user stayed the public owner utils::assert_owns_public_nft(env, nft_contract_address, user, token_id); @@ -27,10 +33,16 @@ unconstrained fn transfer_to_public_to_self() { #[test] unconstrained fn transfer_to_public_on_behalf_of_other() { - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ true); - - let transfer_to_public_call_interface = NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0); - authwit_cheatcodes::add_private_authwit_from_call_interface(sender, recipient, transfer_to_public_call_interface); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ true); + + let transfer_to_public_call_interface = + NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0); + authwit_cheatcodes::add_private_authwit_from_call_interface( + sender, + recipient, + transfer_to_public_call_interface, + ); // Impersonate recipient env.impersonate(recipient); // transfer_to_public the NFT @@ -43,26 +55,38 @@ unconstrained fn transfer_to_public_on_behalf_of_other() { #[test(should_fail_with = "NFT not found when transferring to public")] unconstrained fn transfer_to_public_failure_not_an_owner() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, _, not_owner, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, _, not_owner, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); env.impersonate(not_owner); - NFT::at(nft_contract_address).transfer_to_public(not_owner, not_owner, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_to_public(not_owner, not_owner, token_id, 0).call( + &mut env.private(), + ); } #[test(should_fail_with = "invalid nonce")] unconstrained fn transfer_to_public_failure_on_behalf_of_self_non_zero_nonce() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, nft_contract_address, user, _, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ false); + let (env, nft_contract_address, user, _, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ false); - NFT::at(nft_contract_address).transfer_to_public(user, user, token_id, random()).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_to_public(user, user, token_id, random()).call( + &mut env.private(), + ); } #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn transfer_to_public_failure_on_behalf_of_other_invalid_designated_caller() { - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ true); - - let transfer_to_public_call_interface = NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0); - authwit_cheatcodes::add_private_authwit_from_call_interface(sender, sender, transfer_to_public_call_interface); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ true); + + let transfer_to_public_call_interface = + NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0); + authwit_cheatcodes::add_private_authwit_from_call_interface( + sender, + sender, + transfer_to_public_call_interface, + ); // Impersonate recipient env.impersonate(recipient); // transfer_to_public the NFT @@ -71,10 +95,13 @@ unconstrained fn transfer_to_public_failure_on_behalf_of_other_invalid_designate #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn transfer_to_public_failure_on_behalf_of_other_no_approval() { - let (env, nft_contract_address, sender, recipient, token_id) = utils::setup_mint_and_transfer_to_private(/* with_account_contracts */ true); + let (env, nft_contract_address, sender, recipient, token_id) = + utils::setup_mint_and_transfer_to_private( /* with_account_contracts */ true); // Impersonate recipient env.impersonate(recipient); // transfer_to_public the NFT - NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0).call(&mut env.private()); + NFT::at(nft_contract_address).transfer_to_public(sender, recipient, token_id, 0).call( + &mut env.private(), + ); } diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr index a83ae782208..fdf076c1021 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/test/utils.nr @@ -3,11 +3,15 @@ use dep::aztec::{ hash::pedersen_hash, keys::getters::get_public_keys, prelude::{AztecAddress, NoteHeader}, test::helpers::{cheatcodes, test_environment::TestEnvironment}, protocol_types::storage::map::derive_storage_slot_in_map, - oracle::{execution::{get_block_number, get_contract_address}, random::random, storage::storage_read} + oracle::{ + execution::{get_block_number, get_contract_address}, random::random, storage::storage_read, + }, }; use std::test::OracleMock; -pub unconstrained fn setup(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress) { +pub unconstrained fn setup( + with_account_contracts: bool, +) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress) { // Setup env, generate keys let mut env = TestEnvironment::new(); let (owner, recipient) = if with_account_contracts { @@ -27,15 +31,18 @@ pub unconstrained fn setup(with_account_contracts: bool) -> (&mut TestEnvironmen let initializer_call_interface = NFT::interface().constructor( owner, "TestNFT000000000000000000000000", - "TN00000000000000000000000000000" + "TN00000000000000000000000000000", ); - let nft_contract = env.deploy_self("NFT").with_public_void_initializer(initializer_call_interface); + let nft_contract = + env.deploy_self("NFT").with_public_void_initializer(initializer_call_interface); let nft_contract_address = nft_contract.to_address(); env.advance_block_by(1); (&mut env, nft_contract_address, owner, recipient) } -pub unconstrained fn setup_and_mint(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) { +pub unconstrained fn setup_and_mint( + with_account_contracts: bool, +) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) { // Setup let (env, nft_contract_address, owner, recipient) = setup(with_account_contracts); let minted_token_id = 615; @@ -45,39 +52,47 @@ pub unconstrained fn setup_and_mint(with_account_contracts: bool) -> (&mut TestE (env, nft_contract_address, owner, recipient, minted_token_id) } -pub unconstrained fn setup_mint_and_transfer_to_private(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) { - let (env, nft_contract_address, owner, recipient, minted_token_id) = setup_and_mint(with_account_contracts); +pub unconstrained fn setup_mint_and_transfer_to_private( + with_account_contracts: bool, +) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) { + let (env, nft_contract_address, owner, recipient, minted_token_id) = + setup_and_mint(with_account_contracts); let note_randomness = random(); let transient_storage_slot_randomness = random(); let transfer_preparer_storage_slot_commitment = pedersen_hash( [owner.to_field(), transient_storage_slot_randomness], - NFT::TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX + NFT::TRANSIENT_STORAGE_SLOT_PEDERSEN_INDEX, ); // We mock the Oracle to return the note randomness such that later on we can manually add the note let _ = OracleMock::mock("getRandomField").returns(note_randomness); // We prepare the transfer with user being both the sender and the recipient (classical "shield" flow) - NFT::at(nft_contract_address).prepare_transfer_to_private(owner, owner, transient_storage_slot_randomness).call(&mut env.private()); + NFT::at(nft_contract_address) + .prepare_transfer_to_private(owner, owner, transient_storage_slot_randomness) + .call(&mut env.private()); // Finalize the transfer of the NFT - NFT::at(nft_contract_address).finalize_transfer_to_private(minted_token_id, transfer_preparer_storage_slot_commitment).call(&mut env.public()); + NFT::at(nft_contract_address) + .finalize_transfer_to_private(minted_token_id, transfer_preparer_storage_slot_commitment) + .call(&mut env.public()); // TODO(#8771): We need to manually add the note because in the partial notes flow `notify_created_note_oracle` // is not called and we don't have a `NoteProcessor` in TXE. let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); - let private_nfts_owner_slot = derive_storage_slot_in_map(NFT::storage_layout().private_nfts.slot, owner); + let private_nfts_owner_slot = + derive_storage_slot_in_map(NFT::storage_layout().private_nfts.slot, owner); env.add_note( &mut NFTNote { - token_id: minted_token_id, - npk_m_hash: owner_npk_m_hash, - randomness: note_randomness, - header: NoteHeader::empty() - }, + token_id: minted_token_id, + npk_m_hash: owner_npk_m_hash, + randomness: note_randomness, + header: NoteHeader::empty(), + }, private_nfts_owner_slot, - nft_contract_address + nft_contract_address, ); (env, nft_contract_address, owner, recipient, minted_token_id) @@ -100,14 +115,18 @@ pub unconstrained fn assert_owns_public_nft( env: &mut TestEnvironment, nft_contract_address: AztecAddress, owner: AztecAddress, - token_id: Field + token_id: Field, ) { let obtained_owner = NFT::at(nft_contract_address).owner_of(token_id).view(&mut env.public()); assert(owner == obtained_owner, "Incorrect NFT owner"); } -pub unconstrained fn assert_owns_private_nft(nft_contract_address: AztecAddress, owner: AztecAddress, token_id: Field) { +pub unconstrained fn assert_owns_private_nft( + nft_contract_address: AztecAddress, + owner: AztecAddress, + token_id: Field, +) { let current_contract_address = get_contract_address(); cheatcodes::set_contract_address(nft_contract_address); diff --git a/noir-projects/noir-contracts/contracts/nft_contract/src/types/nft_note.nr b/noir-projects/noir-contracts/contracts/nft_contract/src/types/nft_note.nr index 6755478b14c..9fd3bd2afff 100644 --- a/noir-projects/noir-contracts/contracts/nft_contract/src/types/nft_note.nr +++ b/noir-projects/noir-contracts/contracts/nft_contract/src/types/nft_note.nr @@ -1,8 +1,10 @@ use dep::aztec::{ note::utils::compute_note_hash_for_nullify, keys::getters::get_nsk_app, oracle::random::random, prelude::{NullifiableNote, NoteHeader, PrivateContext}, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, traits::{Empty, Eq}}, - macros::notes::partial_note + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + traits::{Empty, Eq}, + }, macros::notes::partial_note, }; #[partial_note(quote { token_id})] @@ -16,14 +18,15 @@ pub struct NFTNote { } impl NullifiableNote for NFTNote { - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -31,11 +34,8 @@ impl NullifiableNote for NFTNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } @@ -46,9 +46,7 @@ impl NFTNote { // malicious sender could use non-random values to make the note less private. But they already know the full // note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can // therefore assume that the sender will cooperate in the random value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; NFTNote { token_id, npk_m_hash, randomness, header: NoteHeader::empty() } } } diff --git a/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr b/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr index e503add82b5..141e2ad10f8 100644 --- a/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/parent_contract/src/main.nr @@ -1,4 +1,3 @@ - // A contract used along with `Child` contract to test nested calls. use dep::aztec::macros::aztec; @@ -17,41 +16,47 @@ contract Parent { fn pub_entry_point( target_contract: AztecAddress, target_selector: FunctionSelector, - init_value: Field + init_value: Field, ) -> Field { - context.call_public_function( - target_contract, - target_selector, - [init_value].as_slice(), - GasOpts::default() - ).deserialize_into() + context + .call_public_function( + target_contract, + target_selector, + [init_value].as_slice(), + GasOpts::default(), + ) + .deserialize_into() } // Same as pub_entry_point, but calls the target contract twice, using the return value from the first invocation as the argument for the second. #[public] fn pub_entry_point_twice( target_contract: AztecAddress, target_selector: FunctionSelector, - init_value: Field + init_value: Field, ) -> Field { - let return_value: Field = context.call_public_function( - target_contract, - target_selector, - [init_value].as_slice(), - GasOpts::default() - ).deserialize_into(); - context.call_public_function( - target_contract, - target_selector, - [return_value].as_slice(), - GasOpts::default() - ).deserialize_into() + let return_value: Field = context + .call_public_function( + target_contract, + target_selector, + [init_value].as_slice(), + GasOpts::default(), + ) + .deserialize_into(); + context + .call_public_function( + target_contract, + target_selector, + [return_value].as_slice(), + GasOpts::default(), + ) + .deserialize_into() } // Private function to enqueue a call to the target_contract address using the selector and argument provided #[private] fn enqueue_call_to_child( target_contract: AztecAddress, target_selector: FunctionSelector, - target_value: Field + target_value: Field, ) { context.call_public_function(target_contract, target_selector, [target_value]); } @@ -61,7 +66,7 @@ contract Parent { #[private] fn enqueue_calls_to_child_with_nested_first( target_contract: AztecAddress, - target_selector: FunctionSelector + target_selector: FunctionSelector, ) { let enqueue_call_to_child_selector = comptime { FunctionSelector::from_signature("enqueue_call_to_child((Field),(u32),Field)") @@ -69,7 +74,7 @@ contract Parent { let _ret = context.call_private_function( context.this_address(), enqueue_call_to_child_selector, - [target_contract.to_field(), target_selector.to_field(), 10] + [target_contract.to_field(), target_selector.to_field(), 10], ); context.call_public_function(target_contract, target_selector, [20]); } @@ -79,7 +84,7 @@ contract Parent { #[private] fn enqueue_calls_to_child_with_nested_last( target_contract: AztecAddress, - target_selector: FunctionSelector + target_selector: FunctionSelector, ) { context.call_public_function(target_contract, target_selector, [20]); let enqueue_call_to_child_selector = comptime { @@ -88,7 +93,7 @@ contract Parent { let _ret = context.call_private_function( context.this_address(), enqueue_call_to_child_selector, - [target_contract.to_field(), target_selector.to_field(), 10] + [target_contract.to_field(), target_selector.to_field(), 10], ); } // Private function to enqueue a call to the target_contract address using the selector and argument provided @@ -96,7 +101,7 @@ contract Parent { fn enqueue_call_to_child_twice( target_contract: AztecAddress, target_selector: FunctionSelector, - target_value: Field + target_value: Field, ) { // Enqueue the first public call context.call_public_function(target_contract, target_selector, [target_value]); @@ -108,16 +113,15 @@ contract Parent { fn enqueue_call_to_pub_entry_point( target_contract: AztecAddress, target_selector: FunctionSelector, - target_value: Field + target_value: Field, ) { - let pub_entry_point_selector = comptime { - FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") - }; + let pub_entry_point_selector = + comptime { FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") }; let this_address = context.this_address(); let _void = context.call_public_function( this_address, pub_entry_point_selector, - [target_contract.to_field(), target_selector.to_field(), target_value] + [target_contract.to_field(), target_selector.to_field(), target_value], ); } // Private function to enqueue two calls to the pub_entry_point function of this same contract, passing the target arguments provided @@ -125,28 +129,27 @@ contract Parent { fn enqueue_calls_to_pub_entry_point( target_contract: AztecAddress, target_selector: FunctionSelector, - target_value: Field + target_value: Field, ) { - let pub_entry_point_selector = comptime { - FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") - }; + let pub_entry_point_selector = + comptime { FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)") }; let this_address = context.this_address(); context.call_public_function( this_address, pub_entry_point_selector, - [target_contract.to_field(), target_selector.to_field(), target_value] + [target_contract.to_field(), target_selector.to_field(), target_value], ); context.call_public_function( this_address, pub_entry_point_selector, - [target_contract.to_field(), target_selector.to_field(), target_value + 1] + [target_contract.to_field(), target_selector.to_field(), target_value + 1], ); } #[private] fn private_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 2] + args: [Field; 2], ) -> Field { // Call the target private function context.static_call_private_function(target_contract, target_selector, args).unpack_into() @@ -155,7 +158,7 @@ contract Parent { fn private_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 2] + args: [Field; 2], ) -> Field { // Call the target private function context.call_private_function(target_contract, target_selector, args).unpack_into() @@ -165,16 +168,19 @@ contract Parent { fn private_nested_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 2] + args: [Field; 2], ) -> Field { // Call the target private function statically - let private_call_selector = FunctionSelector::from_signature("private_call((Field),(u32),[Field;2])"); + let private_call_selector = + FunctionSelector::from_signature("private_call((Field),(u32),[Field;2])"); let this_address = context.this_address(); - let return_value: Field = context.static_call_private_function( - this_address, - private_call_selector, - [target_contract.to_field(), target_selector.to_field(), args[0], args[1]] - ).unpack_into(); + let return_value: Field = context + .static_call_private_function( + this_address, + private_call_selector, + [target_contract.to_field(), target_selector.to_field(), args[0], args[1]], + ) + .unpack_into(); // Copy the return value from the call to this function's return values return_value } @@ -183,46 +189,52 @@ contract Parent { fn public_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) -> Field { - context.static_call_public_function( - target_contract, - target_selector, - args.as_slice(), - GasOpts::default() - ).deserialize_into() + context + .static_call_public_function( + target_contract, + target_selector, + args.as_slice(), + GasOpts::default(), + ) + .deserialize_into() } // Public function to set a static context and verify correct propagation for nested public calls #[public] fn public_nested_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) -> Field { // Call the target public function through the pub entrypoint statically - let pub_entry_point_selector = FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); + let pub_entry_point_selector = + FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); let this_address = context.this_address(); - context.static_call_public_function( - this_address, - pub_entry_point_selector, - [target_contract.to_field(), target_selector.to_field(), args[0]].as_slice(), - GasOpts::default() - ).deserialize_into() + context + .static_call_public_function( + this_address, + pub_entry_point_selector, + [target_contract.to_field(), target_selector.to_field(), args[0]].as_slice(), + GasOpts::default(), + ) + .deserialize_into() } // Private function to enqueue a static call to the pub_entry_point function of another contract, passing the target arguments provided #[private] fn enqueue_static_nested_call_to_pub_function( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) { // Call the target public function through the pub entrypoint statically - let pub_entry_point_selector = FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); + let pub_entry_point_selector = + FunctionSelector::from_signature("pub_entry_point((Field),(u32),Field)"); let this_address = context.this_address(); context.static_call_public_function( this_address, pub_entry_point_selector, - [target_contract.to_field(), target_selector.to_field(), args[0]] + [target_contract.to_field(), target_selector.to_field(), args[0]], ); } // Private function to enqueue a static call to the pub_entry_point function of another contract, passing the target arguments provided @@ -230,12 +242,12 @@ contract Parent { fn enqueue_static_call_to_pub_function( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) { // Call the target private function context.static_call_public_function(target_contract, target_selector, args); } - use dep::aztec::test::{helpers::{cheatcodes, test_environment::TestEnvironment}}; + use dep::aztec::test::helpers::{cheatcodes, test_environment::TestEnvironment}; use dep::aztec::protocol_types::storage::map::derive_storage_slot_in_map; use dep::aztec::note::note_getter::{MAX_NOTES_PER_PAGE, view_notes}; use dep::aztec::note::note_viewer_options::NoteViewerOptions; @@ -255,13 +267,13 @@ contract Parent { cheatcodes::advance_blocks_by(1); // Set value in child through parent let value_to_set = 7; - let result = Parent::at(parent_contract_address).private_call( - child_contract_address, - comptime { - FunctionSelector::from_signature("private_set_value(Field,(Field))") - }, - [value_to_set, owner.to_field()] - ).call(&mut env.private()); + let result = Parent::at(parent_contract_address) + .private_call( + child_contract_address, + comptime { FunctionSelector::from_signature("private_set_value(Field,(Field))") }, + [value_to_set, owner.to_field()], + ) + .call(&mut env.private()); assert(result == value_to_set); // Read the stored value in the note. We have to change the contract address to the child contract in order to read its notes env.impersonate(child_contract_address); @@ -273,13 +285,13 @@ contract Parent { assert(note_value == value_to_set); assert(note_value == result); // Get value from child through parent - let read_result = Parent::at(parent_contract_address).private_call( - child_contract_address, - comptime { - FunctionSelector::from_signature("private_get_value(Field,(Field))") - }, - [7, owner.to_field()] - ).call(&mut env.private()); + let read_result = Parent::at(parent_contract_address) + .private_call( + child_contract_address, + comptime { FunctionSelector::from_signature("private_get_value(Field,(Field))") }, + [7, owner.to_field()], + ) + .call(&mut env.private()); assert(note_value == read_result); } } diff --git a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr index c15aef6208b..c25ab29afdb 100644 --- a/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/pending_note_hashes_contract/src/main.nr @@ -7,9 +7,13 @@ use dep::aztec::macros::aztec; #[aztec] contract PendingNoteHashes { // Libs - use dep::aztec::prelude::{AztecAddress, FunctionSelector, NoteGetterOptions, PrivateContext, Map, PrivateSet}; + use dep::aztec::prelude::{ + AztecAddress, FunctionSelector, NoteGetterOptions, PrivateContext, Map, PrivateSet, + }; use dep::value_note::{filter::filter_notes_min_sum, value_note::ValueNote}; - use dep::aztec::protocol_types::constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NOTE_HASHES_PER_CALL}; + use dep::aztec::protocol_types::constants::{ + MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NOTE_HASHES_PER_CALL, + }; use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note; use dep::aztec::note::note_emission::NoteEmission; use dep::aztec::keys::getters::get_public_keys; @@ -30,7 +34,7 @@ contract PendingNoteHashes { fn test_insert_then_get_then_nullify_flat( amount: Field, owner: AztecAddress, - outgoing_viewer: AztecAddress + outgoing_viewer: AztecAddress, ) -> Field { let owner_balance = storage.balances.at(owner); @@ -40,14 +44,12 @@ contract PendingNoteHashes { let mut note = ValueNote::new(amount, owner_keys.npk_m.hash()); // Insert note - owner_balance.insert(&mut note).emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + owner_balance.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); let options = NoteGetterOptions::with_filter(filter_notes_min_sum, amount); // get note inserted above @@ -95,14 +97,12 @@ contract PendingNoteHashes { let mut note = ValueNote::new(amount, owner_keys.npk_m.hash()); // Insert note - owner_balance.insert(&mut note).emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + owner_balance.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } // Nested/inner function to create and insert a note @@ -112,7 +112,7 @@ contract PendingNoteHashes { fn insert_note_static_randomness( amount: Field, owner: AztecAddress, - outgoing_viewer: AztecAddress + outgoing_viewer: AztecAddress, ) { let mut owner_balance = storage.balances.at(owner); @@ -123,14 +123,12 @@ contract PendingNoteHashes { note.randomness = 2; // Insert note - owner_balance.insert(&mut note).emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + owner_balance.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } // Nested/inner function to create and insert a note @@ -147,24 +145,20 @@ contract PendingNoteHashes { // Insert note let emission = owner_balance.insert(&mut note); - emission.emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + emission.emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); // Emit note again - emission.emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + emission.emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } // Nested/inner function to get a note and confirm it matches the expected value @@ -200,19 +194,19 @@ contract PendingNoteHashes { owner: AztecAddress, outgoing_viewer: AztecAddress, insert_fn_selector: FunctionSelector, - get_then_nullify_fn_selector: FunctionSelector + get_then_nullify_fn_selector: FunctionSelector, ) { // nested call to create/insert note let _res = context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, - [amount, owner.to_field(), outgoing_viewer.to_field()] + [amount, owner.to_field(), outgoing_viewer.to_field()], ); // nested call to read and nullify that note let _res = context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, - [amount, owner.to_field()] + [amount, owner.to_field()], ); } @@ -223,7 +217,7 @@ contract PendingNoteHashes { owner: AztecAddress, outgoing_viewer: AztecAddress, insert_fn_selector: FunctionSelector, - get_then_nullify_fn_selector: FunctionSelector + get_then_nullify_fn_selector: FunctionSelector, ) { // args for nested calls let insertArgs = [amount, owner.to_field(), outgoing_viewer.to_field()]; @@ -233,23 +227,23 @@ contract PendingNoteHashes { let _callStackItem1 = context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, - insertArgs + insertArgs, ); let _callStackItem2 = context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, - insertArgs + insertArgs, ); // nested call to read and nullify that note let _callStackItem3 = context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, - getNullifyArgs + getNullifyArgs, ); let _callStackItem4 = context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, - getNullifyArgs + getNullifyArgs, ); // nested call to confirm that balance is zero // TODO(dbanks12): once > 4 nested calls is supported, can confirm 0 balance: @@ -263,7 +257,7 @@ contract PendingNoteHashes { owner: AztecAddress, outgoing_viewer: AztecAddress, insert_fn_selector: FunctionSelector, - get_then_nullify_fn_selector: FunctionSelector + get_then_nullify_fn_selector: FunctionSelector, ) { // args for nested calls let insertArgs = [amount, owner.to_field(), outgoing_viewer.to_field()]; @@ -273,18 +267,18 @@ contract PendingNoteHashes { let _callStackItem1 = context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, - insertArgs + insertArgs, ); let _callStackItem2 = context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, - insertArgs + insertArgs, ); // nested call to read and nullify that note let _callStackItem3 = context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, - getNullifyArgs + getNullifyArgs, ); } @@ -297,7 +291,7 @@ contract PendingNoteHashes { owner: AztecAddress, outgoing_viewer: AztecAddress, insert_fn_selector: FunctionSelector, - get_then_nullify_fn_selector: FunctionSelector + get_then_nullify_fn_selector: FunctionSelector, ) { // args for nested calls let insertArgs = [amount, owner.to_field(), outgoing_viewer.to_field()]; @@ -307,18 +301,18 @@ contract PendingNoteHashes { let _callStackItem1 = context.call_private_function( inputs.call_context.contract_address, insert_fn_selector, - insertArgs + insertArgs, ); // nested call to read and nullify that note let _callStackItem2 = context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, - getNullifyArgs + getNullifyArgs, ); let _callStackItem3 = context.call_private_function( inputs.call_context.contract_address, get_then_nullify_fn_selector, - getNullifyArgs + getNullifyArgs, ); } // Confirm cannot get/read a pending note hash in a nested call @@ -340,18 +334,20 @@ contract PendingNoteHashes { fn test_recursively_create_notes( owner: AztecAddress, outgoing_viewer: AztecAddress, - how_many_recursions: u64 + how_many_recursions: u64, ) { create_max_notes(owner, outgoing_viewer, storage, &mut context); - PendingNoteHashes::at(context.this_address()).recursively_destroy_and_create_notes(owner, outgoing_viewer, how_many_recursions).call(&mut context); + PendingNoteHashes::at(context.this_address()) + .recursively_destroy_and_create_notes(owner, outgoing_viewer, how_many_recursions) + .call(&mut context); } #[private] fn recursively_destroy_and_create_notes( owner: AztecAddress, outgoing_viewer: AztecAddress, - executions_left: u64 + executions_left: u64, ) { assert(executions_left > 0); @@ -361,7 +357,9 @@ contract PendingNoteHashes { let executions_left = executions_left - 1; if executions_left > 0 { - PendingNoteHashes::at(context.this_address()).recursively_destroy_and_create_notes(owner, outgoing_viewer, executions_left).call(&mut context); + PendingNoteHashes::at(context.this_address()) + .recursively_destroy_and_create_notes(owner, outgoing_viewer, executions_left) + .call(&mut context); } } @@ -378,14 +376,12 @@ contract PendingNoteHashes { let mut good_note = ValueNote::new(10, owner_npk_m_hash); // Insert good note with real log - owner_balance.insert(&mut good_note).emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + owner_balance.insert(&mut good_note).emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); // We will emit a note log with an incorrect preimage to ensure the pxe throws // This note has not been inserted... @@ -394,14 +390,12 @@ contract PendingNoteHashes { let existing_note_header = good_note.get_header(); bad_note.set_header(existing_note_header); - NoteEmission::new(bad_note).emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + NoteEmission::new(bad_note).emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } #[contract_library_method] @@ -409,7 +403,7 @@ contract PendingNoteHashes { owner: AztecAddress, outgoing_viewer: AztecAddress, storage: Storage<&mut PrivateContext>, - context: &mut PrivateContext + context: &mut PrivateContext, ) { let owner_balance = storage.balances.at(owner); @@ -420,7 +414,12 @@ contract PendingNoteHashes { for i in 0..max_notes_per_call() { let mut note = ValueNote::new(i as Field, owner_npk_m_hash); - owner_balance.insert(&mut note).emit(encode_and_encrypt_note(context, outgoing_viewer_ovpk_m, owner_ivpk_m, owner)); + owner_balance.insert(&mut note).emit(encode_and_encrypt_note( + context, + outgoing_viewer_ovpk_m, + owner_ivpk_m, + owner, + )); } } diff --git a/noir-projects/noir-contracts/contracts/private_fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/private_fpc_contract/src/main.nr index 2c5663962c3..c3ec2837927 100644 --- a/noir-projects/noir-contracts/contracts/private_fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/private_fpc_contract/src/main.nr @@ -7,7 +7,7 @@ contract PrivateFPC { use dep::aztec::{ protocol_types::{address::AztecAddress, hash::compute_siloed_nullifier}, state_vars::SharedImmutable, - macros::{storage::storage, functions::{private, initializer, public}} + macros::{storage::storage, functions::{private, initializer, public}}, }; use token::Token; use crate::settings::Settings; @@ -31,7 +31,9 @@ contract PrivateFPC { assert(asset == settings.other_asset); - Token::at(asset).setup_refund(settings.admin, context.msg_sender(), amount).call(&mut context); + Token::at(asset).setup_refund(settings.admin, context.msg_sender(), amount).call( + &mut context, + ); context.set_as_fee_payer(); } } diff --git a/noir-projects/noir-contracts/contracts/private_fpc_contract/src/settings.nr b/noir-projects/noir-contracts/contracts/private_fpc_contract/src/settings.nr index 3a3ea50030b..fe5a5474e01 100644 --- a/noir-projects/noir-contracts/contracts/private_fpc_contract/src/settings.nr +++ b/noir-projects/noir-contracts/contracts/private_fpc_contract/src/settings.nr @@ -15,6 +15,9 @@ impl Serialize for Settings { impl Deserialize for Settings { fn deserialize(fields: [Field; SETTINGS_LENGTH]) -> Self { - Settings { other_asset: AztecAddress::from_field(fields[0]), admin: AztecAddress::from_field(fields[1]) } + Settings { + other_asset: AztecAddress::from_field(fields[0]), + admin: AztecAddress::from_field(fields[1]), + } } } diff --git a/noir-projects/noir-contracts/contracts/router_contract/src/main.nr b/noir-projects/noir-contracts/contracts/router_contract/src/main.nr index 914b3829f75..10908953fbc 100644 --- a/noir-projects/noir-contracts/contracts/router_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/router_contract/src/main.nr @@ -15,7 +15,9 @@ contract Router { /// to the `value. #[private] fn check_timestamp(operation: u8, value: u64) { - Router::at(context.this_address())._check_timestamp(operation, value).enqueue_view(&mut context); + Router::at(context.this_address())._check_timestamp(operation, value).enqueue_view( + &mut context, + ); } #[public] @@ -32,7 +34,9 @@ contract Router { /// to the `value. #[private] fn check_block_number(operation: u8, value: Field) { - Router::at(context.this_address())._check_block_number(operation, value).enqueue_view(&mut context); + Router::at(context.this_address())._check_block_number(operation, value).enqueue_view( + &mut context, + ); } #[public] diff --git a/noir-projects/noir-contracts/contracts/router_contract/src/test.nr b/noir-projects/noir-contracts/contracts/router_contract/src/test.nr index fb4c75696a2..e8480bc0719 100644 --- a/noir-projects/noir-contracts/contracts/router_contract/src/test.nr +++ b/noir-projects/noir-contracts/contracts/router_contract/src/test.nr @@ -37,4 +37,4 @@ unconstrained fn test_fail_check_block_number() { router.check_block_number(Comparator.LT, 5).call(&mut env.private()); } -// TODO(#8372): Add test for check_timestamp --> setting timestamp currently not supported by TXE \ No newline at end of file +// TODO(#8372): Add test for check_timestamp --> setting timestamp currently not supported by TXE diff --git a/noir-projects/noir-contracts/contracts/router_contract/src/utils.nr b/noir-projects/noir-contracts/contracts/router_contract/src/utils.nr index 1258985565a..46471bf6585 100644 --- a/noir-projects/noir-contracts/contracts/router_contract/src/utils.nr +++ b/noir-projects/noir-contracts/contracts/router_contract/src/utils.nr @@ -18,4 +18,4 @@ pub fn privately_check_block_number(operation: u8, value: Field, context: &mut P Router::at(ROUTER_ADDRESS).check_block_number(operation, value).call(context); // docs:end:enqueueing } -// docs:end:helper_router_functions \ No newline at end of file +// docs:end:helper_router_functions diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr index 7a2aba19720..ddd2ae24292 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr @@ -12,11 +12,14 @@ contract SchnorrAccount { use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, - auth_witness::get_auth_witness, auth::{compute_authwit_nullifier, compute_authwit_message_hash} + auth_witness::get_auth_witness, + auth::{compute_authwit_nullifier, compute_authwit_message_hash}, }; use dep::aztec::{hash::compute_siloed_nullifier, keys::getters::get_public_keys}; use dep::aztec::oracle::get_nullifier_membership_witness::get_low_nullifier_membership_witness; - use dep::aztec::macros::{storage::storage, functions::{private, initializer, view, noinitcheck}}; + use dep::aztec::macros::{ + storage::storage, functions::{private, initializer, view, noinitcheck}, + }; use crate::public_key_note::PublicKeyNote; @@ -34,9 +37,14 @@ contract SchnorrAccount { // Not emitting outgoing for msg_sender here to not have to register keys for the contract through which we // deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that // important. - - let mut pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); - storage.signing_public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note(&mut context, this_keys.ovpk_m, this_keys.ivpk_m, this)); + let mut pub_key_note = + PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash()); + storage.signing_public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note( + &mut context, + this_keys.ovpk_m, + this_keys.ivpk_m, + this, + )); } // Note: If you globally change the entrypoint signature don't forget to update account_entrypoint.ts file @@ -62,9 +70,7 @@ contract SchnorrAccount { let storage = Storage::init(context); let public_key = storage.signing_public_key.get_note(); // Load auth witness - let witness: [Field; 64] = unsafe { - get_auth_witness(outer_hash) - }; + let witness: [Field; 64] = unsafe { get_auth_witness(outer_hash) }; let mut signature: [u8; 64] = [0; 64]; for i in 0..64 { signature[i] = witness[i] as u8; @@ -75,7 +81,7 @@ contract SchnorrAccount { public_key.x, public_key.y, signature, - outer_hash.to_be_bytes::<32>() + outer_hash.to_be_bytes::<32>(), ) // docs:end:is_valid_impl } @@ -89,7 +95,12 @@ contract SchnorrAccount { unconstrained fn lookup_validity(consumer: AztecAddress, inner_hash: Field) -> pub bool { let public_key = storage.signing_public_key.view_note(); - let message_hash = compute_authwit_message_hash(consumer, context.chain_id(), context.version(), inner_hash); + let message_hash = compute_authwit_message_hash( + consumer, + context.chain_id(), + context.version(), + inner_hash, + ); let witness: [Field; 64] = get_auth_witness(message_hash); let mut signature: [u8; 64] = [0; 64]; @@ -100,7 +111,7 @@ contract SchnorrAccount { public_key.x, public_key.y, signature, - message_hash.to_be_bytes::<32>() + message_hash.to_be_bytes::<32>(), ); // Compute the nullifier and check if it is spent @@ -108,7 +119,8 @@ contract SchnorrAccount { // it is not as part of execution of the contract, so we are good. let nullifier = compute_authwit_nullifier(context.this_address(), inner_hash); let siloed_nullifier = compute_siloed_nullifier(consumer, nullifier); - let lower_wit = get_low_nullifier_membership_witness(context.block_number(), siloed_nullifier); + let lower_wit = + get_low_nullifier_membership_witness(context.block_number(), siloed_nullifier); let is_spent = lower_wit.leaf_preimage.nullifier == siloed_nullifier; !is_spent & valid_in_private diff --git a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr index 7098b66ab11..2234c8316f2 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_account_contract/src/public_key_note.nr @@ -1,8 +1,9 @@ use dep::aztec::prelude::{NoteHeader, NullifiableNote, PrivateContext}; use dep::aztec::{ note::utils::compute_note_hash_for_nullify, keys::getters::get_nsk_app, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - macros::notes::note + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + }, macros::notes::note, }; // Stores a public key composed of two fields @@ -16,14 +17,15 @@ pub struct PublicKeyNote { } impl NullifiableNote for PublicKeyNote { - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } @@ -31,11 +33,8 @@ impl NullifiableNote for PublicKeyNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } diff --git a/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr index f61dea42972..30790f2a817 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_hardcoded_account_contract/src/main.nr @@ -7,10 +7,10 @@ contract SchnorrHardcodedAccount { use dep::aztec::prelude::PrivateContext; use dep::authwit::{ entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions, - auth_witness::get_auth_witness + auth_witness::get_auth_witness, }; - use dep::aztec::macros::{functions::{private, view}}; + use dep::aztec::macros::functions::{private, view}; global public_key_x: Field = 0x16b93f4afae55cab8507baeb8e7ab4de80f5ab1e9e1f5149bf8cd0d375451d90; global public_key_y: Field = 0x208d44b36eb6e73b254921134d002da1a90b41131024e3b1d721259182106205; @@ -33,9 +33,7 @@ contract SchnorrHardcodedAccount { #[contract_library_method] fn is_valid_impl(_context: &mut PrivateContext, outer_hash: Field) -> bool { // Load auth witness and format as an u8 array - let witness: [Field; 64] = unsafe { - get_auth_witness(outer_hash) - }; + let witness: [Field; 64] = unsafe { get_auth_witness(outer_hash) }; let mut signature: [u8; 64] = [0; 64]; for i in 0..64 { signature[i] = witness[i] as u8; @@ -46,7 +44,7 @@ contract SchnorrHardcodedAccount { public_key_x, public_key_y, signature, - outer_hash.to_be_bytes::<32>() + outer_hash.to_be_bytes::<32>(), ) } // docs:end:is-valid diff --git a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr index 92bf7d6ad45..97b1205054d 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr @@ -1,5 +1,7 @@ use dep::authwit::auth_witness; -use dep::aztec::protocol_types::{address::PartialAddress, utils::arr_copy_slice, public_keys::{PublicKeys, PUBLIC_KEYS_LENGTH}}; +use dep::aztec::protocol_types::{ + address::PartialAddress, utils::arr_copy_slice, public_keys::{PublicKeys, PUBLIC_KEYS_LENGTH}, +}; pub struct AuthWitness { keys: PublicKeys, @@ -16,7 +18,7 @@ impl AuthWitness { Self { keys: PublicKeys::deserialize(arr_copy_slice(values, [0; PUBLIC_KEYS_LENGTH], 0)), signature, - partial_address: PartialAddress::from_field(values[76]) + partial_address: PartialAddress::from_field(values[76]), } } } diff --git a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr index b9f00815f63..25a1c376799 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr @@ -11,7 +11,7 @@ contract SchnorrSingleKeyAccount { use crate::{util::recover_address, auth_oracle::get_auth_witness}; - use dep::aztec::macros::{functions::{private, view}}; + use dep::aztec::macros::functions::{private, view}; // Note: If you globally change the entrypoint signature don't forget to update account_entrypoint.ts #[private] @@ -29,9 +29,7 @@ contract SchnorrSingleKeyAccount { #[contract_library_method] fn is_valid_impl(context: &mut PrivateContext, outer_hash: Field) -> bool { - let witness = unsafe { - get_auth_witness(outer_hash) - }; + let witness = unsafe { get_auth_witness(outer_hash) }; recover_address(outer_hash, witness).eq(context.this_address()) } } diff --git a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr index 824847e2c0c..82e839cda08 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr @@ -9,7 +9,7 @@ pub fn recover_address(message_hash: Field, witness: AuthWitness) -> AztecAddres witness.keys.ivpk_m.inner.x, witness.keys.ivpk_m.inner.y, witness.signature, - message_bytes + message_bytes, ); assert(verification == true); diff --git a/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr b/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr index e6206501fee..c44c8b050aa 100644 --- a/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/spam_contract/src/main.nr @@ -8,16 +8,15 @@ contract Spam { use dep::aztec::{ prelude::{Map, AztecAddress, PublicMutable}, - encrypted_logs::{encrypted_note_emission::encode_and_encrypt_note_unconstrained}, + encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_unconstrained, keys::getters::get_public_keys, protocol_types::{ - hash::poseidon2_hash_with_separator, - constants::{ - MAX_NOTE_HASHES_PER_CALL, MAX_NULLIFIERS_PER_CALL, GENERATOR_INDEX__NOTE_NULLIFIER, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL - } - }, - macros::{storage::storage, functions::{private, public, internal}} + hash::poseidon2_hash_with_separator, + constants::{ + MAX_NOTE_HASHES_PER_CALL, MAX_NULLIFIERS_PER_CALL, GENERATOR_INDEX__NOTE_NULLIFIER, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + }, + }, macros::{storage::storage, functions::{private, public, internal}}, }; use crate::types::{token_note::TokenNote, balance_set::BalanceSet}; @@ -36,27 +35,34 @@ contract Spam { for _ in 0..MAX_NOTE_HASHES_PER_CALL { storage.balances.at(caller).add(caller_keys.npk_m, U128::from_integer(amount)).emit( - encode_and_encrypt_note_unconstrained(&mut context, caller_keys.ovpk_m, caller_keys.ivpk_m, caller) + encode_and_encrypt_note_unconstrained( + &mut context, + caller_keys.ovpk_m, + caller_keys.ivpk_m, + caller, + ), ); } for i in 0..MAX_NULLIFIERS_PER_CALL { if (i < nullifier_count) { - context.push_nullifier( - poseidon2_hash_with_separator( - [nullifier_seed, i as Field], - GENERATOR_INDEX__NOTE_NULLIFIER as Field - ) - ); + context.push_nullifier(poseidon2_hash_with_separator( + [nullifier_seed, i as Field], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, + )); } } if (call_public) { - Spam::at(context.this_address()).public_spam(0, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL).enqueue(&mut context); - Spam::at(context.this_address()).public_spam( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - ).enqueue(&mut context); + Spam::at(context.this_address()) + .public_spam(0, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL) + .enqueue(&mut context); + Spam::at(context.this_address()) + .public_spam( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + ) + .enqueue(&mut context); } } diff --git a/noir-projects/noir-contracts/contracts/spam_contract/src/types/balance_set.nr b/noir-projects/noir-contracts/contracts/spam_contract/src/types/balance_set.nr index d5f5f1a82c6..fe7840ff1ba 100644 --- a/noir-projects/noir-contracts/contracts/spam_contract/src/types/balance_set.nr +++ b/noir-projects/noir-contracts/contracts/spam_contract/src/types/balance_set.nr @@ -1,9 +1,11 @@ // This file is copied from the token contract. -use dep::aztec::prelude::{NoteGetterOptions, NoteViewerOptions, NoteInterface, NullifiableNote, PrivateSet}; +use dep::aztec::prelude::{ + NoteGetterOptions, NoteViewerOptions, NoteInterface, NullifiableNote, PrivateSet, +}; use dep::aztec::{ context::{PrivateContext, UnconstrainedContext}, protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, public_keys::NpkM}, - note::note_emission::OuterNoteEmission + note::note_emission::OuterNoteEmission, }; use crate::types::token_note::OwnedNote; @@ -19,14 +21,20 @@ impl BalanceSet { } impl BalanceSet { - pub unconstrained fn balance_of(self: Self) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote { + pub unconstrained fn balance_of(self: Self) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote, + { self.balance_of_with_offset(0) } pub unconstrained fn balance_of_with_offset( self: Self, - offset: u32 - ) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote { + offset: u32, + ) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote, + { let mut balance = U128::from_integer(0); // docs:start:view_notes let mut options = NoteViewerOptions::new(); @@ -49,8 +57,11 @@ impl BalanceSet { pub fn add( self: Self, owner_npk_m: NpkM, - addend: U128 - ) -> OuterNoteEmission where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + addend: U128, + ) -> OuterNoteEmission + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { if addend == U128::from_integer(0) { OuterNoteEmission::new(Option::none()) } else { @@ -66,8 +77,11 @@ impl BalanceSet { pub fn sub( self: Self, owner_npk_m: NpkM, - amount: U128 - ) -> OuterNoteEmission where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + amount: U128, + ) -> OuterNoteEmission + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { let subtracted = self.try_sub(amount, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL); // try_sub may have substracted more or less than amount. We must ensure that we subtracted at least as much as @@ -88,14 +102,18 @@ impl BalanceSet { pub fn try_sub( self: Self, target_amount: U128, - max_notes: u32 - ) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + max_notes: u32, + ) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { // We are using a preprocessor here (filter applied in an unconstrained context) instead of a filter because // we do not need to prove correct execution of the preprocessor. // Because the `min_sum` notes is not constrained, users could choose to e.g. not call it. However, all this // might result in is simply higher DA costs due to more nullifiers being emitted. Since we don't care // about proving optimal note usage, we can save these constraints and make the circuit smaller. - let options = NoteGetterOptions::with_preprocessor(preprocess_notes_min_sum, target_amount).set_limit(max_notes); + let options = NoteGetterOptions::with_preprocessor(preprocess_notes_min_sum, target_amount) + .set_limit(max_notes); let notes = self.set.pop_notes(options); let mut subtracted = U128::from_integer(0); @@ -117,8 +135,11 @@ impl BalanceSet { // Note that proper usage of this preprocessor requires for notes to be sorted in descending order. pub fn preprocess_notes_min_sum( notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - min_sum: U128 -) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where T: NoteInterface + NullifiableNote + OwnedNote { + min_sum: U128, +) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] +where + T: NoteInterface + NullifiableNote + OwnedNote, +{ let mut selected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; let mut sum = U128::from_integer(0); for i in 0..notes.len() { diff --git a/noir-projects/noir-contracts/contracts/spam_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/spam_contract/src/types/token_note.nr index 3879f4b603a..5108ad854b0 100644 --- a/noir-projects/noir-contracts/contracts/spam_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/spam_contract/src/types/token_note.nr @@ -1,8 +1,9 @@ use dep::aztec::{ prelude::{NoteHeader, NullifiableNote, PrivateContext}, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - note::utils::compute_note_hash_for_nullify, oracle::random::random, keys::getters::get_nsk_app, - macros::notes::note + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + }, note::utils::compute_note_hash_for_nullify, oracle::random::random, + keys::getters::get_nsk_app, macros::notes::note, }; trait OwnedNote { @@ -23,14 +24,15 @@ pub struct TokenNote { impl NullifiableNote for TokenNote { // docs:start:nullifier - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } // docs:end:nullifier @@ -40,7 +42,7 @@ impl NullifiableNote for TokenNote { let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( [note_hash_for_nullify, secret], - GENERATOR_INDEX__NOTE_NULLIFIER + GENERATOR_INDEX__NOTE_NULLIFIER, ) } } @@ -59,9 +61,7 @@ impl OwnedNote for TokenNote { // malicious sender could use non-random values to make the note less private. But they already know the full // note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can // therefore assume that the sender will cooperate in the random value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; Self { amount, npk_m_hash: owner_npk_m_hash, randomness, header: NoteHeader::empty() } } diff --git a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr index fd229a997d6..fc65d46ef8a 100644 --- a/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/stateful_test_contract/src/main.nr @@ -7,7 +7,7 @@ contract StatefulTest { use dep::value_note::{balance_utils, utils::{increment, decrement}, value_note::ValueNote}; use dep::aztec::{ initializer::assert_is_initialized_private, - macros::{storage::storage, functions::{private, public, initializer, noinitcheck, view}} + macros::{storage::storage, functions::{private, public, initializer, noinitcheck, view}}, }; #[storage] @@ -19,7 +19,9 @@ contract StatefulTest { #[private] #[initializer] fn constructor(owner: AztecAddress, outgoing_viewer: AztecAddress, value: Field) { - StatefulTest::at(context.this_address()).create_note_no_init_check(owner, outgoing_viewer, value).call(&mut context); + StatefulTest::at(context.this_address()) + .create_note_no_init_check(owner, outgoing_viewer, value) + .call(&mut context); } #[private] @@ -34,7 +36,9 @@ contract StatefulTest { #[public] #[initializer] fn public_constructor(owner: AztecAddress, _ignored_arg: AztecAddress, value: Field) { - StatefulTest::at(context.this_address()).increment_public_value_no_init_check(owner, value).call(&mut context); + StatefulTest::at(context.this_address()) + .increment_public_value_no_init_check(owner, value) + .call(&mut context); } #[private] diff --git a/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr b/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr index 0ec1b4bce79..b79a844b4c8 100644 --- a/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/static_child_contract/src/main.nr @@ -6,10 +6,10 @@ contract StaticChild { use dep::aztec::prelude::{AztecAddress, PublicMutable, PrivateSet}; use dep::aztec::{ - note::{note_getter_options::NoteGetterOptions}, + note::note_getter_options::NoteGetterOptions, encrypted_logs::encrypted_note_emission::encode_and_encrypt_note, keys::getters::get_public_keys, utils::comparison::Comparator, - macros::{storage::storage, functions::{private, public, view}} + macros::{storage::storage, functions::{private, public, view}}, }; use dep::value_note::value_note::ValueNote; @@ -49,7 +49,12 @@ contract StaticChild { let mut note = ValueNote::new(new_value, owner_keys.npk_m.hash()); - storage.a_private_value.insert(&mut note).emit(encode_and_encrypt_note(&mut context, msg_sender_keys.ovpk_m, owner_keys.ivpk_m, owner)); + storage.a_private_value.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); new_value } @@ -58,20 +63,18 @@ contract StaticChild { fn private_set_value( new_value: Field, owner: AztecAddress, - outgoing_viewer: AztecAddress + outgoing_viewer: AztecAddress, ) -> Field { let owner_keys = get_public_keys(owner); let outgoing_viewer_keys = get_public_keys(outgoing_viewer); let mut note = ValueNote::new(new_value, owner_keys.npk_m.hash()); - storage.a_private_value.insert(&mut note).emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + storage.a_private_value.insert(&mut note).emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); new_value } @@ -81,11 +84,10 @@ contract StaticChild { fn private_get_value(amount: Field, owner: AztecAddress) -> Field { let owner_npk_m_hash = get_public_keys(owner).npk_m.hash(); let mut options = NoteGetterOptions::new(); - options = options.select(ValueNote::properties().value, Comparator.EQ, amount).select( - ValueNote::properties().npk_m_hash, - Comparator.EQ, - owner_npk_m_hash - ).set_limit(1); + options = options + .select(ValueNote::properties().value, Comparator.EQ, amount) + .select(ValueNote::properties().npk_m_hash, Comparator.EQ, owner_npk_m_hash) + .set_limit(1); let notes = storage.a_private_value.get_notes(options); notes.get(0).value } diff --git a/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr b/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr index d363d073fb0..e0d371cbd23 100644 --- a/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/static_parent_contract/src/main.nr @@ -1,4 +1,3 @@ - // A contract used along with `StaticChild` contract to test static calls. use dep::aztec::macros::aztec; @@ -13,14 +12,16 @@ contract StaticParent { fn public_call( target_contract: AztecAddress, target_selector: FunctionSelector, - arg: Field + arg: Field, ) -> Field { - context.call_public_function( - target_contract, - target_selector, - [arg].as_slice(), - GasOpts::default() - ).deserialize_into() + context + .call_public_function( + target_contract, + target_selector, + [arg].as_slice(), + GasOpts::default(), + ) + .deserialize_into() } // Private function to directly call another private function to the target_contract using the selector and args provided @@ -28,7 +29,7 @@ contract StaticParent { fn private_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 2] + args: [Field; 2], ) -> Field { context.call_private_function(target_contract, target_selector, args).unpack_into() } @@ -38,7 +39,7 @@ contract StaticParent { fn private_call_3_args( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 3] + args: [Field; 3], ) -> Field { context.call_private_function(target_contract, target_selector, args).unpack_into() } @@ -48,7 +49,7 @@ contract StaticParent { fn enqueue_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) { context.call_public_function(target_contract, target_selector, args); } @@ -57,7 +58,7 @@ contract StaticParent { fn private_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 2] + args: [Field; 2], ) -> Field { context.static_call_private_function(target_contract, target_selector, args).unpack_into() } @@ -67,7 +68,7 @@ contract StaticParent { fn private_static_call_3_args( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 3] + args: [Field; 3], ) -> Field { context.static_call_private_function(target_contract, target_selector, args).unpack_into() } @@ -77,7 +78,7 @@ contract StaticParent { fn private_get_value_from_child( target_contract: AztecAddress, value: Field, - owner: AztecAddress + owner: AztecAddress, ) -> Field { StaticChild::at(target_contract).private_get_value(value, owner).view(&mut context) } @@ -87,9 +88,11 @@ contract StaticParent { fn private_nested_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 2] + args: [Field; 2], ) -> Field { - StaticParent::at(context.this_address()).private_call(target_contract, target_selector, args).view(&mut context) + StaticParent::at(context.this_address()) + .private_call(target_contract, target_selector, args) + .view(&mut context) } // Just like function above but with 3 args. @@ -97,9 +100,11 @@ contract StaticParent { fn private_nested_static_call_3_args( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 3] + args: [Field; 3], ) -> Field { - StaticParent::at(context.this_address()).private_call_3_args(target_contract, target_selector, args).view(&mut context) + StaticParent::at(context.this_address()) + .private_call_3_args(target_contract, target_selector, args) + .view(&mut context) } // Public function to statically call another public function to the target_contract using the selector and value provided @@ -107,14 +112,16 @@ contract StaticParent { fn public_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) -> Field { - context.static_call_public_function( - target_contract, - target_selector, - args.as_slice(), - GasOpts::default() - ).deserialize_into() + context + .static_call_public_function( + target_contract, + target_selector, + args.as_slice(), + GasOpts::default(), + ) + .deserialize_into() } // Same as above but using a specific function from the interface @@ -128,10 +135,12 @@ contract StaticParent { fn public_nested_static_call( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) -> Field { // Call the target public function through the pub entrypoint statically - StaticParent::at(context.this_address()).public_call(target_contract, target_selector, args[0]).view(&mut context) + StaticParent::at(context.this_address()) + .public_call(target_contract, target_selector, args[0]) + .view(&mut context) } // Private function to enqueue a static call to a public function of another contract, passing the target arguments provided @@ -139,7 +148,7 @@ contract StaticParent { fn enqueue_static_call_to_pub_function( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) { context.static_call_public_function(target_contract, target_selector, args); } @@ -155,9 +164,11 @@ contract StaticParent { fn enqueue_static_nested_call_to_pub_function( target_contract: AztecAddress, target_selector: FunctionSelector, - args: [Field; 1] + args: [Field; 1], ) { // Call the target public function through the pub entrypoint statically - StaticParent::at(context.this_address()).public_call(target_contract, target_selector, args[0]).enqueue_view(&mut context) + StaticParent::at(context.this_address()) + .public_call(target_contract, target_selector, args[0]) + .enqueue_view(&mut context) } } diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr index 111f8fad6db..88977b9c7f7 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/main.nr @@ -8,12 +8,15 @@ contract Test { use dep::aztec::prelude::{ AztecAddress, EthAddress, FunctionSelector, NoteGetterOptions, NoteViewerOptions, - PrivateImmutable, PrivateSet + PrivateImmutable, PrivateSet, }; use dep::aztec::encrypted_logs::encrypted_note_emission::encode_and_encrypt_note; use dep::aztec::encrypted_logs::encrypted_event_emission::encode_and_encrypt_event_with_randomness_unconstrained; - use dep::aztec::protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, traits::Serialize, point::Point, public_keys::IvpkM}; + use dep::aztec::protocol_types::{ + constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, traits::Serialize, point::Point, + public_keys::IvpkM, + }; use dep::aztec::note::constants::MAX_NOTES_PER_PAGE; use dep::aztec::keys::getters::get_public_keys; @@ -21,14 +24,15 @@ contract Test { use dep::aztec::{ hash::{pedersen_hash, compute_secret_hash, ArgsHasher}, note::{ - lifecycle::{create_note, destroy_note_unsafe}, note_getter::{get_notes, view_notes}, - note_getter_options::NoteStatus - }, - deploy::deploy_contract as aztec_deploy_contract, oracle::random::random, + lifecycle::{create_note, destroy_note_unsafe}, note_getter::{get_notes, view_notes}, + note_getter_options::NoteStatus, + }, deploy::deploy_contract as aztec_deploy_contract, oracle::random::random, utils::comparison::Comparator, - macros::{storage::storage, events::event, functions::{private, public, internal}} + macros::{storage::storage, events::event, functions::{private, public, internal}}, + }; + use dep::token_portal_content_hash_lib::{ + get_mint_private_content_hash, get_mint_public_content_hash, }; - use dep::token_portal_content_hash_lib::{get_mint_private_content_hash, get_mint_public_content_hash}; use dep::value_note::value_note::ValueNote; // TODO investigate why the macros require EmbeddedCurvePoint and EmbeddedCurveScalar use std::embedded_curve_ops::{EmbeddedCurveScalar, EmbeddedCurvePoint}; @@ -88,30 +92,30 @@ contract Test { value: Field, owner: AztecAddress, outgoing_viewer: AztecAddress, - storage_slot: Field + storage_slot: Field, ) { assert( - storage_slot != storage.example_constant.get_storage_slot(), "this storage slot is reserved for example_constant" + storage_slot != storage.example_constant.get_storage_slot(), + "this storage slot is reserved for example_constant", ); let outgoing_viewer_keys = get_public_keys(outgoing_viewer); let owner_keys = get_public_keys(owner); let mut note = ValueNote::new(value, owner_keys.npk_m.hash()); - create_note(&mut context, storage_slot, &mut note).emit( - encode_and_encrypt_note( - &mut context, - outgoing_viewer_keys.ovpk_m, - owner_keys.ivpk_m, - owner - ) - ); + create_note(&mut context, storage_slot, &mut note).emit(encode_and_encrypt_note( + &mut context, + outgoing_viewer_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); } #[private] fn call_get_notes(storage_slot: Field, active_or_nullified: bool) -> Field { assert( - storage_slot != storage.example_constant.get_storage_slot(), "this storage slot is reserved for example_constant" + storage_slot != storage.example_constant.get_storage_slot(), + "this storage slot is reserved for example_constant", ); let mut options = NoteGetterOptions::new(); @@ -119,7 +123,8 @@ contract Test { options = options.set_status(NoteStatus.ACTIVE_OR_NULLIFIED); } - let (notes, _): (BoundedVec, BoundedVec) = get_notes(&mut context, storage_slot, options); + let (notes, _): (BoundedVec, BoundedVec) = + get_notes(&mut context, storage_slot, options); notes.get(0).value } @@ -127,7 +132,8 @@ contract Test { #[private] fn call_get_notes_many(storage_slot: Field, active_or_nullified: bool) -> [Field; 2] { assert( - storage_slot != storage.example_constant.get_storage_slot(), "this storage slot is reserved for example_constant" + storage_slot != storage.example_constant.get_storage_slot(), + "this storage slot is reserved for example_constant", ); let mut options = NoteGetterOptions::new(); @@ -135,14 +141,16 @@ contract Test { options = options.set_status(NoteStatus.ACTIVE_OR_NULLIFIED); } - let (notes, _): (BoundedVec, BoundedVec) = get_notes(&mut context, storage_slot, options); + let (notes, _): (BoundedVec, BoundedVec) = + get_notes(&mut context, storage_slot, options); [notes.get(0).value, notes.get(1).value] } unconstrained fn call_view_notes(storage_slot: Field, active_or_nullified: bool) -> pub Field { assert( - storage_slot != storage.example_constant.get_storage_slot(), "this storage slot is reserved for example_constant" + storage_slot != storage.example_constant.get_storage_slot(), + "this storage slot is reserved for example_constant", ); let mut options = NoteViewerOptions::new(); @@ -155,9 +163,13 @@ contract Test { notes.get(0).value } - unconstrained fn call_view_notes_many(storage_slot: Field, active_or_nullified: bool) -> pub [Field; 2] { + unconstrained fn call_view_notes_many( + storage_slot: Field, + active_or_nullified: bool, + ) -> pub [Field; 2] { assert( - storage_slot != storage.example_constant.get_storage_slot(), "this storage slot is reserved for example_constant" + storage_slot != storage.example_constant.get_storage_slot(), + "this storage slot is reserved for example_constant", ); let mut options = NoteViewerOptions::new(); @@ -173,11 +185,13 @@ contract Test { #[private] fn call_destroy_note(storage_slot: Field) { assert( - storage_slot != storage.example_constant.get_storage_slot(), "this storage slot is reserved for example_constant" + storage_slot != storage.example_constant.get_storage_slot(), + "this storage slot is reserved for example_constant", ); let options = NoteGetterOptions::new(); - let (notes, note_hashes): (BoundedVec, BoundedVec) = get_notes(&mut context, storage_slot, options); + let (notes, note_hashes): (BoundedVec, BoundedVec) = + get_notes(&mut context, storage_slot, options); let note = notes.get(0); let note_hash = note_hashes.get(0); @@ -192,7 +206,7 @@ contract Test { a_number: u32, an_array: [Field; 2], a_struct: DummyNote, - a_deep_struct: DeepStruct + a_deep_struct: DeepStruct, ) -> Field { let mut args = ArgsHasher::new(); args.add(a_field); @@ -216,10 +230,8 @@ contract Test { fn test_setting_teardown() { context.set_public_teardown_function( context.this_address(), - comptime { - FunctionSelector::from_signature("dummy_public_call()") - }, - [] + comptime { FunctionSelector::from_signature("dummy_public_call()") }, + [], ); } @@ -230,7 +242,11 @@ contract Test { // Purely exists for testing #[public] - fn create_l2_to_l1_message_public(amount: Field, secret_hash: Field, portal_address: EthAddress) { + fn create_l2_to_l1_message_public( + amount: Field, + secret_hash: Field, + portal_address: EthAddress, + ) { // Create a commitment to the amount let note = DummyNote::new(amount, secret_hash); @@ -268,57 +284,74 @@ contract Test { fields: [Field; 5], owner: AztecAddress, outgoing_viewer: AztecAddress, - nest: bool + nest: bool, ) { let owner_ivpk_m = get_public_keys(owner).ivpk_m; let outgoing_viewer_ovpk_m = get_public_keys(outgoing_viewer).ovpk_m; - let event = ExampleEvent { value0: fields[0], value1: fields[1], value2: fields[2], value3: fields[3], value4: fields[4] }; - - event.emit( - encode_and_encrypt_event_with_randomness_unconstrained( - &mut context, - // testing only - a secret random value is passed in here to salt / mask the address - 5, - outgoing_viewer_ovpk_m, - owner_ivpk_m, - owner - ) - ); + let event = ExampleEvent { + value0: fields[0], + value1: fields[1], + value2: fields[2], + value3: fields[3], + value4: fields[4], + }; + + event.emit(encode_and_encrypt_event_with_randomness_unconstrained( + &mut context, + // testing only - a secret random value is passed in here to salt / mask the address + 5, + outgoing_viewer_ovpk_m, + owner_ivpk_m, + owner, + )); // this contract has reached max number of functions, so using this one fn // to test nested and non nested encrypted logs if nest { - Test::at(context.this_address()).emit_array_as_encrypted_log([0, 0, 0, 0, 0], owner, outgoing_viewer, false).call(&mut context); + Test::at(context.this_address()) + .emit_array_as_encrypted_log([0, 0, 0, 0, 0], owner, outgoing_viewer, false) + .call(&mut context); let otherEvent = ExampleEvent { value0: 1, value1: 2, value2: 3, value3: 4, value4: 5 }; - otherEvent.emit( - encode_and_encrypt_event_with_randomness_unconstrained( - &mut context, - // testing only - a randomness of 0 signals the kernels to not mask the address - 0, - outgoing_viewer_ovpk_m, - owner_ivpk_m, - owner - ) - ); + otherEvent.emit(encode_and_encrypt_event_with_randomness_unconstrained( + &mut context, + // testing only - a randomness of 0 signals the kernels to not mask the address + 0, + outgoing_viewer_ovpk_m, + owner_ivpk_m, + owner, + )); } } #[private] - fn emit_encrypted_logs_nested(value: Field, owner: AztecAddress, outgoing_viewer: AztecAddress) { + fn emit_encrypted_logs_nested( + value: Field, + owner: AztecAddress, + outgoing_viewer: AztecAddress, + ) { let mut storage_slot = storage.example_constant.get_storage_slot() + 1; - Test::at(context.this_address()).call_create_note(value, owner, outgoing_viewer, storage_slot).call(&mut context); + Test::at(context.this_address()) + .call_create_note(value, owner, outgoing_viewer, storage_slot) + .call(&mut context); storage_slot += 1; let msg_sender_keys = get_public_keys(context.msg_sender()); let owner_keys = get_public_keys(owner); let mut note = ValueNote::new(value + 1, owner_keys.npk_m.hash()); - create_note(&mut context, storage_slot, &mut note).emit(encode_and_encrypt_note(&mut context, msg_sender_keys.ovpk_m, owner_keys.ivpk_m, owner)); + create_note(&mut context, storage_slot, &mut note).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + owner_keys.ivpk_m, + owner, + )); storage_slot += 1; - Test::at(context.this_address()).call_create_note(value + 2, owner, outgoing_viewer, storage_slot).call(&mut context); + Test::at(context.this_address()) + .call_create_note(value + 2, owner, outgoing_viewer, storage_slot) + .call(&mut context); } // docs:start:is-time-equal @@ -332,9 +365,9 @@ contract Test { #[public] fn emit_unencrypted(value: Field) { // docs:start:emit_unencrypted - context.emit_unencrypted_log(/*message=*/ value); - context.emit_unencrypted_log(/*message=*/ [10, 20, 30]); - context.emit_unencrypted_log(/*message=*/ "Hello, world!"); + context.emit_unencrypted_log( /*message=*/ value); + context.emit_unencrypted_log( /*message=*/ [10, 20, 30]); + context.emit_unencrypted_log( /*message=*/ "Hello, world!"); // docs:end:emit_unencrypted } @@ -344,7 +377,7 @@ contract Test { amount: Field, secret: Field, message_leaf_index: Field, - portal_address: EthAddress + portal_address: EthAddress, ) { let content_hash = get_mint_public_content_hash(to, amount); // Consume message and emit nullifier @@ -356,14 +389,15 @@ contract Test { secret_hash_for_redeeming_minted_notes: Field, amount: Field, secret_for_L1_to_L2_message_consumption: Field, - portal_address: EthAddress + portal_address: EthAddress, ) { // Consume L1 to L2 message and emit nullifier - let content_hash = get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes, amount); + let content_hash = + get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes, amount); context.consume_l1_to_l2_message( content_hash, secret_for_L1_to_L2_message_consumption, - portal_address + portal_address, ); } @@ -372,14 +406,18 @@ contract Test { content: Field, secret: Field, sender: EthAddress, - message_leaf_index: Field + message_leaf_index: Field, ) { // Consume message and emit nullifier context.consume_l1_to_l2_message(content, secret, sender, message_leaf_index); } #[private] - fn consume_message_from_arbitrary_sender_private(content: Field, secret: Field, sender: EthAddress) { + fn consume_message_from_arbitrary_sender_private( + content: Field, + secret: Field, + sender: EthAddress, + ) { // Consume message and emit nullifier context.consume_l1_to_l2_message(content, secret, sender); } @@ -403,7 +441,7 @@ contract Test { block_number: Field, timestamp: u64, fee_per_da_gas: Field, - fee_per_l2_gas: Field + fee_per_l2_gas: Field, ) { assert(context.chain_id() == chain_id, "Invalid chain id"); assert(context.version() == version, "Invalid version"); @@ -435,7 +473,8 @@ contract Test { let notes_set = storage.example_set; let secret_hash = compute_secret_hash(secret); let mut options = NoteGetterOptions::new(); - options = options.select(TestNote::properties().value, Comparator.EQ, secret_hash).set_limit(1); + options = + options.select(TestNote::properties().value, Comparator.EQ, secret_hash).set_limit(1); let notes = notes_set.pop_notes(options); assert(notes.len() == 1, "note not popped"); } @@ -457,7 +496,7 @@ contract Test { pub struct DummyNote { amount: Field, - secret_hash: Field + secret_hash: Field, } impl DummyNote { diff --git a/noir-projects/noir-contracts/contracts/test_contract/src/test_note.nr b/noir-projects/noir-contracts/contracts/test_contract/src/test_note.nr index 8092554dad4..66796939be9 100644 --- a/noir-projects/noir-contracts/contracts/test_contract/src/test_note.nr +++ b/noir-projects/noir-contracts/contracts/test_contract/src/test_note.nr @@ -1,6 +1,6 @@ use dep::aztec::{ note::{note_header::NoteHeader, note_interface::NullifiableNote}, context::PrivateContext, - macros::notes::note + macros::notes::note, }; // A note which stores a field and is expected to be passed around using the `addNote` function. @@ -14,7 +14,11 @@ pub struct TestNote { impl NullifiableNote for TestNote { - fn compute_nullifier(_self: Self, _context: &mut PrivateContext, _note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + _self: Self, + _context: &mut PrivateContext, + _note_hash_for_nullify: Field, + ) -> Field { // This note is expected to be shared between users and fstructor this reason can't be nullified using a secret. 0 } diff --git a/noir-projects/noir-contracts/contracts/test_log_contract/src/main.nr b/noir-projects/noir-contracts/contracts/test_log_contract/src/main.nr index 4c685a0a93c..d94213d9349 100644 --- a/noir-projects/noir-contracts/contracts/test_log_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/test_log_contract/src/main.nr @@ -42,41 +42,38 @@ contract TestLog { let other_keys = get_public_keys(other); let msg_sender_keys = get_public_keys(context.msg_sender()); - event0.emit( - encode_and_encrypt_event_with_randomness( - &mut context, - randomness[0], - // outgoing is set to other, incoming is set to msg sender - other_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) - ); + event0.emit(encode_and_encrypt_event_with_randomness( + &mut context, + randomness[0], + // outgoing is set to other, incoming is set to msg sender + other_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); // We duplicate the emission, but specifying different incoming and outgoing parties - event0.emit( - encode_and_encrypt_event_with_randomness( - &mut context, - randomness[0], - // outgoing is set to msg sender, incoming is set to other - msg_sender_keys.ovpk_m, - other_keys.ivpk_m, - other - ) - ); - - let event1 = ExampleEvent1 { value2: AztecAddress::from_field(preimages[2]), value3: preimages[3] as u8 }; - - event1.emit( - encode_and_encrypt_event_with_randomness( - &mut context, - randomness[1], - // outgoing is set to other, incoming is set to msg sender - other_keys.ovpk_m, - msg_sender_keys.ivpk_m, - context.msg_sender() - ) - ); + event0.emit(encode_and_encrypt_event_with_randomness( + &mut context, + randomness[0], + // outgoing is set to msg sender, incoming is set to other + msg_sender_keys.ovpk_m, + other_keys.ivpk_m, + other, + )); + + let event1 = ExampleEvent1 { + value2: AztecAddress::from_field(preimages[2]), + value3: preimages[3] as u8, + }; + + event1.emit(encode_and_encrypt_event_with_randomness( + &mut context, + randomness[1], + // outgoing is set to other, incoming is set to msg sender + other_keys.ovpk_m, + msg_sender_keys.ivpk_m, + context.msg_sender(), + )); } #[public] @@ -85,7 +82,10 @@ contract TestLog { event0.emit(encode_event(&mut context)); - let event1 = ExampleEvent1 { value2: AztecAddress::from_field(preimages[2]), value3: preimages[3] as u8 }; + let event1 = ExampleEvent1 { + value2: AztecAddress::from_field(preimages[2]), + value3: preimages[3] as u8, + }; event1.emit(encode_event(&mut context)); } diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr index 7640690f749..b7ff9f52f94 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/main.nr @@ -16,15 +16,21 @@ contract TokenBlacklist { use dep::aztec::{ hash::compute_secret_hash, prelude::{AztecAddress, Map, NoteGetterOptions, PrivateSet, PublicMutable, SharedMutable}, - encrypted_logs::encrypted_note_emission::{encode_and_encrypt_note_unconstrained, encode_and_encrypt_note}, - utils::comparison::Comparator, + encrypted_logs::encrypted_note_emission::{ + encode_and_encrypt_note_unconstrained, encode_and_encrypt_note, + }, utils::comparison::Comparator, macros::{storage::storage, functions::{private, public, initializer, view, internal}}, - keys::getters::get_public_keys + keys::getters::get_public_keys, }; - use dep::authwit::{auth::{assert_current_call_valid_authwit, assert_current_call_valid_authwit_public}}; + use dep::authwit::auth::{ + assert_current_call_valid_authwit, assert_current_call_valid_authwit_public, + }; - use crate::types::{transparent_note::TransparentNote, token_note::TokenNote, balances_map::BalancesMap, roles::UserFlags}; + use crate::types::{ + transparent_note::TransparentNote, token_note::TokenNote, balances_map::BalancesMap, + roles::UserFlags, + }; // Changing an address' roles has a certain block delay before it goes into effect. global CHANGE_ROLES_DELAY_BLOCKS: u32 = 2; @@ -173,11 +179,10 @@ contract TokenBlacklist { // Pop 1 note (set_limit(1)) which has an amount stored in a field with index 0 (select(0, amount)) and // a secret_hash stored in a field with index 1 (select(1, secret_hash)). let mut options = NoteGetterOptions::new(); - options = options.select(TransparentNote::properties().amount, Comparator.EQ, amount).select( - TransparentNote::properties().secret_hash, - Comparator.EQ, - secret_hash - ).set_limit(1); + options = options + .select(TransparentNote::properties().amount, Comparator.EQ, amount) + .select(TransparentNote::properties().secret_hash, Comparator.EQ, secret_hash) + .set_limit(1); let notes = storage.pending_shields.pop_notes(options); assert(notes.len() == 1, "note not popped"); @@ -185,7 +190,12 @@ contract TokenBlacklist { // Add the token note to user's balances set let msg_sender_keys = get_public_keys(context.msg_sender()); let to_keys = get_public_keys(to); - storage.balances.add(to, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, msg_sender_keys.ovpk_m, to_keys.ivpk_m, to)); + storage.balances.add(to, U128::from_integer(amount)).emit(encode_and_encrypt_note( + &mut context, + msg_sender_keys.ovpk_m, + to_keys.ivpk_m, + to, + )); } #[private] @@ -202,9 +212,16 @@ contract TokenBlacklist { } let from_keys = get_public_keys(from); - storage.balances.sub(from, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); - - TokenBlacklist::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); + storage.balances.sub(from, U128::from_integer(amount)).emit(encode_and_encrypt_note( + &mut context, + from_keys.ovpk_m, + from_keys.ivpk_m, + from, + )); + + TokenBlacklist::at(context.this_address())._increase_public_balance(to, amount).enqueue( + &mut context, + ); } // docs:start:transfer_private @@ -225,10 +242,18 @@ contract TokenBlacklist { let to_keys = get_public_keys(to); let amount = U128::from_integer(amount); - storage.balances.sub(from, amount).emit( - encode_and_encrypt_note_unconstrained(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from) - ); - storage.balances.add(to, amount).emit(encode_and_encrypt_note_unconstrained(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); + storage.balances.sub(from, amount).emit(encode_and_encrypt_note_unconstrained( + &mut context, + from_keys.ovpk_m, + from_keys.ivpk_m, + from, + )); + storage.balances.add(to, amount).emit(encode_and_encrypt_note_unconstrained( + &mut context, + from_keys.ovpk_m, + to_keys.ivpk_m, + to, + )); } #[private] @@ -243,7 +268,12 @@ contract TokenBlacklist { } let from_keys = get_public_keys(from); - storage.balances.sub(from, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); + storage.balances.sub(from, U128::from_integer(amount)).emit(encode_and_encrypt_note( + &mut context, + from_keys.ovpk_m, + from_keys.ivpk_m, + from, + )); TokenBlacklist::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); } diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr index 2c7b6fbd21f..b7f1ae7206a 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/balances_map.nr @@ -1,13 +1,16 @@ -use dep::aztec::prelude::{AztecAddress, NoteGetterOptions, NoteViewerOptions, NoteInterface, NullifiableNote, PrivateSet, Map}; +use dep::aztec::prelude::{ + AztecAddress, NoteGetterOptions, NoteViewerOptions, NoteInterface, NullifiableNote, PrivateSet, + Map, +}; use dep::aztec::{ context::{PrivateContext, UnconstrainedContext}, protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - note::{note_emission::OuterNoteEmission}, keys::getters::get_public_keys + note::note_emission::OuterNoteEmission, keys::getters::get_public_keys, }; -use crate::types::{token_note::OwnedNote}; +use crate::types::token_note::OwnedNote; pub struct BalancesMap { - map: Map, Context> + map: Map, Context>, } impl BalancesMap { @@ -17,8 +20,8 @@ impl BalancesMap { map: Map::new( context, storage_slot, - |context, slot| PrivateSet::new(context, slot) - ) + |context, slot| PrivateSet::new(context, slot), + ), } } } @@ -26,16 +29,22 @@ impl BalancesMap { impl BalancesMap { pub unconstrained fn balance_of( self: Self, - owner: AztecAddress - ) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote { + owner: AztecAddress, + ) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote, + { self.balance_of_with_offset(owner, 0) } pub unconstrained fn balance_of_with_offset( self: Self, owner: AztecAddress, - offset: u32 - ) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote { + offset: u32, + ) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote, + { let mut balance = U128::from_integer(0); // docs:start:view_notes let mut options = NoteViewerOptions::new(); @@ -59,8 +68,11 @@ impl BalancesMap { pub fn add( self: Self, owner: AztecAddress, - addend: U128 - ) -> OuterNoteEmission where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + addend: U128, + ) -> OuterNoteEmission + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { if addend == U128::from_integer(0) { OuterNoteEmission::new(Option::none()) } else { @@ -79,8 +91,11 @@ impl BalancesMap { pub fn sub( self: Self, owner: AztecAddress, - subtrahend: U128 - ) -> OuterNoteEmission where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + subtrahend: U128, + ) -> OuterNoteEmission + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend); let notes = self.map.at(owner).pop_notes(options); @@ -103,8 +118,11 @@ impl BalancesMap { pub fn filter_notes_min_sum( notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - min_sum: U128 -) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where T: NoteInterface + OwnedNote { + min_sum: U128, +) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] +where + T: NoteInterface + OwnedNote, +{ let mut selected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; let mut sum = U128::from_integer(0); for i in 0..notes.len() { diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/roles.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/roles.nr index 565f709cb8d..e27898f0a57 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/roles.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/roles.nr @@ -64,7 +64,11 @@ impl Serialize<3> for UserFlags { // after having received the serialized value as a return-value impl Deserialize<3> for UserFlags { fn deserialize(fields: [Field; 3]) -> Self { - Self { is_admin: fields[0] as bool, is_minter: fields[1] as bool, is_blacklisted: fields[2] as bool } + Self { + is_admin: fields[0] as bool, + is_minter: fields[1] as bool, + is_blacklisted: fields[2] as bool, + } } } diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr index 8345b91b36b..16b1fe92e64 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/token_note.nr @@ -1,8 +1,9 @@ use dep::aztec::{ prelude::{NoteHeader, NullifiableNote, PrivateContext}, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - note::utils::compute_note_hash_for_nullify, oracle::random::random, keys::getters::get_nsk_app, - macros::notes::note + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + }, note::utils::compute_note_hash_for_nullify, oracle::random::random, + keys::getters::get_nsk_app, macros::notes::note, }; trait OwnedNote { @@ -22,14 +23,15 @@ pub struct TokenNote { impl NullifiableNote for TokenNote { // docs:start:nullifier - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } // docs:end:nullifier @@ -38,11 +40,8 @@ impl NullifiableNote for TokenNote { let note_hash_for_nullify = compute_note_hash_for_nullify(self); let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } } @@ -61,9 +60,7 @@ impl OwnedNote for TokenNote { // malicious sender could use non-random values to make the note less private. But they already know the full // note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can // therefore assume that the sender will cooperate in the random value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; Self { amount, npk_m_hash: owner_npk_m_hash, randomness, header: NoteHeader::empty() } } diff --git a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr index 5b440c545b2..77ea426a53f 100644 --- a/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr +++ b/noir-projects/noir-contracts/contracts/token_blacklist_contract/src/types/transparent_note.nr @@ -2,8 +2,9 @@ use dep::aztec::{ note::{note_getter_options::PropertySelector, utils::compute_note_hash_for_nullify}, prelude::{NoteHeader, NullifiableNote, PrivateContext}, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - macros::notes::note + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + }, macros::notes::note, }; use dep::std::mem::zeroed; @@ -27,11 +28,15 @@ impl NullifiableNote for TransparentNote { // 3) the "get_notes" oracle constrains that the secret hash in the returned note matches the one computed in // circuit. // This achieves that the note can only be spent by the party that knows the secret. - fn compute_nullifier(self, _context: &mut PrivateContext, _note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + _context: &mut PrivateContext, + _note_hash_for_nullify: Field, + ) -> Field { let note_hash_for_nullify = compute_note_hash_for_nullify(self); poseidon2_hash_with_separator( [note_hash_for_nullify], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } diff --git a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr index a15be88cb4c..e83b07118ab 100644 --- a/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_bridge_contract/src/main.nr @@ -11,11 +11,15 @@ use dep::aztec::macros::aztec; contract TokenBridge { use dep::aztec::prelude::{AztecAddress, EthAddress, PublicMutable, SharedImmutable}; - use dep::token_portal_content_hash_lib::{get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash}; + use dep::token_portal_content_hash_lib::{ + get_mint_public_content_hash, get_mint_private_content_hash, get_withdraw_content_hash, + }; use dep::token::Token; - use dep::aztec::macros::{storage::storage, functions::{public, initializer, private, internal, view}}; + use dep::aztec::macros::{ + storage::storage, functions::{public, initializer, private, internal, view}, + }; // docs:end:token_bridge_imports // docs:start:token_bridge_storage_and_constructor @@ -56,7 +60,7 @@ contract TokenBridge { content_hash, secret, storage.portal_address.read_public(), - message_leaf_index + message_leaf_index, ); // Mint tokens @@ -72,14 +76,16 @@ contract TokenBridge { recipient: EthAddress, // ethereum address to withdraw to amount: Field, caller_on_l1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) - nonce: Field // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 + nonce: Field, // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient, amount, caller_on_l1); context.message_portal(storage.portal_address.read_public(), content); // Burn tokens - Token::at(storage.token.read()).burn_public(context.msg_sender(), amount, nonce).call(&mut context); + Token::at(storage.token.read()).burn_public(context.msg_sender(), amount, nonce).call( + &mut context, + ); } // docs:end:exit_to_l1_public // docs:start:claim_private @@ -90,21 +96,24 @@ contract TokenBridge { fn claim_private( secret_hash_for_redeeming_minted_notes: Field, // secret hash used to redeem minted notes at a later time. This enables anyone to call this function and mint tokens to a user on their behalf amount: Field, - secret_for_L1_to_L2_message_consumption: Field // secret used to consume the L1 to L2 message + secret_for_L1_to_L2_message_consumption: Field, // secret used to consume the L1 to L2 message ) { // Consume L1 to L2 message and emit nullifier - let content_hash = get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes, amount); + let content_hash = + get_mint_private_content_hash(secret_hash_for_redeeming_minted_notes, amount); context.consume_l1_to_l2_message( content_hash, secret_for_L1_to_L2_message_consumption, - storage.portal_address.read_private() + storage.portal_address.read_private(), ); // Mint tokens on L2 // `mint_private` on token is public. So we call an internal public function // which then calls the public method on the token contract. // Since the secret_hash is passed, no secret is leaked. - TokenBridge::at(context.this_address())._call_mint_on_token(amount, secret_hash_for_redeeming_minted_notes).enqueue(&mut context); + TokenBridge::at(context.this_address()) + ._call_mint_on_token(amount, secret_hash_for_redeeming_minted_notes) + .enqueue(&mut context); } // docs:end:claim_private @@ -117,7 +126,7 @@ contract TokenBridge { recipient: EthAddress, // ethereum address to withdraw to amount: Field, caller_on_l1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) - nonce: Field // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 + nonce: Field, // nonce used in the approval message by `msg.sender` to let bridge burn their tokens on L2 ) { // Send an L2 to L1 message let content = get_withdraw_content_hash(recipient, amount, caller_on_l1); @@ -127,7 +136,6 @@ contract TokenBridge { // Assert that user provided token address is same as seen in storage. TokenBridge::at(context.this_address())._assert_token_is_same(token).enqueue(&mut context); // docs:end:call_assert_token_is_same - // Burn tokens Token::at(token).burn(context.msg_sender(), amount, nonce).call(&mut context); } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr index d75568733e5..e69d0fedec6 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/main.nr @@ -21,21 +21,32 @@ contract Token { use dep::aztec::{ context::{PrivateContext, PrivateCallInterface}, hash::compute_secret_hash, oracle::random::random, - prelude::{NoteGetterOptions, Map, PublicMutable, SharedImmutable, PrivateSet, AztecAddress, FunctionSelector}, + prelude::{ + NoteGetterOptions, Map, PublicMutable, SharedImmutable, PrivateSet, AztecAddress, + FunctionSelector, + }, encrypted_logs::{ - encrypted_note_emission::{encode_and_encrypt_note, encode_and_encrypt_note_unconstrained, encrypt_and_emit_partial_log}, - encrypted_event_emission::encode_and_encrypt_event_unconstrained - }, - keys::getters::get_public_keys, - macros::{storage::storage, events::event, functions::{initializer, private, view, public, internal}}, - utils::comparison::Comparator, protocol_types::{point::Point, traits::Serialize} + encrypted_note_emission::{ + encode_and_encrypt_note, encode_and_encrypt_note_unconstrained, + encrypt_and_emit_partial_log, + }, encrypted_event_emission::encode_and_encrypt_event_unconstrained, + }, keys::getters::get_public_keys, + macros::{ + storage::storage, events::event, + functions::{initializer, private, view, public, internal}, + }, utils::comparison::Comparator, protocol_types::{point::Point, traits::Serialize}, }; // docs:start:import_authwit - use dep::authwit::auth::{assert_current_call_valid_authwit, assert_current_call_valid_authwit_public, compute_authwit_nullifier}; + use dep::authwit::auth::{ + assert_current_call_valid_authwit, assert_current_call_valid_authwit_public, + compute_authwit_nullifier, + }; // docs:end:import_authwit - use crate::types::{transparent_note::TransparentNote, token_note::TokenNote, balance_set::BalanceSet}; + use crate::types::{ + transparent_note::TransparentNote, token_note::TokenNote, balance_set::BalanceSet, + }; // docs:end::imports @@ -209,8 +220,12 @@ contract Token { fn privately_mint_private_note(amount: Field) { let caller = context.msg_sender(); let caller_keys = get_public_keys(caller); - storage.balances.at(caller).add(caller_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, caller_keys.ovpk_m, caller_keys.ivpk_m, caller)); - Token::at(context.this_address()).assert_minter_and_mint(context.msg_sender(), amount).enqueue(&mut context); + storage.balances.at(caller).add(caller_keys.npk_m, U128::from_integer(amount)).emit( + encode_and_encrypt_note(&mut context, caller_keys.ovpk_m, caller_keys.ivpk_m, caller), + ); + Token::at(context.this_address()) + .assert_minter_and_mint(context.msg_sender(), amount) + .enqueue(&mut context); } #[public] #[internal] @@ -275,11 +290,10 @@ contract Token { // Pop 1 note (set_limit(1)) which has an amount stored in a field with index 0 (select(0, amount)) and // a secret_hash stored in a field with index 1 (select(1, secret_hash)). let mut options = NoteGetterOptions::new(); - options = options.select(TransparentNote::properties().amount, Comparator.EQ, amount).select( - TransparentNote::properties().secret_hash, - Comparator.EQ, - secret_hash - ).set_limit(1); + options = options + .select(TransparentNote::properties().amount, Comparator.EQ, amount) + .select(TransparentNote::properties().secret_hash, Comparator.EQ, secret_hash) + .set_limit(1); let notes = storage.pending_shields.pop_notes(options); assert(notes.len() == 1, "note not popped"); // Add the token note to user's balances set @@ -288,7 +302,9 @@ contract Token { let from = context.msg_sender(); let from_keys = get_public_keys(from); let to_keys = get_public_keys(to); - storage.balances.at(to).add(to_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); + storage.balances.at(to).add(to_keys.npk_m, U128::from_integer(amount)).emit( + encode_and_encrypt_note(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to), + ); } // docs:end:redeem_shield // docs:start:unshield @@ -301,7 +317,9 @@ contract Token { } let from_keys = get_public_keys(from); - storage.balances.at(from).sub(from_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); + storage.balances.at(from).sub(from_keys.npk_m, U128::from_integer(amount)).emit( + encode_and_encrypt_note(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from), + ); Token::at(context.this_address())._increase_public_balance(to, amount).enqueue(&mut context); } // docs:end:unshield @@ -325,17 +343,36 @@ contract Token { storage, from, amount, - INITIAL_TRANSFER_CALL_MAX_NOTES + INITIAL_TRANSFER_CALL_MAX_NOTES, ); storage.balances.at(from).add(from_keys.npk_m, change).emit( - encode_and_encrypt_note_unconstrained(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from) + encode_and_encrypt_note_unconstrained( + &mut context, + from_keys.ovpk_m, + from_keys.ivpk_m, + from, + ), + ); + storage.balances.at(to).add(to_keys.npk_m, amount).emit( + encode_and_encrypt_note_unconstrained( + &mut context, + from_keys.ovpk_m, + to_keys.ivpk_m, + to, + ), ); - storage.balances.at(to).add(to_keys.npk_m, amount).emit(encode_and_encrypt_note_unconstrained(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); // We don't constrain encryption of the note log in `transfer` (unlike in `transfer_from`) because the transfer // function is only designed to be used in situations where the event is not strictly necessary (e.g. payment to // another person where the payment is considered to be successful when the other party successfully decrypts a // note). - Transfer { from, to, amount: amount.to_field() }.emit(encode_and_encrypt_event_unconstrained(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); + Transfer { from, to, amount: amount.to_field() }.emit( + encode_and_encrypt_event_unconstrained( + &mut context, + from_keys.ovpk_m, + to_keys.ivpk_m, + to, + ), + ); } // docs:end:transfer #[contract_library_method] @@ -344,7 +381,7 @@ contract Token { storage: Storage<&mut PrivateContext>, account: AztecAddress, amount: U128, - max_notes: u32 + max_notes: u32, ) -> U128 { let subtracted = storage.balances.at(account).try_sub(amount, max_notes); // Failing to subtract any amount means that the owner was unable to produce more notes that could be nullified. @@ -369,7 +406,7 @@ contract Token { fn compute_recurse_subtract_balance_call( context: PrivateContext, account: AztecAddress, - remaining: U128 + remaining: U128, ) -> PrivateCallInterface<25, U128> { Token::at(context.this_address())._recurse_subtract_balance(account, remaining.to_field()) } @@ -383,7 +420,7 @@ contract Token { storage, account, U128::from_integer(amount), - RECURSIVE_TRANSFER_CALL_MAX_NOTES + RECURSIVE_TRANSFER_CALL_MAX_NOTES, ) } /** @@ -408,17 +445,26 @@ contract Token { assert(nonce == 0, "invalid nonce"); } // docs:end:assert_current_call_valid_authwit - let from_keys = get_public_keys(from); let to_keys = get_public_keys(to); let amount = U128::from_integer(amount); // docs:start:increase_private_balance // docs:start:encrypted - storage.balances.at(from).sub(from_keys.npk_m, amount).emit(encode_and_encrypt_note(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); + storage.balances.at(from).sub(from_keys.npk_m, amount).emit(encode_and_encrypt_note( + &mut context, + from_keys.ovpk_m, + from_keys.ivpk_m, + from, + )); // docs:end:encrypted // docs:end:increase_private_balance - storage.balances.at(to).add(to_keys.npk_m, amount).emit(encode_and_encrypt_note(&mut context, from_keys.ovpk_m, to_keys.ivpk_m, to)); + storage.balances.at(to).add(to_keys.npk_m, amount).emit(encode_and_encrypt_note( + &mut context, + from_keys.ovpk_m, + to_keys.ivpk_m, + to, + )); } // docs:end:transfer_from // docs:start:burn @@ -430,7 +476,9 @@ contract Token { assert(nonce == 0, "invalid nonce"); } let from_keys = get_public_keys(from); - storage.balances.at(from).sub(from_keys.npk_m, U128::from_integer(amount)).emit(encode_and_encrypt_note(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from)); + storage.balances.at(from).sub(from_keys.npk_m, U128::from_integer(amount)).emit( + encode_and_encrypt_note(&mut context, from_keys.ovpk_m, from_keys.ivpk_m, from), + ); Token::at(context.this_address())._reduce_total_supply(amount).enqueue(&mut context); } // docs:end:burn @@ -458,7 +506,7 @@ contract Token { fn setup_refund( fee_payer: AztecAddress, // Address of the entity which will receive the fee note. user: AztecAddress, // A user for which we are setting up the fee refund. - funded_amount: Field // The amount the user funded the fee payer with (represents fee limit). + funded_amount: Field, // The amount the user funded the fee payer with (represents fee limit). ) { // 1. This function is called by fee paying contract (fee_payer) when setting up a refund so we need to support // the authwit flow here and check that the user really permitted fee_payer to set up a refund on their behalf. @@ -479,32 +527,33 @@ contract Token { storage, user, U128::from_integer(funded_amount), - INITIAL_TRANSFER_CALL_MAX_NOTES + INITIAL_TRANSFER_CALL_MAX_NOTES, ); storage.balances.at(user).add(user_keys.npk_m, change).emit( - encode_and_encrypt_note_unconstrained(&mut context, user_keys.ovpk_m, user_keys.ivpk_m, user) + encode_and_encrypt_note_unconstrained( + &mut context, + user_keys.ovpk_m, + user_keys.ivpk_m, + user, + ), ); // 4. Now we get the partial payloads // TODO(#7775): Manually fetching the randomness here is not great. If we decide to include randomness in all // notes we could just inject it in macros. - let fee_payer_randomness = unsafe { - random() - }; - let user_randomness = unsafe { - random() - }; + let fee_payer_randomness = unsafe { random() }; + let user_randomness = unsafe { random() }; let fee_payer_setup_payload = TokenNote::setup_payload().new( fee_payer_npk_m_hash, fee_payer_randomness, - storage.balances.at(fee_payer).set.storage_slot + storage.balances.at(fee_payer).set.storage_slot, ); let user_setup_payload = TokenNote::setup_payload().new( user_npk_m_hash, user_randomness, - storage.balances.at(user).set.storage_slot + storage.balances.at(user).set.storage_slot, ); // 5. We encrypt and emit the partial note log @@ -512,9 +561,14 @@ contract Token { &mut context, fee_payer_setup_payload.log_plaintext, fee_payer_keys, - fee_payer + fee_payer, + ); + encrypt_and_emit_partial_log( + &mut context, + user_setup_payload.log_plaintext, + user_keys, + user, ); - encrypt_and_emit_partial_log(&mut context, user_setup_payload.log_plaintext, user_keys, user); // 6. We convert the hiding points to standard `Point` type as we cannot pass `TokenNoteHidingPoint` type // as an argument to a function due to macro limitations (the `TokenNoteHidingPoint` type is macro generated @@ -527,11 +581,19 @@ contract Token { context.set_public_teardown_function( context.this_address(), comptime { - FunctionSelector::from_signature("complete_refund((Field,Field,bool),(Field,Field,bool),Field)") - }, + FunctionSelector::from_signature( + "complete_refund((Field,Field,bool),(Field,Field,bool),Field)", + ) + }, [ - fee_payer_point.x, fee_payer_point.y, fee_payer_point.is_infinite as Field, user_point.x, user_point.y, user_point.is_infinite as Field, funded_amount - ] + fee_payer_point.x, + fee_payer_point.y, + fee_payer_point.is_infinite as Field, + user_point.x, + user_point.y, + user_point.is_infinite as Field, + funded_amount, + ], ); } // docs:end:setup_refund @@ -555,8 +617,10 @@ contract Token { // 3. We construct the note finalization payloads with the correct amounts and hiding points to get the note // hashes and unencrypted logs. - let fee_payer_finalization_payload = TokenNote::finalization_payload().new(fee_payer_point, tx_fee); - let user_finalization_payload = TokenNote::finalization_payload().new(user_point, refund_amount); + let fee_payer_finalization_payload = + TokenNote::finalization_payload().new(fee_payer_point, tx_fee); + let user_finalization_payload = + TokenNote::finalization_payload().new(user_point, refund_amount); // 4. We emit the `tx_fee` and `refund_amount` as unencrypted event such that the `NoteProcessor` can use it // to reconstruct the note. diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/access_control.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/access_control.nr index 2999be5dfeb..9cb547b237d 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/access_control.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/access_control.nr @@ -4,7 +4,8 @@ use crate::Token; #[test] unconstrained fn access_control() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient) = + utils::setup( /* with_account_contracts */ false); // Set a new admin Token::at(token_contract_address).set_admin(recipient).call(&mut env.public()); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/burn.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/burn.nr index 4fe45f2da9f..233b842c651 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/burn.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/burn.nr @@ -5,7 +5,8 @@ use crate::Token; #[test] unconstrained fn burn_public_success() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); let burn_amount = mint_amount / 10; // Burn less than balance @@ -15,12 +16,18 @@ unconstrained fn burn_public_success() { #[test] unconstrained fn burn_public_on_behalf_of_other() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let burn_amount = mint_amount / 10; // Burn on behalf of other - let burn_call_interface = Token::at(token_contract_address).burn_public(owner, burn_amount, random()); - authwit_cheatcodes::add_public_authwit_from_call_interface(owner, recipient, burn_call_interface); + let burn_call_interface = + Token::at(token_contract_address).burn_public(owner, burn_amount, random()); + authwit_cheatcodes::add_public_authwit_from_call_interface( + owner, + recipient, + burn_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Burn tokens @@ -30,7 +37,8 @@ unconstrained fn burn_public_on_behalf_of_other() { #[test(should_fail_with = "attempt to subtract with underflow")] unconstrained fn burn_public_failure_more_than_balance() { - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Burn more than balance let burn_amount = mint_amount * 10; @@ -40,21 +48,26 @@ unconstrained fn burn_public_failure_more_than_balance() { #[test(should_fail_with = "invalid nonce")] unconstrained fn burn_public_failure_on_behalf_of_self_non_zero_nonce() { - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Burn on behalf of self with non-zero nonce let burn_amount = mint_amount / 10; // Try to burn - Token::at(token_contract_address).burn_public(owner, burn_amount, random()).call(&mut env.public()); + Token::at(token_contract_address).burn_public(owner, burn_amount, random()).call( + &mut env.public(), + ); } #[test(should_fail_with = "unauthorized")] unconstrained fn burn_public_failure_on_behalf_of_other_without_approval() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); // Burn on behalf of other without approval let burn_amount = mint_amount / 10; - let burn_call_interface = Token::at(token_contract_address).burn_public(owner, burn_amount, random()); + let burn_call_interface = + Token::at(token_contract_address).burn_public(owner, burn_amount, random()); // Impersonate recipient to perform the call env.impersonate(recipient); burn_call_interface.call(&mut env.public()); @@ -62,11 +75,13 @@ unconstrained fn burn_public_failure_on_behalf_of_other_without_approval() { #[test(should_fail_with = "unauthorized")] unconstrained fn burn_public_failure_on_behalf_of_other_wrong_caller() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); // Burn on behalf of other, wrong designated caller let burn_amount = mint_amount / 10; - let burn_call_interface = Token::at(token_contract_address).burn_public(owner, burn_amount, random()); + let burn_call_interface = + Token::at(token_contract_address).burn_public(owner, burn_amount, random()); authwit_cheatcodes::add_public_authwit_from_call_interface(owner, owner, burn_call_interface); // Impersonate recipient to perform the call env.impersonate(recipient); @@ -75,7 +90,8 @@ unconstrained fn burn_public_failure_on_behalf_of_other_wrong_caller() { #[test] unconstrained fn burn_private_on_behalf_of_self() { - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); let burn_amount = mint_amount / 10; // Burn less than balance @@ -85,12 +101,17 @@ unconstrained fn burn_private_on_behalf_of_self() { #[test] unconstrained fn burn_private_on_behalf_of_other() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let burn_amount = mint_amount / 10; // Burn on behalf of other let burn_call_interface = Token::at(token_contract_address).burn(owner, burn_amount, random()); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, recipient, burn_call_interface); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + recipient, + burn_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Burn tokens @@ -100,7 +121,8 @@ unconstrained fn burn_private_on_behalf_of_other() { #[test(should_fail_with = "Balance too low")] unconstrained fn burn_private_failure_more_than_balance() { - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Burn more than balance let burn_amount = mint_amount * 10; @@ -109,7 +131,8 @@ unconstrained fn burn_private_failure_more_than_balance() { #[test(should_fail_with = "invalid nonce")] unconstrained fn burn_private_failure_on_behalf_of_self_non_zero_nonce() { - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Burn more than balance let burn_amount = mint_amount / 10; @@ -118,13 +141,18 @@ unconstrained fn burn_private_failure_on_behalf_of_self_non_zero_nonce() { #[test(should_fail_with = "Balance too low")] unconstrained fn burn_private_failure_on_behalf_of_other_more_than_balance() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); // Burn more than balance let burn_amount = mint_amount * 10; // Burn on behalf of other let burn_call_interface = Token::at(token_contract_address).burn(owner, burn_amount, random()); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, recipient, burn_call_interface); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + recipient, + burn_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); burn_call_interface.call(&mut env.private()); @@ -132,7 +160,8 @@ unconstrained fn burn_private_failure_on_behalf_of_other_more_than_balance() { #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn burn_private_failure_on_behalf_of_other_without_approval() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); // Burn more than balance let burn_amount = mint_amount / 10; @@ -145,7 +174,8 @@ unconstrained fn burn_private_failure_on_behalf_of_other_without_approval() { #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn burn_private_failure_on_behalf_of_other_wrong_designated_caller() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); // Burn more than balance let burn_amount = mint_amount / 10; diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/minting.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/minting.nr index 0b5fc640787..d4ee834bdb4 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/minting.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/minting.nr @@ -5,7 +5,7 @@ use crate::{types::transparent_note::TransparentNote, Token}; #[test] unconstrained fn mint_public_success() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _) = utils::setup( /* with_account_contracts */ false); let mint_amount = 10000; Token::at(token_contract_address).mint_public(owner, mint_amount).call(&mut env.public()); @@ -19,12 +19,14 @@ unconstrained fn mint_public_success() { #[test] unconstrained fn mint_public_failures() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient) = + utils::setup( /* with_account_contracts */ false); // As non-minter let mint_amount = 10000; env.impersonate(recipient); - let mint_public_call_interface = Token::at(token_contract_address).mint_public(owner, mint_amount); + let mint_public_call_interface = + Token::at(token_contract_address).mint_public(owner, mint_amount); env.assert_public_call_fails(mint_public_call_interface); utils::check_public_balance(token_contract_address, owner, 0); @@ -32,21 +34,23 @@ unconstrained fn mint_public_failures() { env.impersonate(owner); // Overflow recipient - let mint_amount = 2.pow_32(128); - let mint_public_call_interface = Token::at(token_contract_address).mint_public(owner, mint_amount); + let mint_public_call_interface = + Token::at(token_contract_address).mint_public(owner, mint_amount); env.assert_public_call_fails(mint_public_call_interface); utils::check_public_balance(token_contract_address, owner, 0); // Overflow total supply - let mint_for_recipient_amount = 1000; - Token::at(token_contract_address).mint_public(recipient, mint_for_recipient_amount).call(&mut env.public()); + Token::at(token_contract_address).mint_public(recipient, mint_for_recipient_amount).call( + &mut env.public(), + ); let mint_amount = 2.pow_32(128) - mint_for_recipient_amount; - let mint_public_call_interface = Token::at(token_contract_address).mint_public(owner, mint_amount); + let mint_public_call_interface = + Token::at(token_contract_address).mint_public(owner, mint_amount); env.assert_public_call_fails(mint_public_call_interface); utils::check_public_balance(token_contract_address, recipient, mint_for_recipient_amount); @@ -56,7 +60,7 @@ unconstrained fn mint_public_failures() { #[test] unconstrained fn mint_private_success() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _) = utils::setup( /* with_account_contracts */ false); let mint_amount = 10000; // Mint some tokens let secret = random(); @@ -72,11 +76,13 @@ unconstrained fn mint_private_success() { env.add_note( &mut TransparentNote::new(mint_amount, secret_hash), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); // Redeem our shielded tokens - Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call( + &mut env.private(), + ); utils::check_private_balance(token_contract_address, owner, mint_amount); } @@ -84,7 +90,8 @@ unconstrained fn mint_private_success() { #[test(should_fail_with = "note not popped")] unconstrained fn mint_private_failure_double_spend() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient) = + utils::setup( /* with_account_contracts */ false); let mint_amount = 10000; // Mint some tokens let secret = random(); @@ -100,22 +107,27 @@ unconstrained fn mint_private_failure_double_spend() { env.add_note( &mut TransparentNote::new(mint_amount, secret_hash), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); // Redeem our shielded tokens - Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call( + &mut env.private(), + ); utils::check_private_balance(token_contract_address, owner, mint_amount); // Attempt to double spend - Token::at(token_contract_address).redeem_shield(recipient, mint_amount, secret).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(recipient, mint_amount, secret).call( + &mut env.private(), + ); } #[test(should_fail_with = "caller is not minter")] unconstrained fn mint_private_failure_non_minter() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, _, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, _, recipient) = + utils::setup( /* with_account_contracts */ false); let mint_amount = 10000; // Try to mint some tokens impersonating recipient env.impersonate(recipient); @@ -128,7 +140,7 @@ unconstrained fn mint_private_failure_non_minter() { #[test(should_fail_with = "call to assert_max_bit_size")] unconstrained fn mint_private_failure_overflow() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, _, _) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, _, _) = utils::setup( /* with_account_contracts */ false); // Overflow recipient let mint_amount = 2.pow_32(128); @@ -140,7 +152,7 @@ unconstrained fn mint_private_failure_overflow() { #[test(should_fail_with = "attempt to add with overflow")] unconstrained fn mint_private_failure_overflow_recipient() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _) = utils::setup( /* with_account_contracts */ false); let mint_amount = 10000; // Mint some tokens let secret = random(); @@ -153,11 +165,13 @@ unconstrained fn mint_private_failure_overflow_recipient() { env.add_note( &mut TransparentNote::new(mint_amount, secret_hash), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); // Redeem our shielded tokens - Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call( + &mut env.private(), + ); utils::check_private_balance(token_contract_address, owner, mint_amount); @@ -171,7 +185,8 @@ unconstrained fn mint_private_failure_overflow_recipient() { #[test(should_fail_with = "attempt to add with overflow")] unconstrained fn mint_private_failure_overflow_total_supply() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient) = + utils::setup( /* with_account_contracts */ false); let mint_amount = 10000; // Mint some tokens let secret_owner = random(); @@ -179,8 +194,12 @@ unconstrained fn mint_private_failure_overflow_total_supply() { let secret_hash_owner = compute_secret_hash(secret_owner); let secret_hash_recipient = compute_secret_hash(secret_recipient); - Token::at(token_contract_address).mint_private(mint_amount, secret_hash_owner).call(&mut env.public()); - Token::at(token_contract_address).mint_private(mint_amount, secret_hash_recipient).call(&mut env.public()); + Token::at(token_contract_address).mint_private(mint_amount, secret_hash_owner).call( + &mut env.public(), + ); + Token::at(token_contract_address).mint_private(mint_amount, secret_hash_recipient).call( + &mut env.public(), + ); // Time travel so we can read keys from the registry env.advance_block_by(6); @@ -189,21 +208,25 @@ unconstrained fn mint_private_failure_overflow_total_supply() { env.add_note( &mut TransparentNote::new(mint_amount, secret_hash_owner), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); env.add_note( &mut TransparentNote::new(mint_amount, secret_hash_recipient), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); // Redeem owner's shielded tokens env.impersonate(owner); - Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret_owner).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret_owner).call( + &mut env.private(), + ); // Redeem recipient's shielded tokens env.impersonate(recipient); - Token::at(token_contract_address).redeem_shield(recipient, mint_amount, secret_recipient).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(recipient, mint_amount, secret_recipient).call( + &mut env.private(), + ); utils::check_private_balance(token_contract_address, owner, mint_amount); utils::check_private_balance(token_contract_address, recipient, mint_amount); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/reading_constants.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/reading_constants.nr index 822d3158242..c96bd9613be 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/reading_constants.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/reading_constants.nr @@ -7,7 +7,7 @@ use crate::Token; #[test] unconstrained fn check_decimals_private() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, _, _) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, _, _) = utils::setup( /* with_account_contracts */ false); // Check decimals let result = Token::at(token_contract_address).private_get_decimals().view(&mut env.private()); @@ -18,7 +18,7 @@ unconstrained fn check_decimals_private() { #[test] unconstrained fn check_decimals_public() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, _, _) = utils::setup(/* with_account_contracts */ false); + let (env, token_contract_address, _, _) = utils::setup( /* with_account_contracts */ false); // Check decimals let result = Token::at(token_contract_address).public_get_decimals().view(&mut env.public()); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr index 8a599d834a4..a8f48973acb 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr @@ -2,7 +2,7 @@ use crate::{test::utils, Token, types::token_note::TokenNote}; use dep::aztec::{ prelude::NoteHeader, protocol_types::storage::map::derive_storage_slot_in_map, - keys::getters::get_public_keys + keys::getters::get_public_keys, }; use dep::authwit::cheatcodes as authwit_cheatcodes; use std::test::OracleMock; @@ -23,9 +23,14 @@ unconstrained fn setup_refund_success() { let _ = OracleMock::mock("getRandomField").returns(fee_payer_randomness); - let setup_refund_from_call_interface = Token::at(token_contract_address).setup_refund(fee_payer, user, funded_amount); + let setup_refund_from_call_interface = + Token::at(token_contract_address).setup_refund(fee_payer, user, funded_amount); - authwit_cheatcodes::add_private_authwit_from_call_interface(user, fee_payer, setup_refund_from_call_interface); + authwit_cheatcodes::add_private_authwit_from_call_interface( + user, + fee_payer, + setup_refund_from_call_interface, + ); env.impersonate(fee_payer); @@ -33,8 +38,10 @@ unconstrained fn setup_refund_success() { let user_npk_m_hash = get_public_keys(user).npk_m.hash(); let fee_payer_npk_m_hash = get_public_keys(fee_payer).npk_m.hash(); - let fee_payer_balances_slot = derive_storage_slot_in_map(Token::storage_layout().balances.slot, fee_payer); - let user_balances_slot = derive_storage_slot_in_map(Token::storage_layout().balances.slot, user); + let fee_payer_balances_slot = + derive_storage_slot_in_map(Token::storage_layout().balances.slot, fee_payer); + let user_balances_slot = + derive_storage_slot_in_map(Token::storage_layout().balances.slot, user); // When the refund was set up, we would've spent the note worth mint_amount, and inserted a note worth //`mint_amount - funded_amount`. When completing the refund, we would've constructed a hash corresponding to a note @@ -42,23 +49,23 @@ unconstrained fn setup_refund_success() { // `executePublicFunction` TXE oracle) but we need to notify TXE of the note (preimage). env.add_note( &mut TokenNote { - amount: U128::from_integer(funded_amount - 1), - npk_m_hash: user_npk_m_hash, - randomness: user_randomness, - header: NoteHeader::empty() - }, + amount: U128::from_integer(funded_amount - 1), + npk_m_hash: user_npk_m_hash, + randomness: user_randomness, + header: NoteHeader::empty(), + }, user_balances_slot, - token_contract_address + token_contract_address, ); env.add_note( &mut TokenNote { - amount: U128::from_integer(1), - npk_m_hash: fee_payer_npk_m_hash, - randomness: fee_payer_randomness, - header: NoteHeader::empty() - }, + amount: U128::from_integer(1), + npk_m_hash: fee_payer_npk_m_hash, + randomness: fee_payer_randomness, + header: NoteHeader::empty(), + }, fee_payer_balances_slot, - token_contract_address + token_contract_address, ); utils::check_private_balance(token_contract_address, user, mint_amount - 1); @@ -79,9 +86,14 @@ unconstrained fn setup_refund_insufficient_funded_amount() { // We set funded amount to 0 to make the transaction fee higher than the funded amount let funded_amount = 0; - let setup_refund_from_call_interface = Token::at(token_contract_address).setup_refund(fee_payer, user, funded_amount); + let setup_refund_from_call_interface = + Token::at(token_contract_address).setup_refund(fee_payer, user, funded_amount); - authwit_cheatcodes::add_private_authwit_from_call_interface(user, fee_payer, setup_refund_from_call_interface); + authwit_cheatcodes::add_private_authwit_from_call_interface( + user, + fee_payer, + setup_refund_from_call_interface, + ); env.impersonate(fee_payer); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/shielding.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/shielding.nr index 51b06e83ed1..5abf58a7328 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/shielding.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/shielding.nr @@ -6,22 +6,27 @@ use crate::{types::transparent_note::TransparentNote, Token}; #[test] unconstrained fn shielding_on_behalf_of_self() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); let secret = random(); let secret_hash = compute_secret_hash(secret); // Shield tokens let shield_amount = mint_amount / 10; - Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0).call(&mut env.public()); + Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0).call( + &mut env.public(), + ); // We need to manually add the note to TXE because `TransparentNote` does not support automatic note log delivery. env.add_note( &mut TransparentNote::new(shield_amount, secret_hash), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); // Redeem our shielded tokens - Token::at(token_contract_address).redeem_shield(owner, shield_amount, secret).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(owner, shield_amount, secret).call( + &mut env.private(), + ); // Check balances utils::check_public_balance(token_contract_address, owner, mint_amount - shield_amount); @@ -30,14 +35,20 @@ unconstrained fn shielding_on_behalf_of_self() { #[test] unconstrained fn shielding_on_behalf_of_other() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let secret = random(); let secret_hash = compute_secret_hash(secret); // Shield tokens on behalf of owner let shield_amount = 1000; - let shield_call_interface = Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); - authwit_cheatcodes::add_public_authwit_from_call_interface(owner, recipient, shield_call_interface); + let shield_call_interface = + Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); + authwit_cheatcodes::add_public_authwit_from_call_interface( + owner, + recipient, + shield_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Shield tokens @@ -49,11 +60,13 @@ unconstrained fn shielding_on_behalf_of_other() { env.add_note( &mut TransparentNote::new(shield_amount, secret_hash), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); // Redeem our shielded tokens - Token::at(token_contract_address).redeem_shield(owner, shield_amount, secret).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(owner, shield_amount, secret).call( + &mut env.private(), + ); // Check balances utils::check_public_balance(token_contract_address, owner, mint_amount - shield_amount); @@ -63,12 +76,14 @@ unconstrained fn shielding_on_behalf_of_other() { #[test] unconstrained fn shielding_failure_on_behalf_of_self_more_than_balance() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let secret = random(); let secret_hash = compute_secret_hash(secret); // Shield tokens let shield_amount = mint_amount + 1; - let shield_call_interface = Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); + let shield_call_interface = + Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); env.assert_public_call_fails(shield_call_interface); // Check balances @@ -79,12 +94,14 @@ unconstrained fn shielding_failure_on_behalf_of_self_more_than_balance() { #[test] unconstrained fn shielding_failure_on_behalf_of_self_invalid_nonce() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let secret = random(); let secret_hash = compute_secret_hash(secret); // Shield tokens let shield_amount = mint_amount / 10; - let shield_call_interface = Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, random()); + let shield_call_interface = + Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, random()); env.assert_public_call_fails(shield_call_interface); // Check balances @@ -95,13 +112,19 @@ unconstrained fn shielding_failure_on_behalf_of_self_invalid_nonce() { #[test] unconstrained fn shielding_failure_on_behalf_of_other_more_than_balance() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let secret = random(); let secret_hash = compute_secret_hash(secret); // Shield tokens on behalf of owner let shield_amount = mint_amount + 1; - let shield_call_interface = Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); - authwit_cheatcodes::add_public_authwit_from_call_interface(owner, recipient, shield_call_interface); + let shield_call_interface = + Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); + authwit_cheatcodes::add_public_authwit_from_call_interface( + owner, + recipient, + shield_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Shield tokens @@ -115,12 +138,14 @@ unconstrained fn shielding_failure_on_behalf_of_other_more_than_balance() { #[test] unconstrained fn shielding_failure_on_behalf_of_other_wrong_caller() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let secret = random(); let secret_hash = compute_secret_hash(secret); // Shield tokens on behalf of owner let shield_amount = mint_amount + 1; - let shield_call_interface = Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); + let shield_call_interface = + Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); authwit_cheatcodes::add_public_authwit_from_call_interface(owner, owner, shield_call_interface); // Impersonate recipient to perform the call env.impersonate(recipient); @@ -135,12 +160,14 @@ unconstrained fn shielding_failure_on_behalf_of_other_wrong_caller() { #[test] unconstrained fn shielding_failure_on_behalf_of_other_without_approval() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let secret = random(); let secret_hash = compute_secret_hash(secret); // Shield tokens on behalf of owner let shield_amount = mint_amount + 1; - let shield_call_interface = Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); + let shield_call_interface = + Token::at(token_contract_address).shield(owner, shield_amount, secret_hash, 0); // Impersonate recipient to perform the call env.impersonate(recipient); // Shield tokens diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_private.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_private.nr index 20a84f39266..feaa922200a 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_private.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_private.nr @@ -6,14 +6,14 @@ use crate::Token; #[test] unconstrained fn transfer_private() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // docs:start:txe_test_transfer_private // Transfer tokens let transfer_amount = 1000; Token::at(token_contract_address).transfer(recipient, transfer_amount).call(&mut env.private()); // docs:end:txe_test_transfer_private - // Check balances utils::check_private_balance(token_contract_address, owner, mint_amount - transfer_amount); utils::check_private_balance(token_contract_address, recipient, transfer_amount); @@ -22,7 +22,8 @@ unconstrained fn transfer_private() { #[test] unconstrained fn transfer_private_to_self() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer tokens let transfer_amount = 1000; Token::at(token_contract_address).transfer(owner, transfer_amount).call(&mut env.private()); @@ -34,26 +35,39 @@ unconstrained fn transfer_private_to_self() { #[test] unconstrained fn transfer_private_to_non_deployed_account() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); let not_deployed = cheatcodes::create_account(); // Transfer tokens let transfer_amount = 1000; - Token::at(token_contract_address).transfer(not_deployed.address, transfer_amount).call(&mut env.private()); + Token::at(token_contract_address).transfer(not_deployed.address, transfer_amount).call( + &mut env.private(), + ); // Check balances utils::check_private_balance(token_contract_address, owner, mint_amount - transfer_amount); - utils::check_private_balance(token_contract_address, not_deployed.address, transfer_amount); + utils::check_private_balance( + token_contract_address, + not_deployed.address, + transfer_amount, + ); } #[test] unconstrained fn transfer_private_on_behalf_of_other() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); // Add authwit // docs:start:private_authwit let transfer_amount = 1000; - let transfer_private_from_call_interface = Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, recipient, transfer_private_from_call_interface); + let transfer_private_from_call_interface = + Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + recipient, + transfer_private_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Transfer tokens @@ -67,7 +81,8 @@ unconstrained fn transfer_private_on_behalf_of_other() { #[test(should_fail_with = "Balance too low")] unconstrained fn transfer_private_failure_more_than_balance() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, _, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, _, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer tokens let transfer_amount = mint_amount + 1; Token::at(token_contract_address).transfer(recipient, transfer_amount).call(&mut env.private()); @@ -77,11 +92,17 @@ unconstrained fn transfer_private_failure_more_than_balance() { #[test(should_fail_with = "invalid nonce")] unconstrained fn transfer_private_failure_on_behalf_of_self_non_zero_nonce() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, _) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient, _) = + utils::setup_and_mint( /* with_account_contracts */ false); // Add authwit let transfer_amount = 1000; - let transfer_private_from_call_interface = Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, recipient, transfer_private_from_call_interface); + let transfer_private_from_call_interface = + Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + recipient, + transfer_private_from_call_interface, + ); // Transfer tokens transfer_private_from_call_interface.call(&mut env.private()); } @@ -90,11 +111,17 @@ unconstrained fn transfer_private_failure_on_behalf_of_self_non_zero_nonce() { #[test(should_fail_with = "Balance too low")] unconstrained fn transfer_private_failure_on_behalf_of_more_than_balance() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); // Add authwit let transfer_amount = mint_amount + 1; - let transfer_private_from_call_interface = Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, recipient, transfer_private_from_call_interface); + let transfer_private_from_call_interface = + Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + recipient, + transfer_private_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Transfer tokens @@ -104,10 +131,12 @@ unconstrained fn transfer_private_failure_on_behalf_of_more_than_balance() { #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn transfer_private_failure_on_behalf_of_other_without_approval() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, _) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, _) = + utils::setup_and_mint( /* with_account_contracts */ true); // Add authwit let transfer_amount = 1000; - let transfer_private_from_call_interface = Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); + let transfer_private_from_call_interface = + Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); // Impersonate recipient to perform the call env.impersonate(recipient); // Transfer tokens @@ -117,11 +146,17 @@ unconstrained fn transfer_private_failure_on_behalf_of_other_without_approval() #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn transfer_private_failure_on_behalf_of_other_wrong_caller() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, _) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, _) = + utils::setup_and_mint( /* with_account_contracts */ true); // Add authwit let transfer_amount = 1000; - let transfer_private_from_call_interface = Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, owner, transfer_private_from_call_interface); + let transfer_private_from_call_interface = + Token::at(token_contract_address).transfer_from(owner, recipient, transfer_amount, 1); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + owner, + transfer_private_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Transfer tokens diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_public.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_public.nr index 4de91aef482..600f1e92ed4 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_public.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/transfer_public.nr @@ -6,10 +6,13 @@ use crate::Token; #[test] unconstrained fn public_transfer() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer tokens let transfer_amount = mint_amount / 10; - Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 0).call(&mut env.public()); + Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 0).call( + &mut env.public(), + ); // Check balances utils::check_public_balance(token_contract_address, owner, mint_amount - transfer_amount); @@ -19,13 +22,15 @@ unconstrained fn public_transfer() { #[test] unconstrained fn public_transfer_to_self() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer tokens let transfer_amount = mint_amount / 10; // docs:start:call_public - Token::at(token_contract_address).transfer_public(owner, owner, transfer_amount, 0).call(&mut env.public()); + Token::at(token_contract_address).transfer_public(owner, owner, transfer_amount, 0).call( + &mut env.public(), + ); // docs:end:call_public - // Check balances utils::check_public_balance(token_contract_address, owner, mint_amount); } @@ -33,10 +38,16 @@ unconstrained fn public_transfer_to_self() { #[test] unconstrained fn public_transfer_on_behalf_of_other() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let transfer_amount = mint_amount / 10; - let public_transfer_from_call_interface = Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); - authwit_cheatcodes::add_public_authwit_from_call_interface(owner, recipient, public_transfer_from_call_interface); + let public_transfer_from_call_interface = + Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); + authwit_cheatcodes::add_public_authwit_from_call_interface( + owner, + recipient, + public_transfer_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Transfer tokens @@ -49,10 +60,12 @@ unconstrained fn public_transfer_on_behalf_of_other() { #[test(should_fail_with = "attempt to subtract with underflow")] unconstrained fn public_transfer_failure_more_than_balance() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer tokens let transfer_amount = mint_amount + 1; - let public_transfer_call_interface = Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 0); + let public_transfer_call_interface = + Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 0); // Try to transfer tokens public_transfer_call_interface.call(&mut env.public()); } @@ -60,11 +73,21 @@ unconstrained fn public_transfer_failure_more_than_balance() { #[test(should_fail_with = "invalid nonce")] unconstrained fn public_transfer_failure_on_behalf_of_self_non_zero_nonce() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); // Transfer tokens let transfer_amount = mint_amount / 10; - let public_transfer_call_interface = Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, random()); - authwit_cheatcodes::add_public_authwit_from_call_interface(owner, recipient, public_transfer_call_interface); + let public_transfer_call_interface = Token::at(token_contract_address).transfer_public( + owner, + recipient, + transfer_amount, + random(), + ); + authwit_cheatcodes::add_public_authwit_from_call_interface( + owner, + recipient, + public_transfer_call_interface, + ); // Try to transfer tokens public_transfer_call_interface.call(&mut env.public()); } @@ -72,9 +95,11 @@ unconstrained fn public_transfer_failure_on_behalf_of_self_non_zero_nonce() { #[test(should_fail_with = "unauthorized")] unconstrained fn public_transfer_failure_on_behalf_of_other_without_approval() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let transfer_amount = mint_amount / 10; - let public_transfer_from_call_interface = Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); + let public_transfer_from_call_interface = + Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); // Impersonate recipient to perform the call env.impersonate(recipient); // Try to transfer tokens @@ -84,11 +109,17 @@ unconstrained fn public_transfer_failure_on_behalf_of_other_without_approval() { #[test(should_fail_with = "attempt to subtract with underflow")] unconstrained fn public_transfer_failure_on_behalf_of_other_more_than_balance() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let transfer_amount = mint_amount + 1; // docs:start:public_authwit - let public_transfer_from_call_interface = Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); - authwit_cheatcodes::add_public_authwit_from_call_interface(owner, recipient, public_transfer_from_call_interface); + let public_transfer_from_call_interface = + Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); + authwit_cheatcodes::add_public_authwit_from_call_interface( + owner, + recipient, + public_transfer_from_call_interface, + ); // docs:end:public_authwit // Impersonate recipient to perform the call env.impersonate(recipient); @@ -99,10 +130,16 @@ unconstrained fn public_transfer_failure_on_behalf_of_other_more_than_balance() #[test(should_fail_with = "unauthorized")] unconstrained fn public_transfer_failure_on_behalf_of_other_wrong_caller() { // Setup with account contracts. Slower since we actually deploy them, but needed for authwits. - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let transfer_amount = mint_amount / 10; - let public_transfer_from_call_interface = Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); - authwit_cheatcodes::add_public_authwit_from_call_interface(owner, owner, public_transfer_from_call_interface); + let public_transfer_from_call_interface = + Token::at(token_contract_address).transfer_public(owner, recipient, transfer_amount, 1); + authwit_cheatcodes::add_public_authwit_from_call_interface( + owner, + owner, + public_transfer_from_call_interface, + ); // Impersonate recipient to perform the call env.impersonate(recipient); // Try to transfer tokens diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/unshielding.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/unshielding.nr index 7ec866a3a32..8e4063561a7 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/unshielding.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/unshielding.nr @@ -6,21 +6,30 @@ use crate::Token; #[test] unconstrained fn unshield_on_behalf_of_self() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); let unshield_amount = mint_amount / 10; - Token::at(token_contract_address).unshield(owner, owner, unshield_amount, 0).call(&mut env.private()); + Token::at(token_contract_address).unshield(owner, owner, unshield_amount, 0).call( + &mut env.private(), + ); utils::check_private_balance(token_contract_address, owner, mint_amount - unshield_amount); utils::check_public_balance(token_contract_address, owner, mint_amount + unshield_amount); } #[test] unconstrained fn unshield_on_behalf_of_other() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let unshield_amount = mint_amount / 10; - let unshield_call_interface = Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, recipient, unshield_call_interface); + let unshield_call_interface = + Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + recipient, + unshield_call_interface, + ); // Impersonate recipient env.impersonate(recipient); // Unshield tokens @@ -32,28 +41,40 @@ unconstrained fn unshield_on_behalf_of_other() { #[test(should_fail_with = "Balance too low")] unconstrained fn unshield_failure_more_than_balance() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); let unshield_amount = mint_amount + 1; - Token::at(token_contract_address).unshield(owner, owner, unshield_amount, 0).call(&mut env.private()); + Token::at(token_contract_address).unshield(owner, owner, unshield_amount, 0).call( + &mut env.private(), + ); } #[test(should_fail_with = "invalid nonce")] unconstrained fn unshield_failure_on_behalf_of_self_non_zero_nonce() { // Setup without account contracts. We are not using authwits here, so dummy accounts are enough - let (env, token_contract_address, owner, _, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ false); + let (env, token_contract_address, owner, _, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ false); let unshield_amount = mint_amount + 1; - Token::at(token_contract_address).unshield(owner, owner, unshield_amount, random()).call(&mut env.private()); + Token::at(token_contract_address).unshield(owner, owner, unshield_amount, random()).call( + &mut env.private(), + ); } #[test(should_fail_with = "Balance too low")] unconstrained fn unshield_failure_on_behalf_of_other_more_than_balance() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let unshield_amount = mint_amount + 1; - let unshield_call_interface = Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, recipient, unshield_call_interface); + let unshield_call_interface = + Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + recipient, + unshield_call_interface, + ); // Impersonate recipient env.impersonate(recipient); // Unshield tokens @@ -62,11 +83,17 @@ unconstrained fn unshield_failure_on_behalf_of_other_more_than_balance() { #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn unshield_failure_on_behalf_of_other_invalid_designated_caller() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let unshield_amount = mint_amount + 1; - let unshield_call_interface = Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); - authwit_cheatcodes::add_private_authwit_from_call_interface(owner, owner, unshield_call_interface); + let unshield_call_interface = + Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); + authwit_cheatcodes::add_private_authwit_from_call_interface( + owner, + owner, + unshield_call_interface, + ); // Impersonate recipient env.impersonate(recipient); // Unshield tokens @@ -75,10 +102,12 @@ unconstrained fn unshield_failure_on_behalf_of_other_invalid_designated_caller() #[test(should_fail_with = "Authorization not found for message hash")] unconstrained fn unshield_failure_on_behalf_of_other_no_approval() { - let (env, token_contract_address, owner, recipient, mint_amount) = utils::setup_and_mint(/* with_account_contracts */ true); + let (env, token_contract_address, owner, recipient, mint_amount) = + utils::setup_and_mint( /* with_account_contracts */ true); let unshield_amount = mint_amount + 1; - let unshield_call_interface = Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); + let unshield_call_interface = + Token::at(token_contract_address).unshield(owner, recipient, unshield_amount, 0); // Impersonate recipient env.impersonate(recipient); // Unshield tokens diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/test/utils.nr b/noir-projects/noir-contracts/contracts/token_contract/src/test/utils.nr index 871c33ea9ad..082cb882370 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/test/utils.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/test/utils.nr @@ -2,12 +2,16 @@ use dep::aztec::{ hash::compute_secret_hash, prelude::AztecAddress, test::helpers::{cheatcodes, test_environment::TestEnvironment}, protocol_types::storage::map::derive_storage_slot_in_map, - oracle::{execution::{get_block_number, get_contract_address}, random::random, storage::storage_read} + oracle::{ + execution::{get_block_number, get_contract_address}, random::random, storage::storage_read, + }, }; use crate::{types::transparent_note::TransparentNote, Token}; -pub unconstrained fn setup(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress) { +pub unconstrained fn setup( + with_account_contracts: bool, +) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress) { // Setup env, generate keys let mut env = TestEnvironment::new(); let (owner, recipient) = if with_account_contracts { @@ -28,15 +32,18 @@ pub unconstrained fn setup(with_account_contracts: bool) -> (&mut TestEnvironmen owner, "TestToken0000000000000000000000", "TT00000000000000000000000000000", - 18 + 18, ); - let token_contract = env.deploy_self("Token").with_public_void_initializer(initializer_call_interface); + let token_contract = + env.deploy_self("Token").with_public_void_initializer(initializer_call_interface); let token_contract_address = token_contract.to_address(); env.advance_block_by(1); (&mut env, token_contract_address, owner, recipient) } -pub unconstrained fn setup_and_mint(with_account_contracts: bool) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) { +pub unconstrained fn setup_and_mint( + with_account_contracts: bool, +) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) { // Setup let (env, token_contract_address, owner, recipient) = setup(with_account_contracts); let mint_amount = 10000; @@ -54,12 +61,13 @@ pub unconstrained fn setup_and_mint(with_account_contracts: bool) -> (&mut TestE env.add_note( &mut TransparentNote::new(mint_amount, secret_hash), Token::storage_layout().pending_shields.slot, - token_contract_address + token_contract_address, ); // docs:end:txe_test_add_note - // Redeem our shielded tokens - Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call(&mut env.private()); + Token::at(token_contract_address).redeem_shield(owner, mint_amount, secret).call( + &mut env.private(), + ); (env, token_contract_address, owner, recipient, mint_amount) } @@ -68,7 +76,7 @@ pub unconstrained fn setup_and_mint(with_account_contracts: bool) -> (&mut TestE pub unconstrained fn check_public_balance( token_contract_address: AztecAddress, address: AztecAddress, - address_amount: Field + address_amount: Field, ) { let current_contract_address = get_contract_address(); cheatcodes::set_contract_address(token_contract_address); @@ -86,7 +94,7 @@ pub unconstrained fn check_public_balance( pub unconstrained fn check_private_balance( token_contract_address: AztecAddress, address: AztecAddress, - address_amount: Field + address_amount: Field, ) { let current_contract_address = get_contract_address(); cheatcodes::set_contract_address(token_contract_address); diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr index edc7909bd02..2bb1a34b5cb 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/balance_set.nr @@ -2,8 +2,9 @@ use dep::aztec::prelude::{NoteGetterOptions, NoteViewerOptions, NoteInterface, P use dep::aztec::{ context::{PrivateContext, UnconstrainedContext}, protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, public_keys::NpkM}, - note::{note_interface::NullifiableNote, note_getter::view_notes, note_emission::OuterNoteEmission}, - keys::getters::get_public_keys + note::{ + note_interface::NullifiableNote, note_getter::view_notes, note_emission::OuterNoteEmission, + }, keys::getters::get_public_keys, }; use crate::types::token_note::OwnedNote; @@ -19,14 +20,20 @@ impl BalanceSet { } impl BalanceSet { - pub unconstrained fn balance_of(self: Self) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote { + pub unconstrained fn balance_of(self: Self) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote, + { self.balance_of_with_offset(0) } pub unconstrained fn balance_of_with_offset( self: Self, - offset: u32 - ) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote { + offset: u32, + ) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote, + { let mut balance = U128::from_integer(0); // docs:start:view_notes let mut options = NoteViewerOptions::new(); @@ -49,8 +56,11 @@ impl BalanceSet { pub fn add( self: Self, owner_npk_m: NpkM, - addend: U128 - ) -> OuterNoteEmission where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + addend: U128, + ) -> OuterNoteEmission + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { if addend == U128::from_integer(0) { OuterNoteEmission::new(Option::none()) } else { @@ -66,8 +76,11 @@ impl BalanceSet { pub fn sub( self: Self, owner_npk_m: NpkM, - amount: U128 - ) -> OuterNoteEmission where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + amount: U128, + ) -> OuterNoteEmission + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { let subtracted = self.try_sub(amount, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL); // try_sub may have substracted more or less than amount. We must ensure that we subtracted at least as much as @@ -88,14 +101,18 @@ impl BalanceSet { pub fn try_sub( self: Self, target_amount: U128, - max_notes: u32 - ) -> U128 where T: NoteInterface + NullifiableNote + OwnedNote + Eq { + max_notes: u32, + ) -> U128 + where + T: NoteInterface + NullifiableNote + OwnedNote + Eq, + { // We are using a preprocessor here (filter applied in an unconstrained context) instead of a filter because // we do not need to prove correct execution of the preprocessor. // Because the `min_sum` notes is not constrained, users could choose to e.g. not call it. However, all this // might result in is simply higher DA costs due to more nullifiers being emitted. Since we don't care // about proving optimal note usage, we can save these constraints and make the circuit smaller. - let options = NoteGetterOptions::with_preprocessor(preprocess_notes_min_sum, target_amount).set_limit(max_notes); + let options = NoteGetterOptions::with_preprocessor(preprocess_notes_min_sum, target_amount) + .set_limit(max_notes); let notes = self.set.pop_notes(options); let mut subtracted = U128::from_integer(0); @@ -117,8 +134,11 @@ impl BalanceSet { // Note that proper usage of this preprocessor requires for notes to be sorted in descending order. pub fn preprocess_notes_min_sum( notes: [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], - min_sum: U128 -) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where T: NoteInterface + NullifiableNote + OwnedNote { + min_sum: U128, +) -> [Option; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] +where + T: NoteInterface + NullifiableNote + OwnedNote, +{ let mut selected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL]; let mut sum = U128::from_integer(0); for i in 0..notes.len() { diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr index 8501b17c014..ace732b7c72 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/token_note.nr @@ -1,8 +1,9 @@ use dep::aztec::{ prelude::{NoteHeader, NullifiableNote, PrivateContext}, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - note::utils::compute_note_hash_for_nullify, oracle::random::random, keys::getters::get_nsk_app, - macros::notes::partial_note + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + }, note::utils::compute_note_hash_for_nullify, oracle::random::random, + keys::getters::get_nsk_app, macros::notes::partial_note, }; trait OwnedNote { @@ -24,14 +25,15 @@ pub struct TokenNote { impl NullifiableNote for TokenNote { // docs:start:nullifier - fn compute_nullifier(self, context: &mut PrivateContext, note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + context: &mut PrivateContext, + note_hash_for_nullify: Field, + ) -> Field { let secret = context.request_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( - [ - note_hash_for_nullify, - secret - ], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + [note_hash_for_nullify, secret], + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } // docs:end:nullifier @@ -41,7 +43,7 @@ impl NullifiableNote for TokenNote { let secret = get_nsk_app(self.npk_m_hash); poseidon2_hash_with_separator( [note_hash_for_nullify, secret], - GENERATOR_INDEX__NOTE_NULLIFIER + GENERATOR_INDEX__NOTE_NULLIFIER, ) } } @@ -60,9 +62,7 @@ impl OwnedNote for TokenNote { // malicious sender could use non-random values to make the note less private. But they already know the full // note pre-image anyway, and so the recipient already trusts them to not disclose this information. We can // therefore assume that the sender will cooperate in the random value generation. - let randomness = unsafe { - random() - }; + let randomness = unsafe { random() }; Self { amount, npk_m_hash: owner_npk_m_hash, randomness, header: NoteHeader::empty() } } diff --git a/noir-projects/noir-contracts/contracts/token_contract/src/types/transparent_note.nr b/noir-projects/noir-contracts/contracts/token_contract/src/types/transparent_note.nr index 19ec7ac1812..b89920a82ec 100644 --- a/noir-projects/noir-contracts/contracts/token_contract/src/types/transparent_note.nr +++ b/noir-projects/noir-contracts/contracts/token_contract/src/types/transparent_note.nr @@ -1,8 +1,10 @@ // docs:start:token_types_all use dep::aztec::{ - note::utils::compute_note_hash_for_nullify, prelude::{NoteHeader, NullifiableNote, PrivateContext}, - protocol_types::{constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator}, - macros::notes::note + note::utils::compute_note_hash_for_nullify, + prelude::{NoteHeader, NullifiableNote, PrivateContext}, + protocol_types::{ + constants::GENERATOR_INDEX__NOTE_NULLIFIER, hash::poseidon2_hash_with_separator, + }, macros::notes::note, }; use dep::std::mem::zeroed; @@ -26,11 +28,15 @@ impl NullifiableNote for TransparentNote { // 3) the "get_notes" oracle constrains that the secret hash in the returned note matches the one computed in // circuit. // This achieves that the note can only be spent by the party that knows the secret. - fn compute_nullifier(self, _context: &mut PrivateContext, _note_hash_for_nullify: Field) -> Field { + fn compute_nullifier( + self, + _context: &mut PrivateContext, + _note_hash_for_nullify: Field, + ) -> Field { let note_hash_for_nullify = compute_note_hash_for_nullify(self); poseidon2_hash_with_separator( [note_hash_for_nullify], - GENERATOR_INDEX__NOTE_NULLIFIER as Field + GENERATOR_INDEX__NOTE_NULLIFIER as Field, ) } diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr index 0b1aeb7cd55..4e488288226 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/main.nr @@ -10,12 +10,17 @@ use dep::aztec::macros::aztec; contract Uniswap { use dep::aztec::prelude::{FunctionSelector, AztecAddress, EthAddress, SharedImmutable}; - use dep::authwit::auth::{assert_current_call_valid_authwit_public, compute_authwit_message_hash_from_call, set_authorized}; + use dep::authwit::auth::{ + assert_current_call_valid_authwit_public, compute_authwit_message_hash_from_call, + set_authorized, + }; use dep::token::Token; use dep::token_bridge::TokenBridge; use crate::util::{compute_swap_private_content_hash, compute_swap_public_content_hash}; - use dep::aztec::macros::{storage::storage, functions::{public, initializer, view, internal, private}}; + use dep::aztec::macros::{ + storage::storage, functions::{public, initializer, view, internal, private}, + }; #[storage] struct Storage { @@ -46,7 +51,7 @@ contract Uniswap { secret_hash_for_L1_to_l2_message: Field, caller_on_L1: EthAddress, // nonce for someone to call swap on sender's behalf - nonce_for_swap_approval: Field + nonce_for_swap_approval: Field, ) { if (!sender.eq(context.msg_sender())) { assert_current_call_valid_authwit_public(&mut context, sender); @@ -55,25 +60,37 @@ contract Uniswap { let input_asset = TokenBridge::at(input_asset_bridge).get_token().view(&mut context); // Transfer funds to this contract - Token::at(input_asset).transfer_public( - sender, - context.this_address(), - input_amount, - nonce_for_transfer_approval - ).call(&mut context); + Token::at(input_asset) + .transfer_public( + sender, + context.this_address(), + input_amount, + nonce_for_transfer_approval, + ) + .call(&mut context); // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal - Uniswap::at(context.this_address())._approve_bridge_and_exit_input_asset_to_L1(input_asset, input_asset_bridge, input_amount).call(&mut context); + Uniswap::at(context.this_address()) + ._approve_bridge_and_exit_input_asset_to_L1( + input_asset, + input_asset_bridge, + input_amount, + ) + .call(&mut context); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. - let input_asset_bridge_portal_address = TokenBridge::at(input_asset_bridge).get_portal_address_public().view(&mut context); - let output_asset_bridge_portal_address = TokenBridge::at(output_asset_bridge).get_portal_address_public().view(&mut context); + let input_asset_bridge_portal_address = + TokenBridge::at(input_asset_bridge).get_portal_address_public().view(&mut context); + let output_asset_bridge_portal_address = + TokenBridge::at(output_asset_bridge).get_portal_address_public().view(&mut context); // ensure portal exists - else funds might be lost assert( - !input_asset_bridge_portal_address.is_zero(), "L1 portal address of input_asset's bridge is 0" + !input_asset_bridge_portal_address.is_zero(), + "L1 portal address of input_asset's bridge is 0", ); assert( - !output_asset_bridge_portal_address.is_zero(), "L1 portal address of output_asset's bridge is 0" + !output_asset_bridge_portal_address.is_zero(), + "L1 portal address of output_asset's bridge is 0", ); let content_hash = compute_swap_public_content_hash( @@ -84,7 +101,7 @@ contract Uniswap { minimum_output_amount, recipient, secret_hash_for_L1_to_l2_message, - caller_on_L1 + caller_on_L1, ); context.message_portal(storage.portal_address.read_public(), content_hash); } @@ -100,38 +117,52 @@ contract Uniswap { // params for using the unshield approval nonce_for_unshield_approval: Field, // params for the swap - uniswap_fee_tier: Field,// which uniswap tier to use (eg 3000 for 0.3% fee) + uniswap_fee_tier: Field, // which uniswap tier to use (eg 3000 for 0.3% fee) minimum_output_amount: Field, // minimum output amount to receive (slippage protection for the swap) // params for the depositing output_asset back to Aztec - secret_hash_for_redeeming_minted_notes: Field,// secret hash used to redeem minted notes at a later time. This enables anyone to call this function and mint tokens to a user on their behalf + secret_hash_for_redeeming_minted_notes: Field, // secret hash used to redeem minted notes at a later time. This enables anyone to call this function and mint tokens to a user on their behalf secret_hash_for_L1_to_l2_message: Field, // for when l1 uniswap portal inserts the message to consume output assets on L2 - caller_on_L1: EthAddress // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) + caller_on_L1: EthAddress, // ethereum address that can call this function on the L1 portal (0x0 if anyone can call) ) { // Assert that user provided token address is same as expected by token bridge. // we can't directly use `input_asset_bridge.token` because that is a public method and public can't return data to private - Uniswap::at(context.this_address())._assert_token_is_same(input_asset, input_asset_bridge).enqueue_view(&mut context); + Uniswap::at(context.this_address()) + ._assert_token_is_same(input_asset, input_asset_bridge) + .enqueue_view(&mut context); // Transfer funds to this contract - Token::at(input_asset).unshield( - context.msg_sender(), - context.this_address(), - input_amount, - nonce_for_unshield_approval - ).call(&mut context); + Token::at(input_asset) + .unshield( + context.msg_sender(), + context.this_address(), + input_amount, + nonce_for_unshield_approval, + ) + .call(&mut context); // Approve bridge to burn this contract's funds and exit to L1 Uniswap Portal - Uniswap::at(context.this_address())._approve_bridge_and_exit_input_asset_to_L1(input_asset, input_asset_bridge, input_amount).enqueue(&mut context); + Uniswap::at(context.this_address()) + ._approve_bridge_and_exit_input_asset_to_L1( + input_asset, + input_asset_bridge, + input_amount, + ) + .enqueue(&mut context); // Create swap message and send to Outbox for Uniswap Portal // this ensures the integrity of what the user originally intends to do on L1. - let input_asset_bridge_portal_address = TokenBridge::at(input_asset_bridge).get_portal_address().view(&mut context); - let output_asset_bridge_portal_address = TokenBridge::at(output_asset_bridge).get_portal_address().view(&mut context); + let input_asset_bridge_portal_address = + TokenBridge::at(input_asset_bridge).get_portal_address().view(&mut context); + let output_asset_bridge_portal_address = + TokenBridge::at(output_asset_bridge).get_portal_address().view(&mut context); // ensure portal exists - else funds might be lost assert( - !input_asset_bridge_portal_address.is_zero(), "L1 portal address of input_asset's bridge is 0" + !input_asset_bridge_portal_address.is_zero(), + "L1 portal address of input_asset's bridge is 0", ); assert( - !output_asset_bridge_portal_address.is_zero(), "L1 portal address of output_asset's bridge is 0" + !output_asset_bridge_portal_address.is_zero(), + "L1 portal address of output_asset's bridge is 0", ); let content_hash = compute_swap_private_content_hash( @@ -142,7 +173,7 @@ contract Uniswap { minimum_output_amount, secret_hash_for_redeeming_minted_notes, secret_hash_for_L1_to_l2_message, - caller_on_L1 + caller_on_L1, ); context.message_portal(storage.portal_address.read_private(), content_hash); } @@ -156,7 +187,11 @@ contract Uniswap { // this method is used for both private and public swaps. #[public] #[internal] - fn _approve_bridge_and_exit_input_asset_to_L1(token: AztecAddress, token_bridge: AztecAddress, amount: Field) { + fn _approve_bridge_and_exit_input_asset_to_L1( + token: AztecAddress, + token_bridge: AztecAddress, + amount: Field, + ) { // Since we will authorize and instantly spend the funds, all in public, we can use the same nonce // every interaction. In practice, the authwit should be squashed, so this is also cheap! let nonce = 0xdeadbeef; @@ -168,7 +203,7 @@ contract Uniswap { context.chain_id(), context.version(), selector, - [context.this_address().to_field(), amount, nonce] + [context.this_address().to_field(), amount, nonce], ); // We need to make a call to update it. @@ -176,7 +211,9 @@ contract Uniswap { let this_portal_address = storage.portal_address.read_public(); // Exit to L1 Uniswap Portal ! - TokenBridge::at(token_bridge).exit_to_l1_public(this_portal_address, amount, this_portal_address, nonce).call(&mut context) + TokenBridge::at(token_bridge) + .exit_to_l1_public(this_portal_address, amount, this_portal_address, nonce) + .call(&mut context) } // docs:end:authwit_uniswap_set @@ -186,7 +223,8 @@ contract Uniswap { #[view] fn _assert_token_is_same(token: AztecAddress, token_bridge: AztecAddress) { assert( - token.eq(TokenBridge::at(token_bridge).get_token().view(&mut context)), "input_asset address is not the same as seen in the bridge contract" + token.eq(TokenBridge::at(token_bridge).get_token().view(&mut context)), + "input_asset address is not the same as seen in the bridge contract", ); } // docs:end:assert_token_is_same diff --git a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr index afc689c2f0c..8d93994d624 100644 --- a/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr +++ b/noir-projects/noir-contracts/contracts/uniswap_contract/src/util.nr @@ -12,17 +12,19 @@ pub fn compute_swap_public_content_hash( minimum_output_amount: Field, aztec_recipient: AztecAddress, secret_hash_for_L1_to_l2_message: Field, - caller_on_L1: EthAddress + caller_on_L1: EthAddress, ) -> Field { let mut hash_bytes = [0; 260]; // 8 fields of 32 bytes each + 4 bytes fn selector - - let input_token_portal_bytes: [u8; 32] = input_asset_bridge_portal_address.to_field().to_be_bytes(); + let input_token_portal_bytes: [u8; 32] = + input_asset_bridge_portal_address.to_field().to_be_bytes(); let in_amount_bytes: [u8; 32] = input_amount.to_be_bytes(); let uniswap_fee_tier_bytes: [u8; 32] = uniswap_fee_tier.to_be_bytes(); - let output_token_portal_bytes: [u8; 32] = output_asset_bridge_portal_address.to_field().to_be_bytes(); + let output_token_portal_bytes: [u8; 32] = + output_asset_bridge_portal_address.to_field().to_be_bytes(); let amount_out_min_bytes: [u8; 32] = minimum_output_amount.to_be_bytes(); let aztec_recipient_bytes: [u8; 32] = aztec_recipient.to_field().to_be_bytes(); - let secret_hash_for_L1_to_l2_message_bytes: [u8; 32] = secret_hash_for_L1_to_l2_message.to_be_bytes(); + let secret_hash_for_L1_to_l2_message_bytes: [u8; 32] = + secret_hash_for_L1_to_l2_message.to_be_bytes(); let caller_on_L1_bytes: [u8; 32] = caller_on_L1.to_field().to_be_bytes(); // function selector: 0xf18186d8 keccak256("swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") @@ -58,17 +60,20 @@ pub fn compute_swap_private_content_hash( minimum_output_amount: Field, secret_hash_for_redeeming_minted_notes: Field, secret_hash_for_L1_to_l2_message: Field, - caller_on_L1: EthAddress + caller_on_L1: EthAddress, ) -> Field { let mut hash_bytes = [0; 260]; // 8 fields of 32 bytes each + 4 bytes fn selector - - let input_token_portal_bytes: [u8; 32] = input_asset_bridge_portal_address.to_field().to_be_bytes(); + let input_token_portal_bytes: [u8; 32] = + input_asset_bridge_portal_address.to_field().to_be_bytes(); let in_amount_bytes: [u8; 32] = input_amount.to_be_bytes(); let uniswap_fee_tier_bytes: [u8; 32] = uniswap_fee_tier.to_be_bytes(); - let output_token_portal_bytes: [u8; 32] = output_asset_bridge_portal_address.to_field().to_be_bytes(); + let output_token_portal_bytes: [u8; 32] = + output_asset_bridge_portal_address.to_field().to_be_bytes(); let amount_out_min_bytes: [u8; 32] = minimum_output_amount.to_be_bytes(); - let secret_hash_for_redeeming_minted_notes_bytes: [u8; 32] = secret_hash_for_redeeming_minted_notes.to_be_bytes(); - let secret_hash_for_L1_to_l2_message_bytes: [u8; 32] = secret_hash_for_L1_to_l2_message.to_be_bytes(); + let secret_hash_for_redeeming_minted_notes_bytes: [u8; 32] = + secret_hash_for_redeeming_minted_notes.to_be_bytes(); + let secret_hash_for_L1_to_l2_message_bytes: [u8; 32] = + secret_hash_for_L1_to_l2_message.to_be_bytes(); let caller_on_L1_bytes: [u8; 32] = caller_on_L1.to_field().to_be_bytes(); // function selector: 0x16f416eb keccak256("swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)") diff --git a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/base/base_parity_inputs.nr b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/base/base_parity_inputs.nr index d9bbcdab794..0684362547b 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/base/base_parity_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/base/base_parity_inputs.nr @@ -14,7 +14,7 @@ impl BaseParityInputs { ParityPublicInputs { sha_root: sha_tree.get_root(), converted_root: poseidon_tree.get_root(), - vk_tree_root: self.vk_tree_root + vk_tree_root: self.vk_tree_root, } } } @@ -26,7 +26,7 @@ fn test_sha_root_matches_frontier_tree() { 0x151de48ca3efbae39f180fe00b8f472ec9f25be10b4f283a87c6d783935370, 0x14c2ea9dedf77698d4afe23bc663263eed0bf9aa3a8b17d9b74812f185610f, 0x1570cc6641699e3ae87fa258d80a6d853f7b8ccb211dc244d017e2ca6530f8, - 0x2806c860af67e9cd50000378411b8c4c4db172ceb2daa862b259b689ccbdc1 + 0x2806c860af67e9cd50000378411b8c4c4db172ceb2daa862b259b689ccbdc1, ]; let base_parity_inputs = BaseParityInputs { msgs, vk_tree_root: 42 }; diff --git a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/parity_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/parity_public_inputs.nr index 20b645c4050..3b7b286020c 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/parity_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/parity_public_inputs.nr @@ -1,4 +1,4 @@ -use dep::types::{traits::{Empty, Serialize, Deserialize}}; +use dep::types::traits::{Empty, Serialize, Deserialize}; pub struct ParityPublicInputs { sha_root: Field, @@ -24,6 +24,10 @@ impl Serialize<3> for ParityPublicInputs { impl Deserialize<3> for ParityPublicInputs { fn deserialize(fields: [Field; 3]) -> Self { - ParityPublicInputs { sha_root: fields[0], converted_root: fields[1], vk_tree_root: fields[2] } + ParityPublicInputs { + sha_root: fields[0], + converted_root: fields[1], + vk_tree_root: fields[2], + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_input.nr b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_input.nr index 66b9884a315..1999eff165e 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_input.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_input.nr @@ -1,7 +1,10 @@ use dep::types::{ traits::Empty, - recursion::{verification_key::{VerificationKey, HonkVerificationKey}, proof::RecursiveProof, traits::Verifiable}, - constants::{BASE_PARITY_INDEX, VK_TREE_HEIGHT}, merkle_tree::membership::assert_check_membership + recursion::{ + verification_key::{VerificationKey, HonkVerificationKey}, proof::RecursiveProof, + traits::Verifiable, + }, constants::{BASE_PARITY_INDEX, VK_TREE_HEIGHT}, + merkle_tree::membership::assert_check_membership, }; use crate::parity_public_inputs::ParityPublicInputs; @@ -18,7 +21,7 @@ impl Empty for RootParityInput { proof: RecursiveProof::empty(), verification_key: VerificationKey::empty(), vk_path: [0; VK_TREE_HEIGHT], - public_inputs: ParityPublicInputs::empty() + public_inputs: ParityPublicInputs::empty(), } } } @@ -30,7 +33,7 @@ impl Verifiable for RootParityInput { self.verification_key.key, self.proof.fields, inputs, - self.verification_key.hash + self.verification_key.hash, ); } } @@ -42,7 +45,7 @@ impl RootParityInput { self.verification_key.hash, BASE_PARITY_INDEX as Field, self.vk_path, - self.public_inputs.vk_tree_root + self.public_inputs.vk_tree_root, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_inputs.nr b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_inputs.nr index e765f5e3137..50bc3edc4ce 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_parity_inputs.nr @@ -1,7 +1,7 @@ use dep::types::merkle_tree::MerkleTree; use crate::{ parity_public_inputs::ParityPublicInputs, root::root_parity_input::RootParityInput, - utils::sha256_merkle_tree::Sha256MerkleTree + utils::sha256_merkle_tree::Sha256MerkleTree, }; global NUM_BASE_PARITY_PER_ROOT_PARITY: u32 = 4; @@ -16,7 +16,8 @@ impl RootParityInputs { let vk_tree_root = self.children[0].public_inputs.vk_tree_root; for i in 0..NUM_BASE_PARITY_PER_ROOT_PARITY { assert( - self.children[i].public_inputs.vk_tree_root == vk_tree_root, "Inconsistent vk tree roots across base parity circuits" + self.children[i].public_inputs.vk_tree_root == vk_tree_root, + "Inconsistent vk tree roots across base parity circuits", ); } @@ -30,16 +31,22 @@ impl RootParityInputs { let sha_tree = Sha256MerkleTree::new(sha_roots); let poseidon_tree = MerkleTree::new(converted_roots); - ParityPublicInputs { sha_root: sha_tree.get_root(), converted_root: poseidon_tree.get_root(), vk_tree_root } + ParityPublicInputs { + sha_root: sha_tree.get_root(), + converted_root: poseidon_tree.get_root(), + vk_tree_root, + } } fn verify_child_proofs(self) { for i in 0..NUM_BASE_PARITY_PER_ROOT_PARITY { assert( - self.children[i].verification_key.hash == self.children[0].verification_key.hash, "Inconsistent vk hashes across base parity circuits" + self.children[i].verification_key.hash == self.children[0].verification_key.hash, + "Inconsistent vk hashes across base parity circuits", ); assert( - self.children[i].vk_path == self.children[0].vk_path, "Inconsistent vk paths across base parity circuits" + self.children[i].vk_path == self.children[0].vk_path, + "Inconsistent vk paths across base parity circuits", ); self.children[i].verify(); self.children[i].validate_in_vk_tree(); @@ -50,7 +57,7 @@ impl RootParityInputs { mod tests { use crate::{ parity_public_inputs::ParityPublicInputs, - root::{root_parity_input::RootParityInput, root_parity_inputs::RootParityInputs} + root::{root_parity_input::RootParityInput, root_parity_inputs::RootParityInputs}, }; use dep::types::recursion::{verification_key::VerificationKey, proof::RecursiveProof}; use dep::types::tests::fixtures; @@ -66,7 +73,7 @@ mod tests { 0xb3a3fc1968999f2c2d798b900bdf0de41311be2a4d20496a7e792a521fc8ab, 0x43f78e0ebc9633ce336a8c086064d898c32fb5d7d6011f5427459c0b8d14e9, 0x024259b6404280addcc9319bc5a32c9a5d56af5c93b2f941fa326064fbe963, - 0x53042d820859d80c474d4694e03778f8dc0ac88fc1c3a97b4369c1096e904a + 0x53042d820859d80c474d4694e03778f8dc0ac88fc1c3a97b4369c1096e904a, ]; let vk_tree = fixtures::vk_tree::get_vk_merkle_tree(); @@ -81,26 +88,42 @@ mod tests { proof: RecursiveProof::empty(), verification_key: vk1, vk_path, - public_inputs: ParityPublicInputs { sha_root: children_sha_roots[0], converted_root: 0, vk_tree_root } + public_inputs: ParityPublicInputs { + sha_root: children_sha_roots[0], + converted_root: 0, + vk_tree_root, + }, }, RootParityInput { proof: RecursiveProof::empty(), verification_key: vk1, vk_path, - public_inputs: ParityPublicInputs { sha_root: children_sha_roots[1], converted_root: 0, vk_tree_root } + public_inputs: ParityPublicInputs { + sha_root: children_sha_roots[1], + converted_root: 0, + vk_tree_root, + }, }, RootParityInput { proof: RecursiveProof::empty(), verification_key: vk1, vk_path, - public_inputs: ParityPublicInputs { sha_root: children_sha_roots[2], converted_root: 0, vk_tree_root } + public_inputs: ParityPublicInputs { + sha_root: children_sha_roots[2], + converted_root: 0, + vk_tree_root, + }, }, RootParityInput { proof: RecursiveProof::empty(), verification_key: vk1, vk_path, - public_inputs: ParityPublicInputs { sha_root: children_sha_roots[3], converted_root: 0, vk_tree_root } - } + public_inputs: ParityPublicInputs { + sha_root: children_sha_roots[3], + converted_root: 0, + vk_tree_root, + }, + }, ]; children } diff --git a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_rollup_parity_input.nr b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_rollup_parity_input.nr index 018541f82a2..23f082d38f9 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_rollup_parity_input.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/root/root_rollup_parity_input.nr @@ -1,10 +1,10 @@ use dep::types::{ traits::Empty, recursion::{ - verification_key::{VerificationKey, HonkVerificationKey}, proof::NestedRecursiveProof, - traits::Verifiable -}, - constants::{ROOT_PARITY_INDEX, VK_TREE_HEIGHT}, merkle_tree::membership::assert_check_membership + verification_key::{VerificationKey, HonkVerificationKey}, proof::NestedRecursiveProof, + traits::Verifiable, + }, constants::{ROOT_PARITY_INDEX, VK_TREE_HEIGHT}, + merkle_tree::membership::assert_check_membership, }; use crate::parity_public_inputs::ParityPublicInputs; @@ -21,7 +21,7 @@ impl Empty for RootRollupParityInput { proof: NestedRecursiveProof::empty(), verification_key: VerificationKey::empty(), vk_path: [0; VK_TREE_HEIGHT], - public_inputs: ParityPublicInputs::empty() + public_inputs: ParityPublicInputs::empty(), } } } @@ -33,7 +33,7 @@ impl Verifiable for RootRollupParityInput { self.verification_key.key, self.proof.fields, inputs, - self.verification_key.hash + self.verification_key.hash, ); } } @@ -45,7 +45,7 @@ impl RootRollupParityInput { self.verification_key.hash, ROOT_PARITY_INDEX as Field, self.vk_path, - self.public_inputs.vk_tree_root + self.public_inputs.vk_tree_root, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/utils/sha256_merkle_tree.nr b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/utils/sha256_merkle_tree.nr index 8e9ace41647..0d908e43e16 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-lib/src/utils/sha256_merkle_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-lib/src/utils/sha256_merkle_tree.nr @@ -1,4 +1,4 @@ -use dep::types::{hash::accumulate_sha256}; +use dep::types::hash::accumulate_sha256; // Note: Once we'll truncate sha256 to 1 Field we can nuke this and generalize the standard MerkleTree over different // hash functions. @@ -19,22 +19,12 @@ impl Sha256MerkleTree { // hash base layer for i in 0..half_size { - nodes[i] = accumulate_sha256( - [ - leaves[2*i], - leaves[2*i+1] - ] - ); + nodes[i] = accumulate_sha256([leaves[2 * i], leaves[2 * i + 1]]); } // hash the other layers for i in 0..(total_nodes - half_size) { - nodes[half_size+i] = accumulate_sha256( - [ - nodes[2*i], - nodes[2*i+1] - ] - ); + nodes[half_size + i] = accumulate_sha256([nodes[2 * i], nodes[2 * i + 1]]); } Sha256MerkleTree { leaves, nodes } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr index d1d89b9c862..8d34da7efff 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr @@ -9,14 +9,14 @@ unconstrained fn main( vk_tree_root: Field, protocol_contract_tree_root: Field, private_call: PrivateCallDataWithoutPublicInputs, - app_public_inputs: PrivateCircuitPublicInputs + app_public_inputs: PrivateCircuitPublicInputs, ) -> pub PrivateKernelCircuitPublicInputs { let private_inputs = PrivateKernelInitCircuitPrivateInputs::new( tx_request, vk_tree_root, protocol_contract_tree_root, private_call, - app_public_inputs + app_public_inputs, ); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr index 011337bb55c..8ed70c84e56 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr @@ -9,14 +9,14 @@ fn main( vk_tree_root: Field, protocol_contract_tree_root: Field, private_call: PrivateCallDataWithoutPublicInputs, - app_public_inputs: call_data(1) PrivateCircuitPublicInputs + app_public_inputs: call_data(1) PrivateCircuitPublicInputs, ) -> return_data PrivateKernelCircuitPublicInputs { let private_inputs = PrivateKernelInitCircuitPrivateInputs::new( tx_request, vk_tree_root, protocol_contract_tree_root, private_call, - app_public_inputs + app_public_inputs, ); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr index 5f4180f1571..930117c4bcc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr @@ -8,13 +8,13 @@ unconstrained fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, private_call: PrivateCallDataWithoutPublicInputs, - app_public_inputs: PrivateCircuitPublicInputs + app_public_inputs: PrivateCircuitPublicInputs, ) -> pub PrivateKernelCircuitPublicInputs { let private_inputs = PrivateKernelInnerCircuitPrivateInputs::new( previous_kernel, previous_kernel_public_inputs, private_call, - app_public_inputs + app_public_inputs, ); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr index e9d4e26f921..54a3ae66fb5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr @@ -8,13 +8,13 @@ fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, previous_kernel_public_inputs: call_data(0) PrivateKernelCircuitPublicInputs, private_call: PrivateCallDataWithoutPublicInputs, - app_public_inputs: call_data(1) PrivateCircuitPublicInputs + app_public_inputs: call_data(1) PrivateCircuitPublicInputs, ) -> return_data PrivateKernelCircuitPublicInputs { let private_inputs = PrivateKernelInnerCircuitPrivateInputs::new( previous_kernel, previous_kernel_public_inputs, private_call, - app_public_inputs + app_public_inputs, ); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr index 67489e713a9..fdadacfe1ad 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator.nr @@ -1,9 +1,11 @@ mod previous_kernel_validator_hints; -use crate::components::previous_kernel_validator::previous_kernel_validator_hints::{generate_previous_kernel_validator_hints, PreviousKernelValidatorHints}; +use crate::components::previous_kernel_validator::previous_kernel_validator_hints::{ + generate_previous_kernel_validator_hints, PreviousKernelValidatorHints, +}; use dep::types::{ abis::{log_hash::ScopedEncryptedLogHash, private_kernel_data::PrivateKernelData}, - address::AztecAddress, traits::is_empty, utils::arrays::array_length + address::AztecAddress, traits::is_empty, utils::arrays::array_length, }; pub struct PreviousKernelValidator { @@ -13,9 +15,8 @@ pub struct PreviousKernelValidator { impl PreviousKernelValidator { pub fn new(previous_kernel: PrivateKernelData) -> Self { - let hints = unsafe { - generate_previous_kernel_validator_hints(previous_kernel.public_inputs) - }; + let hints = + unsafe { generate_previous_kernel_validator_hints(previous_kernel.public_inputs) }; PreviousKernelValidator { previous_kernel, hints } } @@ -45,86 +46,134 @@ impl PreviousKernelValidator { fn validate_empty_private_call_stack(self) { // Only need to check the first item as the kernel circuits always append items to the arrays properly. assert( - is_empty(self.previous_kernel.public_inputs.end.private_call_stack[0]), "Private call stack must be empty when executing the tail circuit" + is_empty(self.previous_kernel.public_inputs.end.private_call_stack[0]), + "Private call stack must be empty when executing the tail circuit", ); } fn validate_empty_data(self) { assert( - is_empty(self.previous_kernel.public_inputs.end.public_call_requests[0]), "Public call stack must be empty when executing the tail circuit" + is_empty( + self.previous_kernel.public_inputs.end.public_call_requests[0], + ), + "Public call stack must be empty when executing the tail circuit", ); assert( - is_empty(self.previous_kernel.public_inputs.public_teardown_call_request), "Public teardown call request must be empty when executing the tail circuit" + is_empty( + self.previous_kernel.public_inputs.public_teardown_call_request, + ), + "Public teardown call request must be empty when executing the tail circuit", ); if self.previous_kernel.public_inputs.validation_requests.split_counter.is_some() { // Even when min_revertible_side_effect_counter could be non-zero in a pure private tx. // The split counter must be 0 to ensure that all the transient data are squashed. assert_eq( - self.previous_kernel.public_inputs.validation_requests.split_counter.unwrap_unchecked(), 0, "split_counter must be 0 for pure private tx" + self + .previous_kernel + .public_inputs + .validation_requests + .split_counter + .unwrap_unchecked(), + 0, + "split_counter must be 0 for pure private tx", ); } } fn validate_non_empty_data(self) { assert( - !is_empty(self.previous_kernel.public_inputs.end.public_call_requests[0]) - | !is_empty(self.previous_kernel.public_inputs.public_teardown_call_request), "Must have public calls when exporting public kernel data from the tail circuit" + !is_empty( + self.previous_kernel.public_inputs.end.public_call_requests[0], + ) + | !is_empty( + self.previous_kernel.public_inputs.public_teardown_call_request, + ), + "Must have public calls when exporting public kernel data from the tail circuit", ); assert( - self.previous_kernel.public_inputs.min_revertible_side_effect_counter != 0, "min_revertible_side_effect_counter must not be 0" + self.previous_kernel.public_inputs.min_revertible_side_effect_counter != 0, + "min_revertible_side_effect_counter must not be 0", ); if self.previous_kernel.public_inputs.validation_requests.split_counter.is_some() { assert_eq( - self.previous_kernel.public_inputs.validation_requests.split_counter.unwrap_unchecked(), self.previous_kernel.public_inputs.min_revertible_side_effect_counter, "split_counter does not match min_revertible_side_effect_counter" + self + .previous_kernel + .public_inputs + .validation_requests + .split_counter + .unwrap_unchecked(), + self.previous_kernel.public_inputs.min_revertible_side_effect_counter, + "split_counter does not match min_revertible_side_effect_counter", ); } } fn verify_empty_validation_requests(self) { assert( - is_empty(self.previous_kernel.public_inputs.validation_requests.note_hash_read_requests[0]), "Non empty note hash read requests" + is_empty( + self.previous_kernel.public_inputs.validation_requests.note_hash_read_requests[0], + ), + "Non empty note hash read requests", ); assert( - is_empty(self.previous_kernel.public_inputs.validation_requests.nullifier_read_requests[0]), "Non empty nullifier read requests" + is_empty( + self.previous_kernel.public_inputs.validation_requests.nullifier_read_requests[0], + ), + "Non empty nullifier read requests", ); assert( is_empty( - self.previous_kernel.public_inputs.validation_requests.scoped_key_validation_requests_and_generators[0] - ), "Non empty key validation requests" + self + .previous_kernel + .public_inputs + .validation_requests + .scoped_key_validation_requests_and_generators[0], + ), + "Non empty key validation requests", ); } fn verify_sorted_siloed_values(self) { // Check that the data are already siloed and/or sorted in the reset circuit. // Any unprocessed data added after the last reset with siloing was called should be caught here. - let num_note_hashes = array_length(self.previous_kernel.public_inputs.end.note_hashes); if num_note_hashes != 0 { let note_hash = self.previous_kernel.public_inputs.end.note_hashes[num_note_hashes - 1]; assert_eq( - note_hash.contract_address, AztecAddress::zero(), "note hashes have not been siloed in a reset" + note_hash.contract_address, + AztecAddress::zero(), + "note hashes have not been siloed in a reset", ); } let num_nullifiers = array_length(self.previous_kernel.public_inputs.end.nullifiers); let nullifier = self.previous_kernel.public_inputs.end.nullifiers[num_nullifiers - 1]; // - 1 without checking because there's at least 1 nullifier. assert_eq( - nullifier.contract_address, AztecAddress::zero(), "nullifiers have not been siloed in a reset" + nullifier.contract_address, + AztecAddress::zero(), + "nullifiers have not been siloed in a reset", ); // Note logs are not siloed, but they are sorted and their note_hash_counter should've been set to 0 in the reset circuit. - let num_note_logs = array_length(self.previous_kernel.public_inputs.end.note_encrypted_logs_hashes); + let num_note_logs = array_length( + self.previous_kernel.public_inputs.end.note_encrypted_logs_hashes, + ); if num_note_logs != 0 { - let note_log = self.previous_kernel.public_inputs.end.note_encrypted_logs_hashes[num_note_logs - 1]; + let note_log = self.previous_kernel.public_inputs.end.note_encrypted_logs_hashes[ + num_note_logs + - 1]; assert_eq(note_log.note_hash_counter, 0, "note logs have not been sorted in a reset"); } // We need to check the entire array because randomness can be 0 for encrypted logs if the app wants to reveal the actual contract address. assert( - self.previous_kernel.public_inputs.end.encrypted_logs_hashes.all(|h: ScopedEncryptedLogHash| h.log_hash.randomness == 0), "encrypted logs have not been siloed in a reset" + self.previous_kernel.public_inputs.end.encrypted_logs_hashes.all( + |h: ScopedEncryptedLogHash| h.log_hash.randomness == 0, + ), + "encrypted logs have not been siloed in a reset", ); } @@ -138,10 +187,13 @@ impl PreviousKernelValidator { if nullified_note_hash != 0 { let note_hash = note_hashes[note_hash_indexes_for_nullifiers[i]]; assert_eq( - note_hash.value(), nullified_note_hash, "Hinted siloed note hash does not match nullified note hash" + note_hash.value(), + nullified_note_hash, + "Hinted siloed note hash does not match nullified note hash", ); assert( - note_hash.counter() < nullifier.counter(), "Cannot link a note hash emitted after a nullifier" + note_hash.counter() < nullifier.counter(), + "Cannot link a note hash emitted after a nullifier", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator/previous_kernel_validator_hints.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator/previous_kernel_validator_hints.nr index b106bc1a3e0..28719890ab0 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator/previous_kernel_validator_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/previous_kernel_validator/previous_kernel_validator_hints.nr @@ -1,13 +1,16 @@ use dep::types::{ - abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, note_hash::ScopedNoteHash}, - constants::{MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX}, utils::arrays::find_index_hint + abis::{ + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, note_hash::ScopedNoteHash, + }, constants::{MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX}, utils::arrays::find_index_hint, }; pub struct PreviousKernelValidatorHints { note_hash_indexes_for_nullifiers: [u32; MAX_NULLIFIERS_PER_TX], } -pub unconstrained fn generate_previous_kernel_validator_hints(previous_kernel: PrivateKernelCircuitPublicInputs) -> PreviousKernelValidatorHints { +pub unconstrained fn generate_previous_kernel_validator_hints( + previous_kernel: PrivateKernelCircuitPublicInputs, +) -> PreviousKernelValidatorHints { let mut note_hash_indexes_for_nullifiers = [0; MAX_NULLIFIERS_PER_TX]; let note_hashes = previous_kernel.end.note_hashes; let nullifiers = previous_kernel.end.nullifiers; @@ -15,7 +18,7 @@ pub unconstrained fn generate_previous_kernel_validator_hints(previous_kernel: P let nullified_note_hash = nullifiers[i].nullifier.note_hash; let note_hash_index = find_index_hint( note_hashes, - |n: ScopedNoteHash| n.value() == nullified_note_hash + |n: ScopedNoteHash| n.value() == nullified_note_hash, ); if (nullified_note_hash != 0) & (note_hash_index != MAX_NOTE_HASHES_PER_TX) { note_hash_indexes_for_nullifiers[i] = note_hash_index; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr index ca5ca3013a3..2fa422b6c00 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr @@ -4,22 +4,24 @@ mod validate_split_ranges; use crate::components::private_call_data_validator::{ find_first_revertible_item_index::find_first_revertible_item_index, - validate_contract_address::validate_contract_address, validate_split_ranges::validate_split_ranges + validate_contract_address::validate_contract_address, + validate_split_ranges::validate_split_ranges, }; use dep::types::{ abis::{ - call_context::CallContext, kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - note_hash::ScopedNoteHash, private_call_request::PrivateCallRequest, - private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths, - private_kernel::private_call_data::PrivateCallData, side_effect::{Ordered, RangeOrdered} -}, - address::AztecAddress, constants::MAX_FIELD_VALUE, transaction::tx_request::TxRequest, - utils::arrays::find_index_hint + call_context::CallContext, kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + note_hash::ScopedNoteHash, private_call_request::PrivateCallRequest, + private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths, + private_kernel::private_call_data::PrivateCallData, side_effect::{Ordered, RangeOrdered}, + }, address::AztecAddress, constants::MAX_FIELD_VALUE, transaction::tx_request::TxRequest, + utils::arrays::find_index_hint, }; fn validate_call_context(target_context: CallContext, this_context: CallContext) { assert_eq( - target_context.msg_sender, this_context.contract_address, "incorrect msg_sender for call request" + target_context.msg_sender, + this_context.contract_address, + "incorrect msg_sender for call request", ); if !target_context.is_static_call { assert(this_context.is_static_call == false, "static call cannot make non-static calls"); @@ -30,8 +32,11 @@ fn validate_incrementing_counters_within_range( counter_start: u32, counter_end: u32, items: [T; N], - num_items: u32 -) where T: Ordered { + num_items: u32, +) +where + T: Ordered, +{ let mut prev_counter = counter_start; let mut should_check = true; for i in 0..N { @@ -39,7 +44,8 @@ fn validate_incrementing_counters_within_range( if should_check { let item = items[i]; assert( - item.counter() > prev_counter, "counter must be larger than the counter of the previous item" + item.counter() > prev_counter, + "counter must be larger than the counter of the previous item", ); prev_counter = item.counter(); } @@ -51,8 +57,11 @@ fn validate_incrementing_counter_ranges_within_range( counter_start: u32, counter_end: u32, items: [T; N], - num_items: u32 -) where T: RangeOrdered { + num_items: u32, +) +where + T: RangeOrdered, +{ let mut prev_counter = counter_start; let mut should_check = true; for i in 0..N { @@ -60,14 +69,19 @@ fn validate_incrementing_counter_ranges_within_range( if should_check { let item = items[i]; assert( - item.counter_start() > prev_counter, "start counter must be larger than the end counter of the previous call" + item.counter_start() > prev_counter, + "start counter must be larger than the end counter of the previous call", + ); + assert( + item.counter_end() > item.counter_start(), + "nested call has incorrect counter range", ); - assert(item.counter_end() > item.counter_start(), "nested call has incorrect counter range"); prev_counter = item.counter_end(); } } assert( - prev_counter < counter_end, "end counter must be smaller than the end counter of the parent call" + prev_counter < counter_end, + "end counter must be smaller than the end counter of the parent call", ); } @@ -85,7 +99,7 @@ impl PrivateCallDataValidator { pub fn validate( self, accumulated_note_hashes: [ScopedNoteHash; N], - protocol_contract_tree_root: Field + protocol_contract_tree_root: Field, ) { validate_contract_address(self.data, protocol_contract_tree_root); self.validate_call(); @@ -101,7 +115,8 @@ impl PrivateCallDataValidator { let call_context = public_inputs.call_context; assert(call_context.is_static_call == false, "Users cannot make a static call"); assert( - call_context.msg_sender == AztecAddress::from_field(MAX_FIELD_VALUE), "Users cannot set msg_sender in first call" + call_context.msg_sender == AztecAddress::from_field(MAX_FIELD_VALUE), + "Users cannot set msg_sender in first call", ); } @@ -109,39 +124,71 @@ impl PrivateCallDataValidator { pub fn validate_against_tx_request(self, tx_request: TxRequest) { let public_inputs = self.data.public_inputs; assert_eq( - tx_request.origin, public_inputs.call_context.contract_address, "contract address does not match origin" + tx_request.origin, + public_inputs.call_context.contract_address, + "contract address does not match origin", ); assert_eq( - tx_request.function_data.selector, public_inputs.call_context.function_selector, "function_selector in call_context does not match the value in tx_request" + tx_request.function_data.selector, + public_inputs.call_context.function_selector, + "function_selector in call_context does not match the value in tx_request", ); assert( - tx_request.function_data.is_private, "tx_request does not indicate the first function is private" + tx_request.function_data.is_private, + "tx_request does not indicate the first function is private", ); assert_eq( - tx_request.args_hash, public_inputs.args_hash, "args_hash in private call does not match the value in tx_request" + tx_request.args_hash, + public_inputs.args_hash, + "args_hash in private call does not match the value in tx_request", ); assert_eq( - tx_request.tx_context, public_inputs.tx_context, "tx_context in private call does not match the value in tx_request" + tx_request.tx_context, + public_inputs.tx_context, + "tx_context in private call does not match the value in tx_request", ); } pub fn validate_against_call_request(self, request: PrivateCallRequest) { let public_inputs = self.data.public_inputs; - assert_eq(request.call_context, public_inputs.call_context, "call_context does not match call request"); - assert_eq(request.args_hash, public_inputs.args_hash, "args_hash does not match call request"); - assert_eq(request.returns_hash, public_inputs.returns_hash, "returns_hash does not match call request"); assert_eq( - request.start_side_effect_counter, public_inputs.start_side_effect_counter, "start_side_effect_counter does not match call request" + request.call_context, + public_inputs.call_context, + "call_context does not match call request", + ); + assert_eq( + request.args_hash, + public_inputs.args_hash, + "args_hash does not match call request", ); assert_eq( - request.end_side_effect_counter, public_inputs.end_side_effect_counter, "end_side_effect_counter does not match call request" + request.returns_hash, + public_inputs.returns_hash, + "returns_hash does not match call request", + ); + assert_eq( + request.start_side_effect_counter, + public_inputs.start_side_effect_counter, + "start_side_effect_counter does not match call request", + ); + assert_eq( + request.end_side_effect_counter, + public_inputs.end_side_effect_counter, + "end_side_effect_counter does not match call request", ); } - pub fn validate_against_previous_kernel(self, previous_kernel: PrivateKernelCircuitPublicInputs) { + pub fn validate_against_previous_kernel( + self, + previous_kernel: PrivateKernelCircuitPublicInputs, + ) { let constants = previous_kernel.constants; let public_inputs = self.data.public_inputs; - assert_eq(public_inputs.historical_header, constants.historical_header, "mismatch historical header"); + assert_eq( + public_inputs.historical_header, + constants.historical_header, + "mismatch historical header", + ); assert_eq(public_inputs.tx_context, constants.tx_context, "mismatch tx context"); // constants.global_variables is not relevant to private functions and is ensured to be empty in PrivateKernelCircuitOutputValidator. } @@ -150,17 +197,35 @@ impl PrivateCallDataValidator { let call_context = self.data.public_inputs.call_context; if call_context.is_static_call { // No state changes are allowed for static calls: - assert_eq(self.array_lengths.note_hashes, 0, "note_hashes must be empty for static calls"); - assert_eq(self.array_lengths.nullifiers, 0, "nullifiers must be empty for static calls"); - assert_eq(self.array_lengths.l2_to_l1_msgs, 0, "l2_to_l1_msgs must be empty for static calls"); assert_eq( - self.array_lengths.note_encrypted_logs_hashes, 0, "note_encrypted_logs_hashes must be empty for static calls" + self.array_lengths.note_hashes, + 0, + "note_hashes must be empty for static calls", + ); + assert_eq( + self.array_lengths.nullifiers, + 0, + "nullifiers must be empty for static calls", + ); + assert_eq( + self.array_lengths.l2_to_l1_msgs, + 0, + "l2_to_l1_msgs must be empty for static calls", ); assert_eq( - self.array_lengths.encrypted_logs_hashes, 0, "encrypted_logs_hashes must be empty for static calls" + self.array_lengths.note_encrypted_logs_hashes, + 0, + "note_encrypted_logs_hashes must be empty for static calls", ); assert_eq( - self.array_lengths.unencrypted_logs_hashes, 0, "unencrypted_logs_hashes must be empty for static calls" + self.array_lengths.encrypted_logs_hashes, + 0, + "encrypted_logs_hashes must be empty for static calls", + ); + assert_eq( + self.array_lengths.unencrypted_logs_hashes, + 0, + "unencrypted_logs_hashes must be empty for static calls", ); } } @@ -190,14 +255,14 @@ impl PrivateCallDataValidator { let first_revertible_index = unsafe { find_first_revertible_item_index( public_inputs.min_revertible_side_effect_counter, - public_inputs.private_call_requests + public_inputs.private_call_requests, ) }; validate_split_ranges( min_revertible_side_effect_counter, first_revertible_index, public_inputs.private_call_requests, - self.array_lengths.private_call_requests + self.array_lengths.private_call_requests, ); } @@ -233,49 +298,49 @@ impl PrivateCallDataValidator { counter_start, counter_end, public_inputs.note_hash_read_requests, - self.array_lengths.note_hash_read_requests + self.array_lengths.note_hash_read_requests, ); validate_incrementing_counters_within_range( counter_start, counter_end, public_inputs.nullifier_read_requests, - self.array_lengths.nullifier_read_requests + self.array_lengths.nullifier_read_requests, ); validate_incrementing_counters_within_range( counter_start, counter_end, public_inputs.note_hashes, - self.array_lengths.note_hashes + self.array_lengths.note_hashes, ); validate_incrementing_counters_within_range( counter_start, counter_end, public_inputs.nullifiers, - self.array_lengths.nullifiers + self.array_lengths.nullifiers, ); validate_incrementing_counters_within_range( counter_start, counter_end, public_inputs.l2_to_l1_msgs, - self.array_lengths.l2_to_l1_msgs + self.array_lengths.l2_to_l1_msgs, ); validate_incrementing_counters_within_range( counter_start, counter_end, public_inputs.encrypted_logs_hashes, - self.array_lengths.encrypted_logs_hashes + self.array_lengths.encrypted_logs_hashes, ); validate_incrementing_counters_within_range( counter_start, counter_end, public_inputs.unencrypted_logs_hashes, - self.array_lengths.unencrypted_logs_hashes + self.array_lengths.unencrypted_logs_hashes, ); validate_incrementing_counter_ranges_within_range( counter_start, counter_end, public_inputs.private_call_requests, - self.array_lengths.private_call_requests + self.array_lengths.private_call_requests, ); // Validate the public call requests by checking their start counters only, as their end counters are unknown. @@ -283,21 +348,22 @@ impl PrivateCallDataValidator { counter_start, counter_end, public_inputs.public_call_requests, - self.array_lengths.public_call_requests + self.array_lengths.public_call_requests, ); - let teardown_call_request_count = if public_inputs.public_teardown_call_request.counter == 0 { - 0 - } else { - 1 - }; - validate_incrementing_counters_within_range( - counter_start, - counter_end, - [public_inputs.public_teardown_call_request], - teardown_call_request_count - ); - } + let teardown_call_request_count = if public_inputs.public_teardown_call_request.counter == 0 + { + 0 + } else { + 1 + }; + validate_incrementing_counters_within_range( + counter_start, + counter_end, + [public_inputs.public_teardown_call_request], + teardown_call_request_count, + ); + } fn validate_note_logs(self, accumulated_note_hashes: [ScopedNoteHash; N]) { let note_logs = self.data.public_inputs.note_encrypted_logs_hashes; @@ -311,16 +377,20 @@ impl PrivateCallDataValidator { let note_index = unsafe { find_index_hint( accumulated_note_hashes, - |n: ScopedNoteHash| n.counter() == note_log.note_hash_counter + |n: ScopedNoteHash| n.counter() == note_log.note_hash_counter, ) }; assert(note_index != N, "could not find note hash linked to note log"); assert_eq( - note_log.note_hash_counter, accumulated_note_hashes[note_index].counter(), "could not find note hash linked to note log" + note_log.note_hash_counter, + accumulated_note_hashes[note_index].counter(), + "could not find note hash linked to note log", ); // If the note_index points to an empty note hash, the following check will fail. assert_eq( - accumulated_note_hashes[note_index].contract_address, contract_address, "could not link a note log to a note hash in another contract" + accumulated_note_hashes[note_index].contract_address, + contract_address, + "could not link a note log to a note hash in another contract", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/find_first_revertible_item_index.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/find_first_revertible_item_index.nr index 9e929e53347..8651114f4a2 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/find_first_revertible_item_index.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/find_first_revertible_item_index.nr @@ -2,8 +2,11 @@ use dep::types::{abis::side_effect::Ordered, traits::Empty, utils::arrays::array pub unconstrained fn find_first_revertible_item_index( min_revertible_side_effect_counter: u32, - items: [T; N] -) -> u32 where T: Ordered + Empty + Eq { + items: [T; N], +) -> u32 +where + T: Ordered + Empty + Eq, +{ let mut index = N; for i in 0..N { let item = items[i]; @@ -22,7 +25,7 @@ mod tests { use dep::types::tests::fixture_builder::FixtureBuilder; struct TestBuilder { - private_call: FixtureBuilder + private_call: FixtureBuilder, } impl TestBuilder { @@ -36,7 +39,7 @@ mod tests { let index = unsafe { find_first_revertible_item_index( private_call.min_revertible_side_effect_counter, - private_call.private_call_requests + private_call.private_call_requests, ) }; assert_eq(index, expected); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr index d96536d7766..8d0eec386ed 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_contract_address.nr @@ -1,15 +1,19 @@ use dep::types::{ abis::private_kernel::private_call_data::PrivateCallData, address::AztecAddress, constants::MAX_PROTOCOL_CONTRACTS, hash::stdlib_recursion_verification_key_compress_native_vk, - merkle_tree::root::root_from_sibling_path + merkle_tree::root::root_from_sibling_path, }; -pub fn validate_contract_address(private_call_data: PrivateCallData, protocol_contract_tree_root: Field) { +pub fn validate_contract_address( + private_call_data: PrivateCallData, + protocol_contract_tree_root: Field, +) { let contract_address = private_call_data.public_inputs.call_context.contract_address; assert(!contract_address.is_zero(), "contract address cannot be zero"); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3062): Why is this using a hash function from the stdlib::recursion namespace - let private_call_vk_hash = stdlib_recursion_verification_key_compress_native_vk(private_call_data.vk); + let private_call_vk_hash = + stdlib_recursion_verification_key_compress_native_vk(private_call_data.vk); let computed_address = AztecAddress::compute_from_private_function( private_call_data.public_inputs.call_context.function_selector, @@ -18,22 +22,25 @@ pub fn validate_contract_address(private_call_data: PrivateCallData, protocol_co private_call_data.contract_class_artifact_hash, private_call_data.contract_class_public_bytecode_commitment, private_call_data.salted_initialization_hash, - private_call_data.public_keys.hash() + private_call_data.public_keys.hash(), ); let protocol_contract_index = contract_address.to_field(); - let computed_protocol_contract_tree_root = if (MAX_PROTOCOL_CONTRACTS as Field).lt(protocol_contract_index) { + let computed_protocol_contract_tree_root = if (MAX_PROTOCOL_CONTRACTS as Field).lt( + protocol_contract_index, + ) { 0 } else { root_from_sibling_path( computed_address.to_field(), protocol_contract_index, - private_call_data.protocol_contract_sibling_path + private_call_data.protocol_contract_sibling_path, ) }; assert( computed_address.eq(contract_address) - | computed_protocol_contract_tree_root.eq(protocol_contract_tree_root), "computed contract address does not match expected one" + | computed_protocol_contract_tree_root.eq(protocol_contract_tree_root), + "computed contract address does not match expected one", ); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_split_ranges.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_split_ranges.nr index 83b687e09ba..b1fb0854863 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_split_ranges.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator/validate_split_ranges.nr @@ -4,19 +4,24 @@ pub fn validate_split_ranges( min_revertible_side_effect_counter: u32, first_revertible_item_index: u32, items: [T; N], - num_items: u32 -) where T: RangeOrdered { + num_items: u32, +) +where + T: RangeOrdered, +{ if first_revertible_item_index != 0 { let last_non_revertible_item_index = first_revertible_item_index - 1; let item = items[last_non_revertible_item_index]; assert( - min_revertible_side_effect_counter > item.counter_end(), "min_revertible_side_effect_counter must be greater than the end counter of the last non revertible item" + min_revertible_side_effect_counter > item.counter_end(), + "min_revertible_side_effect_counter must be greater than the end counter of the last non revertible item", ); } if first_revertible_item_index != num_items { let item = items[first_revertible_item_index]; assert( - min_revertible_side_effect_counter <= item.counter_start(), "min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible item" + min_revertible_side_effect_counter <= item.counter_start(), + "min_revertible_side_effect_counter must be less than or equal to the start counter of the first revertible item", ); } } @@ -38,14 +43,17 @@ mod tests { pub fn split_calls(&mut self, counter: u32) { self.private_call.min_revertible_side_effect_counter = counter; - self.first_revertible_private_call_request_index = self.private_call.private_call_requests.len(); + self.first_revertible_private_call_request_index = + self.private_call.private_call_requests.len(); } pub fn add_private_call_request(&mut self, counter_start: u32, counter_end: u32) { let index = self.private_call.private_call_requests.len(); self.private_call.append_private_call_requests(1); - self.private_call.private_call_requests.storage[index].start_side_effect_counter = counter_start; - self.private_call.private_call_requests.storage[index].end_side_effect_counter = counter_end; + self.private_call.private_call_requests.storage[index].start_side_effect_counter = + counter_start; + self.private_call.private_call_requests.storage[index].end_side_effect_counter = + counter_end; self.private_call.counter = counter_end + 1; } @@ -54,7 +62,7 @@ mod tests { self.private_call.min_revertible_side_effect_counter, self.first_revertible_private_call_request_index, self.private_call.private_call_requests.storage, - self.private_call.private_call_requests.len() + self.private_call.private_call_requests.len(), ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr index 9fa956e45f3..fcc7ed1819e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_output_validator.nr @@ -1,15 +1,17 @@ use crate::components::private_kernel_circuit_public_inputs_composer::create_first_nullifier; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, - max_block_number::MaxBlockNumber, - private_circuit_public_inputs::{PrivateCircuitPublicInputs, PrivateCircuitPublicInputsArrayLengths} -}, - address::AztecAddress, traits::is_empty, transaction::tx_request::TxRequest, + kernel_circuit_public_inputs::{ + PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths, + }, max_block_number::MaxBlockNumber, + private_circuit_public_inputs::{ + PrivateCircuitPublicInputs, PrivateCircuitPublicInputsArrayLengths, + }, + }, address::AztecAddress, traits::is_empty, transaction::tx_request::TxRequest, utils::arrays::{ - assert_array_appended, assert_array_appended_reversed, assert_array_appended_scoped, - assert_array_prepended -} + assert_array_appended, assert_array_appended_reversed, assert_array_appended_scoped, + assert_array_prepended, + }, }; pub struct PrivateKernelCircuitOutputValidator { @@ -27,13 +29,13 @@ impl PrivateKernelCircuitOutputValidator { private_call: PrivateCircuitPublicInputs, private_call_array_lengths: PrivateCircuitPublicInputsArrayLengths, vk_tree_root: Field, - protocol_contract_tree_root: Field + protocol_contract_tree_root: Field, ) { self.validate_initial_values( tx_request, private_call, vk_tree_root, - protocol_contract_tree_root + protocol_contract_tree_root, ); let mut offsets = PrivateKernelCircuitPublicInputsArrayLengths::empty(); offsets.nullifiers = 1; // The first nullifier is not propagated from the private call. @@ -41,7 +43,7 @@ impl PrivateKernelCircuitOutputValidator { private_call, private_call_array_lengths, offsets, - 0 // num_popped_call + 0, // num_popped_call ); } @@ -50,15 +52,18 @@ impl PrivateKernelCircuitOutputValidator { previous_kernel: PrivateKernelCircuitPublicInputs, previous_kernel_array_lengths: PrivateKernelCircuitPublicInputsArrayLengths, private_call: PrivateCircuitPublicInputs, - private_call_array_lengths: PrivateCircuitPublicInputsArrayLengths + private_call_array_lengths: PrivateCircuitPublicInputsArrayLengths, ) { self.validate_aggregated_values(previous_kernel, private_call); - self.validate_propagated_from_previous_kernel(previous_kernel, previous_kernel_array_lengths); + self.validate_propagated_from_previous_kernel( + previous_kernel, + previous_kernel_array_lengths, + ); self.validate_propagated_from_private_call( private_call, private_call_array_lengths, previous_kernel_array_lengths, - 1 // num_popped_call + 1, // num_popped_call ); } @@ -67,34 +72,49 @@ impl PrivateKernelCircuitOutputValidator { tx_request: TxRequest, private_call: PrivateCircuitPublicInputs, vk_tree_root: Field, - protocol_contract_tree_root: Field + protocol_contract_tree_root: Field, ) { // Constants. assert_eq(self.output.constants.tx_context, tx_request.tx_context, "mismatch tx_context"); assert_eq( - self.output.constants.historical_header, private_call.historical_header, "mismatch historical_header" + self.output.constants.historical_header, + private_call.historical_header, + "mismatch historical_header", + ); + assert( + is_empty(self.output.constants.global_variables), + "constants.global_variables must be empty", ); - assert(is_empty(self.output.constants.global_variables), "constants.global_variables must be empty"); assert_eq(self.output.constants.vk_tree_root, vk_tree_root, "mismatch vk_tree_root"); assert_eq( - self.output.constants.protocol_contract_tree_root, protocol_contract_tree_root, "mismatch protocol_contract_tree_root" + self.output.constants.protocol_contract_tree_root, + protocol_contract_tree_root, + "mismatch protocol_contract_tree_root", ); // First nullifier. let first_nullifier = create_first_nullifier(tx_request); assert_eq( - self.output.end.nullifiers[0], first_nullifier, "first nullifier must be the tx request nullifier" + self.output.end.nullifiers[0], + first_nullifier, + "first nullifier must be the tx request nullifier", ); // Others. assert_eq( - self.output.min_revertible_side_effect_counter, private_call.min_revertible_side_effect_counter, "incorrect initial min_revertible_side_effect_counter" + self.output.min_revertible_side_effect_counter, + private_call.min_revertible_side_effect_counter, + "incorrect initial min_revertible_side_effect_counter", ); assert_eq( - self.output.validation_requests.for_rollup.max_block_number, private_call.max_block_number, "incorrect initial max_block_number" + self.output.validation_requests.for_rollup.max_block_number, + private_call.max_block_number, + "incorrect initial max_block_number", ); assert_eq( - self.output.public_teardown_call_request, private_call.public_teardown_call_request, "incorrect initial public_teardown_call_request" + self.output.public_teardown_call_request, + private_call.public_teardown_call_request, + "incorrect initial public_teardown_call_request", ); let initial_fee_payer = if private_call.is_fee_payer { private_call.call_context.contract_address @@ -107,41 +127,53 @@ impl PrivateKernelCircuitOutputValidator { fn validate_aggregated_values( self, previous_kernel: PrivateKernelCircuitPublicInputs, - private_call: PrivateCircuitPublicInputs + private_call: PrivateCircuitPublicInputs, ) { // min_revertible_side_effect_counter - let propagated_min_revertible_counter = if previous_kernel.min_revertible_side_effect_counter != 0 { + let propagated_min_revertible_counter = if previous_kernel + .min_revertible_side_effect_counter + != 0 { assert( - private_call.min_revertible_side_effect_counter == 0, "cannot overwrite min_revertible_side_effect_counter" + private_call.min_revertible_side_effect_counter == 0, + "cannot overwrite min_revertible_side_effect_counter", ); previous_kernel.min_revertible_side_effect_counter } else { private_call.min_revertible_side_effect_counter }; assert_eq( - self.output.min_revertible_side_effect_counter, propagated_min_revertible_counter, "incorrect output min_revertible_side_effect_counter" + self.output.min_revertible_side_effect_counter, + propagated_min_revertible_counter, + "incorrect output min_revertible_side_effect_counter", ); // max_block_number let max_block_number = MaxBlockNumber::min( previous_kernel.validation_requests.for_rollup.max_block_number, - private_call.max_block_number + private_call.max_block_number, ); assert_eq( - self.output.validation_requests.for_rollup.max_block_number, max_block_number, "incorrect output max_block_number" + self.output.validation_requests.for_rollup.max_block_number, + max_block_number, + "incorrect output max_block_number", ); // public_teardown_call_request - let propagated_public_teardown_call_request = if !is_empty(previous_kernel.public_teardown_call_request) { + let propagated_public_teardown_call_request = if !is_empty( + previous_kernel.public_teardown_call_request, + ) { assert( - is_empty(private_call.public_teardown_call_request), "cannot overwrite public_teardown_call_request" + is_empty(private_call.public_teardown_call_request), + "cannot overwrite public_teardown_call_request", ); previous_kernel.public_teardown_call_request } else { private_call.public_teardown_call_request }; assert_eq( - self.output.public_teardown_call_request, propagated_public_teardown_call_request, "incorrect output public_teardown_call_request" + self.output.public_teardown_call_request, + propagated_public_teardown_call_request, + "incorrect output public_teardown_call_request", ); // fee_payer @@ -159,70 +191,72 @@ impl PrivateKernelCircuitOutputValidator { fn validate_propagated_from_previous_kernel( self, previous_kernel: PrivateKernelCircuitPublicInputs, - array_lengths: PrivateKernelCircuitPublicInputsArrayLengths + array_lengths: PrivateKernelCircuitPublicInputsArrayLengths, ) { assert_eq(self.output.constants, previous_kernel.constants, "mismatch constants"); assert_eq( - self.output.validation_requests.split_counter, previous_kernel.validation_requests.split_counter, "mismatch validation requests split counter" + self.output.validation_requests.split_counter, + previous_kernel.validation_requests.split_counter, + "mismatch validation requests split counter", ); assert_array_prepended( self.output.validation_requests.note_hash_read_requests, previous_kernel.validation_requests.note_hash_read_requests, - array_lengths.note_hash_read_requests + array_lengths.note_hash_read_requests, ); assert_array_prepended( self.output.validation_requests.nullifier_read_requests, previous_kernel.validation_requests.nullifier_read_requests, - array_lengths.nullifier_read_requests + array_lengths.nullifier_read_requests, ); assert_array_prepended( self.output.validation_requests.scoped_key_validation_requests_and_generators, previous_kernel.validation_requests.scoped_key_validation_requests_and_generators, - array_lengths.scoped_key_validation_requests_and_generators + array_lengths.scoped_key_validation_requests_and_generators, ); assert_array_prepended( self.output.end.note_hashes, previous_kernel.end.note_hashes, - array_lengths.note_hashes + array_lengths.note_hashes, ); assert_array_prepended( self.output.end.nullifiers, previous_kernel.end.nullifiers, - array_lengths.nullifiers + array_lengths.nullifiers, ); assert_array_prepended( self.output.end.l2_to_l1_msgs, previous_kernel.end.l2_to_l1_msgs, - array_lengths.l2_to_l1_msgs + array_lengths.l2_to_l1_msgs, ); assert_array_prepended( self.output.end.note_encrypted_logs_hashes, previous_kernel.end.note_encrypted_logs_hashes, - array_lengths.note_encrypted_logs_hashes + array_lengths.note_encrypted_logs_hashes, ); assert_array_prepended( self.output.end.encrypted_logs_hashes, previous_kernel.end.encrypted_logs_hashes, - array_lengths.encrypted_logs_hashes + array_lengths.encrypted_logs_hashes, ); assert_array_prepended( self.output.end.unencrypted_logs_hashes, previous_kernel.end.unencrypted_logs_hashes, - array_lengths.unencrypted_logs_hashes + array_lengths.unencrypted_logs_hashes, ); assert_array_prepended( self.output.end.public_call_requests, previous_kernel.end.public_call_requests, - array_lengths.public_call_requests + array_lengths.public_call_requests, ); // array_lengths.private_call_stack is guaranteed to be greater than 0. // It's checked in private_kernel_inner when comparing the top item in the stack with the current private call. assert_array_prepended( self.output.end.private_call_stack, previous_kernel.end.private_call_stack, - array_lengths.private_call_stack - 1 // Do not copy the top item in the stack. + array_lengths.private_call_stack - 1, // Do not copy the top item in the stack. ); } @@ -231,7 +265,7 @@ impl PrivateKernelCircuitOutputValidator { private_call: PrivateCircuitPublicInputs, array_lengths: PrivateCircuitPublicInputsArrayLengths, offsets: PrivateKernelCircuitPublicInputsArrayLengths, - num_popped_call: u32 + num_popped_call: u32, ) { let contract_address = private_call.call_context.contract_address; assert_array_appended_scoped( @@ -239,74 +273,74 @@ impl PrivateKernelCircuitOutputValidator { private_call.note_hash_read_requests, array_lengths.note_hash_read_requests, offsets.note_hash_read_requests, - contract_address + contract_address, ); assert_array_appended_scoped( self.output.validation_requests.nullifier_read_requests, private_call.nullifier_read_requests, array_lengths.nullifier_read_requests, offsets.nullifier_read_requests, - contract_address + contract_address, ); assert_array_appended_scoped( self.output.validation_requests.scoped_key_validation_requests_and_generators, private_call.key_validation_requests_and_generators, array_lengths.key_validation_requests_and_generators, offsets.scoped_key_validation_requests_and_generators, - contract_address + contract_address, ); assert_array_appended_scoped( self.output.end.note_hashes, private_call.note_hashes, array_lengths.note_hashes, offsets.note_hashes, - contract_address + contract_address, ); assert_array_appended_scoped( self.output.end.nullifiers, private_call.nullifiers, array_lengths.nullifiers, offsets.nullifiers, - contract_address + contract_address, ); assert_array_appended_scoped( self.output.end.l2_to_l1_msgs, private_call.l2_to_l1_msgs, array_lengths.l2_to_l1_msgs, offsets.l2_to_l1_msgs, - contract_address + contract_address, ); assert_array_appended( self.output.end.note_encrypted_logs_hashes, private_call.note_encrypted_logs_hashes, array_lengths.note_encrypted_logs_hashes, - offsets.note_encrypted_logs_hashes + offsets.note_encrypted_logs_hashes, ); assert_array_appended_scoped( self.output.end.encrypted_logs_hashes, private_call.encrypted_logs_hashes, array_lengths.encrypted_logs_hashes, offsets.encrypted_logs_hashes, - contract_address + contract_address, ); assert_array_appended_scoped( self.output.end.unencrypted_logs_hashes, private_call.unencrypted_logs_hashes, array_lengths.unencrypted_logs_hashes, offsets.unencrypted_logs_hashes, - contract_address + contract_address, ); assert_array_appended( self.output.end.public_call_requests, private_call.public_call_requests, array_lengths.public_call_requests, - offsets.public_call_requests + offsets.public_call_requests, ); assert_array_appended_reversed( self.output.end.private_call_stack, private_call.private_call_requests, array_lengths.private_call_requests, - offsets.private_call_stack - num_popped_call + offsets.private_call_stack - num_popped_call, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr index 782967e4843..67cfffefe28 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_kernel_circuit_public_inputs_composer.nr @@ -1,12 +1,12 @@ use dep::types::{ abis::{ - combined_constant_data::CombinedConstantData, - kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder}, - max_block_number::MaxBlockNumber, nullifier::{Nullifier, ScopedNullifier}, - private_circuit_public_inputs::PrivateCircuitPublicInputs -}, - address::AztecAddress, traits::is_empty, transaction::tx_request::TxRequest, - utils::arrays::{array_length, array_to_bounded_vec, sort_by_counter_asc, sort_by_counter_desc} + combined_constant_data::CombinedConstantData, + kernel_circuit_public_inputs::{ + PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder, + }, max_block_number::MaxBlockNumber, nullifier::{Nullifier, ScopedNullifier}, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + }, address::AztecAddress, traits::is_empty, transaction::tx_request::TxRequest, + utils::arrays::{array_length, array_to_bounded_vec, sort_by_counter_asc, sort_by_counter_desc}, }; pub fn create_first_nullifier(tx_request: TxRequest) -> ScopedNullifier { @@ -22,7 +22,7 @@ impl PrivateKernelCircuitPublicInputsComposer { tx_request: TxRequest, private_call_public_inputs: PrivateCircuitPublicInputs, vk_tree_root: Field, - protocol_contract_tree_root: Field + protocol_contract_tree_root: Field, ) -> Self { let mut public_inputs = PrivateKernelCircuitPublicInputsBuilder::empty(); @@ -39,32 +39,40 @@ impl PrivateKernelCircuitPublicInputsComposer { // Should an account want to additionally use nonces for replay protection or handling cancellations, // they will be able to do so in the account contract logic: // https://github.com/AztecProtocol/aztec-packages/issues/660 - PrivateKernelCircuitPublicInputsComposer { public_inputs } } - pub fn new_from_previous_kernel(previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs) -> Self { + pub fn new_from_previous_kernel( + previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, + ) -> Self { let mut public_inputs = PrivateKernelCircuitPublicInputsBuilder::empty(); public_inputs.constants = previous_kernel_public_inputs.constants; - public_inputs.min_revertible_side_effect_counter = previous_kernel_public_inputs.min_revertible_side_effect_counter; + public_inputs.min_revertible_side_effect_counter = + previous_kernel_public_inputs.min_revertible_side_effect_counter; public_inputs.fee_payer = previous_kernel_public_inputs.fee_payer; - public_inputs.public_teardown_call_request = previous_kernel_public_inputs.public_teardown_call_request; + public_inputs.public_teardown_call_request = + previous_kernel_public_inputs.public_teardown_call_request; let start = previous_kernel_public_inputs.validation_requests; public_inputs.validation_requests.max_block_number = start.for_rollup.max_block_number; - public_inputs.validation_requests.note_hash_read_requests = array_to_bounded_vec(start.note_hash_read_requests); - public_inputs.validation_requests.nullifier_read_requests = array_to_bounded_vec(start.nullifier_read_requests); - public_inputs.validation_requests.scoped_key_validation_requests_and_generators = array_to_bounded_vec(start.scoped_key_validation_requests_and_generators); + public_inputs.validation_requests.note_hash_read_requests = + array_to_bounded_vec(start.note_hash_read_requests); + public_inputs.validation_requests.nullifier_read_requests = + array_to_bounded_vec(start.nullifier_read_requests); + public_inputs.validation_requests.scoped_key_validation_requests_and_generators = + array_to_bounded_vec(start.scoped_key_validation_requests_and_generators); public_inputs.validation_requests.split_counter = start.split_counter; let start = previous_kernel_public_inputs.end; public_inputs.end.note_hashes = array_to_bounded_vec(start.note_hashes); public_inputs.end.nullifiers = array_to_bounded_vec(start.nullifiers); public_inputs.end.l2_to_l1_msgs = array_to_bounded_vec(start.l2_to_l1_msgs); - public_inputs.end.note_encrypted_logs_hashes = array_to_bounded_vec(start.note_encrypted_logs_hashes); + public_inputs.end.note_encrypted_logs_hashes = + array_to_bounded_vec(start.note_encrypted_logs_hashes); public_inputs.end.encrypted_logs_hashes = array_to_bounded_vec(start.encrypted_logs_hashes); - public_inputs.end.unencrypted_logs_hashes = array_to_bounded_vec(start.unencrypted_logs_hashes); + public_inputs.end.unencrypted_logs_hashes = + array_to_bounded_vec(start.unencrypted_logs_hashes); public_inputs.end.public_call_requests = array_to_bounded_vec(start.public_call_requests); public_inputs.end.private_call_stack = array_to_bounded_vec(start.private_call_stack); @@ -77,16 +85,22 @@ impl PrivateKernelCircuitPublicInputsComposer { *self } - pub fn with_private_call(&mut self, private_call_public_inputs: PrivateCircuitPublicInputs) -> Self { + pub fn with_private_call( + &mut self, + private_call_public_inputs: PrivateCircuitPublicInputs, + ) -> Self { self.propagate_from_private_call(private_call_public_inputs); *self } pub unconstrained fn sort_ordered_values(&mut self) { // Note hashes, nullifiers, note_encrypted_logs_hashes, and encrypted_logs_hashes are sorted in the reset circuit. - self.public_inputs.end.l2_to_l1_msgs.storage = sort_by_counter_asc(self.public_inputs.end.l2_to_l1_msgs.storage); - self.public_inputs.end.unencrypted_logs_hashes.storage = sort_by_counter_asc(self.public_inputs.end.unencrypted_logs_hashes.storage); - self.public_inputs.end.public_call_requests.storage = sort_by_counter_desc(self.public_inputs.end.public_call_requests.storage); + self.public_inputs.end.l2_to_l1_msgs.storage = + sort_by_counter_asc(self.public_inputs.end.l2_to_l1_msgs.storage); + self.public_inputs.end.unencrypted_logs_hashes.storage = + sort_by_counter_asc(self.public_inputs.end.unencrypted_logs_hashes.storage); + self.public_inputs.end.public_call_requests.storage = + sort_by_counter_desc(self.public_inputs.end.public_call_requests.storage); } pub fn finish(self) -> PrivateKernelCircuitPublicInputs { @@ -109,19 +123,27 @@ impl PrivateKernelCircuitPublicInputsComposer { self.propagate_min_revertible_side_effect_counter(private_call); } - fn propagate_min_revertible_side_effect_counter(&mut self, private_call: PrivateCircuitPublicInputs) { + fn propagate_min_revertible_side_effect_counter( + &mut self, + private_call: PrivateCircuitPublicInputs, + ) { if self.public_inputs.min_revertible_side_effect_counter != 0 { assert( - private_call.min_revertible_side_effect_counter == 0, "cannot overwrite non-zero min_revertible_side_effect_counter" + private_call.min_revertible_side_effect_counter == 0, + "cannot overwrite non-zero min_revertible_side_effect_counter", ); } else { - self.public_inputs.min_revertible_side_effect_counter = private_call.min_revertible_side_effect_counter; + self.public_inputs.min_revertible_side_effect_counter = + private_call.min_revertible_side_effect_counter; }; } fn propagate_max_block_number(&mut self, private_call: PrivateCircuitPublicInputs) { // Update the max block number if the private call requested a lower one. - self.public_inputs.validation_requests.max_block_number = MaxBlockNumber::min(self.public_inputs.validation_requests.max_block_number, private_call.max_block_number); + self.public_inputs.validation_requests.max_block_number = MaxBlockNumber::min( + self.public_inputs.validation_requests.max_block_number, + private_call.max_block_number, + ); } fn propagate_note_hash_read_requests(&mut self, private_call: PrivateCircuitPublicInputs) { @@ -129,7 +151,9 @@ impl PrivateKernelCircuitPublicInputsComposer { for i in 0..read_requests.len() { let request = read_requests[i]; if !is_empty(request) { - self.public_inputs.validation_requests.note_hash_read_requests.push(request.scope(private_call.call_context.contract_address)); + self.public_inputs.validation_requests.note_hash_read_requests.push(request.scope( + private_call.call_context.contract_address, + )); } } } @@ -139,17 +163,24 @@ impl PrivateKernelCircuitPublicInputsComposer { for i in 0..nullifier_read_requests.len() { let request = nullifier_read_requests[i]; if !is_empty(request) { - self.public_inputs.validation_requests.nullifier_read_requests.push(request.scope(private_call.call_context.contract_address)); + self.public_inputs.validation_requests.nullifier_read_requests.push(request.scope( + private_call.call_context.contract_address, + )); } } } fn propagate_key_validation_requests(&mut self, private_call: PrivateCircuitPublicInputs) { - let key_validation_requests_and_generators = private_call.key_validation_requests_and_generators; + let key_validation_requests_and_generators = + private_call.key_validation_requests_and_generators; for i in 0..key_validation_requests_and_generators.len() { let request = key_validation_requests_and_generators[i]; if !is_empty(request) { - self.public_inputs.validation_requests.scoped_key_validation_requests_and_generators.push(request.scope(private_call.call_context.contract_address)); + self + .public_inputs + .validation_requests + .scoped_key_validation_requests_and_generators + .push(request.scope(private_call.call_context.contract_address)); } } } @@ -159,7 +190,9 @@ impl PrivateKernelCircuitPublicInputsComposer { for i in 0..note_hashes.len() { let note_hash = note_hashes[i]; if note_hash.value != 0 { - self.public_inputs.end.note_hashes.push(note_hash.scope(private_call.call_context.contract_address)); + self.public_inputs.end.note_hashes.push(note_hash.scope( + private_call.call_context.contract_address, + )); } } } @@ -169,7 +202,9 @@ impl PrivateKernelCircuitPublicInputsComposer { for i in 0..nullifiers.len() { let nullifier = nullifiers[i]; if nullifier.value != 0 { - self.public_inputs.end.nullifiers.push(nullifier.scope(private_call.call_context.contract_address)); + self.public_inputs.end.nullifiers.push(nullifier.scope( + private_call.call_context.contract_address, + )); } } } @@ -179,7 +214,9 @@ impl PrivateKernelCircuitPublicInputsComposer { for i in 0..l2_to_l1_msgs.len() { let msg = l2_to_l1_msgs[i]; if !is_empty(msg) { - self.public_inputs.end.l2_to_l1_msgs.push(msg.scope(private_call.call_context.contract_address)); + self.public_inputs.end.l2_to_l1_msgs.push(msg.scope( + private_call.call_context.contract_address, + )); } } } @@ -189,7 +226,9 @@ impl PrivateKernelCircuitPublicInputsComposer { for i in 0..encrypted_logs.len() { let log = encrypted_logs[i]; if !is_empty(log) { - self.public_inputs.end.encrypted_logs_hashes.push(log.scope(private_call.call_context.contract_address)); + self.public_inputs.end.encrypted_logs_hashes.push(log.scope( + private_call.call_context.contract_address, + )); } } @@ -197,7 +236,9 @@ impl PrivateKernelCircuitPublicInputsComposer { for i in 0..unencrypted_logs.len() { let log = unencrypted_logs[i]; if !is_empty(log) { - self.public_inputs.end.unencrypted_logs_hashes.push(log.scope(private_call.call_context.contract_address)); + self.public_inputs.end.unencrypted_logs_hashes.push(log.scope( + private_call.call_context.contract_address, + )); } } @@ -234,7 +275,8 @@ impl PrivateKernelCircuitPublicInputsComposer { let call_request = private_call.public_teardown_call_request; if !is_empty(call_request) { assert( - is_empty(self.public_inputs.public_teardown_call_request), "Public teardown call request already set" + is_empty(self.public_inputs.public_teardown_call_request), + "Public teardown call request already set", ); self.public_inputs.public_teardown_call_request = call_request; } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr index a143d3fc069..747f6594245 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer.nr @@ -2,29 +2,22 @@ mod reset_output_hints; pub use reset_output_hints::ResetOutputHints; -use crate::components::reset_output_composer::{reset_output_hints::generate_reset_output_hints}; +use crate::components::reset_output_composer::reset_output_hints::generate_reset_output_hints; use dep::reset_kernel_lib::{TransientDataIndexHint, PrivateValidationRequestProcessor}; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - log_hash::{NoteLogHash, ScopedEncryptedLogHash}, note_hash::ScopedNoteHash, - nullifier::ScopedNullifier -}, - address::AztecAddress, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + log_hash::{NoteLogHash, ScopedEncryptedLogHash}, note_hash::ScopedNoteHash, + nullifier::ScopedNullifier, + }, address::AztecAddress, constants::{ - MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIERS_PER_TX -}, - hash::{mask_encrypted_log_hash, silo_note_hash, silo_nullifier}, utils::arrays::sort_by_counter_asc + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASHES_PER_TX, + MAX_NULLIFIERS_PER_TX, + }, hash::{mask_encrypted_log_hash, silo_note_hash, silo_nullifier}, + utils::arrays::sort_by_counter_asc, }; -pub struct ResetOutputComposer< - let NH_RR_PENDING: u32, - let NH_RR_SETTLED: u32, - let NLL_RR_PENDING: u32, - let NLL_RR_SETTLED: u32, - let KEY_VALIDATION_REQUESTS: u32, -> { +pub struct ResetOutputComposer { previous_kernel: PrivateKernelCircuitPublicInputs, validation_request_processor: PrivateValidationRequestProcessor, note_hash_siloing_amount: u32, @@ -33,26 +26,14 @@ pub struct ResetOutputComposer< hints: ResetOutputHints, } -impl< - let NH_RR_PENDING: u32, - let NH_RR_SETTLED: u32, - let NLL_RR_PENDING: u32, - let NLL_RR_SETTLED: u32, - let KEY_VALIDATION_REQUESTS: u32, -> ResetOutputComposer< - NH_RR_PENDING, - NH_RR_SETTLED, - NLL_RR_PENDING, - NLL_RR_SETTLED, - KEY_VALIDATION_REQUESTS, -> { +impl ResetOutputComposer { pub unconstrained fn new( previous_kernel: PrivateKernelCircuitPublicInputs, validation_request_processor: PrivateValidationRequestProcessor, transient_data_index_hints: [TransientDataIndexHint; TRANSIENT_DATA_AMOUNT], note_hash_siloing_amount: u32, nullifier_siloing_amount: u32, - encrypted_log_siloing_amount: u32 + encrypted_log_siloing_amount: u32, ) -> Self { let hints = generate_reset_output_hints(previous_kernel, transient_data_index_hints); ResetOutputComposer { @@ -61,7 +42,7 @@ impl< note_hash_siloing_amount, nullifier_siloing_amount, encrypted_log_siloing_amount, - hints + hints, } } @@ -97,21 +78,21 @@ impl< output } - unconstrained fn get_sorted_siloed_note_hashes(self) -> [ScopedNoteHash; MAX_NOTE_HASHES_PER_TX] { + unconstrained fn get_sorted_siloed_note_hashes( + self, + ) -> [ScopedNoteHash; MAX_NOTE_HASHES_PER_TX] { let mut note_hashes = sort_by_counter_asc(self.hints.kept_note_hashes); let first_nullifier = self.previous_kernel.end.nullifiers[0].value(); for i in 0..note_hashes.len() { - note_hashes[i].note_hash.value = silo_note_hash( - note_hashes[i], - first_nullifier, - i - ); + note_hashes[i].note_hash.value = silo_note_hash(note_hashes[i], first_nullifier, i); note_hashes[i].contract_address = AztecAddress::zero(); } note_hashes } - unconstrained fn get_sorted_siloed_nullifiers(self) -> [ScopedNullifier; MAX_NULLIFIERS_PER_TX] { + unconstrained fn get_sorted_siloed_nullifiers( + self, + ) -> [ScopedNullifier; MAX_NULLIFIERS_PER_TX] { let mut nullifiers = sort_by_counter_asc(self.hints.kept_nullifiers); for i in 0..nullifiers.len() { nullifiers[i].nullifier.value = silo_nullifier(nullifiers[i]); @@ -120,7 +101,9 @@ impl< nullifiers } - unconstrained fn get_sorted_note_encrypted_log_hashes(self) -> [NoteLogHash; MAX_NOTE_ENCRYPTED_LOGS_PER_TX] { + unconstrained fn get_sorted_note_encrypted_log_hashes( + self, + ) -> [NoteLogHash; MAX_NOTE_ENCRYPTED_LOGS_PER_TX] { let mut log_hashes = sort_by_counter_asc(self.hints.kept_note_encrypted_log_hashes); for i in 0..log_hashes.len() { log_hashes[i].note_hash_counter = 0; @@ -128,7 +111,9 @@ impl< log_hashes } - unconstrained fn get_sorted_masked_encrypted_log_hashes(self) -> [ScopedEncryptedLogHash; MAX_ENCRYPTED_LOGS_PER_TX] { + unconstrained fn get_sorted_masked_encrypted_log_hashes( + self, + ) -> [ScopedEncryptedLogHash; MAX_ENCRYPTED_LOGS_PER_TX] { let mut log_hashes = sort_by_counter_asc(self.previous_kernel.end.encrypted_logs_hashes); for i in 0..log_hashes.len() { log_hashes[i].contract_address = mask_encrypted_log_hash(log_hashes[i]); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/reset_output_hints.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/reset_output_hints.nr index 10dedc2a4af..9a669dd1701 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/reset_output_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/reset_output_composer/reset_output_hints.nr @@ -3,19 +3,18 @@ mod squash_transient_data; use crate::components::reset_output_composer::reset_output_hints::{ get_transient_or_propagated_note_hash_indexes_for_logs::get_transient_or_propagated_note_hash_indexes_for_logs, - squash_transient_data::squash_transient_data + squash_transient_data::squash_transient_data, }; use dep::reset_kernel_lib::TransientDataIndexHint; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, log_hash::NoteLogHash, - note_hash::ScopedNoteHash, nullifier::ScopedNullifier -}, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, log_hash::NoteLogHash, + note_hash::ScopedNoteHash, nullifier::ScopedNullifier, + }, constants::{ - MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIERS_PER_TX -}, - utils::arrays::{OrderHint, get_order_hints_asc} + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASHES_PER_TX, + MAX_NULLIFIERS_PER_TX, + }, utils::arrays::{OrderHint, get_order_hints_asc}, }; pub struct ResetOutputHints { @@ -35,32 +34,38 @@ pub struct ResetOutputHints { pub unconstrained fn generate_reset_output_hints( previous_kernel: PrivateKernelCircuitPublicInputs, - transient_data_index_hints: [TransientDataIndexHint; NUM_TRANSIENT_DATA_INDEX_HINTS] + transient_data_index_hints: [TransientDataIndexHint; NUM_TRANSIENT_DATA_INDEX_HINTS], ) -> ResetOutputHints { let (kept_note_hashes, kept_nullifiers, kept_note_encrypted_log_hashes) = squash_transient_data( previous_kernel.end.note_hashes, previous_kernel.end.nullifiers, previous_kernel.end.note_encrypted_logs_hashes, - transient_data_index_hints + transient_data_index_hints, ); // note_hashes - let sorted_note_hash_indexes = get_order_hints_asc(kept_note_hashes).map(|h: OrderHint| h.sorted_index); + let sorted_note_hash_indexes = + get_order_hints_asc(kept_note_hashes).map(|h: OrderHint| h.sorted_index); // nullifiers - let sorted_nullifier_indexes = get_order_hints_asc(kept_nullifiers).map(|h: OrderHint| h.sorted_index); + let sorted_nullifier_indexes = + get_order_hints_asc(kept_nullifiers).map(|h: OrderHint| h.sorted_index); // note_encrypted_log_hashes - let sorted_note_encrypted_log_hash_indexes = get_order_hints_asc(kept_note_encrypted_log_hashes).map(|h: OrderHint| h.sorted_index); + let sorted_note_encrypted_log_hash_indexes = + get_order_hints_asc(kept_note_encrypted_log_hashes).map(|h: OrderHint| h.sorted_index); let transient_or_propagated_note_hash_indexes_for_logs = get_transient_or_propagated_note_hash_indexes_for_logs( previous_kernel.end.note_encrypted_logs_hashes, previous_kernel.end.note_hashes, kept_note_hashes, - transient_data_index_hints + transient_data_index_hints, ); // encrypted_log_hashes - let sorted_encrypted_log_hash_indexes = get_order_hints_asc(previous_kernel.end.encrypted_logs_hashes).map(|h: OrderHint| h.sorted_index); + let sorted_encrypted_log_hash_indexes = get_order_hints_asc( + previous_kernel.end.encrypted_logs_hashes, + ) + .map(|h: OrderHint| h.sorted_index); ResetOutputHints { kept_note_hashes, @@ -70,6 +75,6 @@ pub unconstrained fn generate_reset_output_hints( note_logs: [NoteLogHash; NUM_LOGS], note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES], expected_note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES], - transient_data_index_hints: [TransientDataIndexHint; NUM_INDEX_HINTS] + transient_data_index_hints: [TransientDataIndexHint; NUM_INDEX_HINTS], ) -> [u32; NUM_LOGS] { let mut indexes = [0; NUM_LOGS]; for i in 0..note_logs.len() { @@ -20,7 +22,10 @@ pub unconstrained fn get_transient_or_propagated_note_hash_indexes_for_logs( note_hashes: [ScopedNoteHash; M], nullifiers: [ScopedNullifier; N], logs: [NoteLogHash; P], - transient_data_index_hints: [TransientDataIndexHint; NUM_TRANSIENT_DATA_INDEX_HINTS] + transient_data_index_hints: [TransientDataIndexHint; NUM_TRANSIENT_DATA_INDEX_HINTS], ) -> ([ScopedNoteHash; M], [ScopedNullifier; N], [NoteLogHash; P]) { let mut transient_nullifier_indexes_for_note_hashes = [N; M]; let mut transient_note_hash_indexes_for_nullifiers = [M; N]; for i in 0..transient_data_index_hints.len() { let hint = transient_data_index_hints[i]; if hint.note_hash_index != M { - transient_nullifier_indexes_for_note_hashes[hint.note_hash_index] = hint.nullifier_index; + transient_nullifier_indexes_for_note_hashes[hint.note_hash_index] = + hint.nullifier_index; transient_note_hash_indexes_for_nullifiers[hint.nullifier_index] = hint.note_hash_index; } } @@ -34,7 +37,9 @@ pub unconstrained fn squash_transient_data { +pub struct ResetOutputValidator { output: PrivateKernelCircuitPublicInputs, previous_kernel: PrivateKernelCircuitPublicInputs, validation_request_processor: PrivateValidationRequestProcessor, @@ -28,14 +24,7 @@ pub struct ResetOutputValidator< hints: ResetOutputHints, } -impl< - let NH_RR_PENDING: u32, - let NH_RR_SETTLED: u32, - let NLL_RR_PENDING: u32, - let NLL_RR_SETTLED: u32, - let KEY_VALIDATION_REQUESTS: u32, - let NUM_TRANSIENT_DATA_INDEX_HINTS: u32 -> ResetOutputValidator { +impl ResetOutputValidator { pub fn new( output: PrivateKernelCircuitPublicInputs, previous_kernel: PrivateKernelCircuitPublicInputs, @@ -44,7 +33,7 @@ impl< note_hash_siloing_amount: u32, nullifier_siloing_amount: u32, encrypted_log_siloing_amount: u32, - hints: ResetOutputHints + hints: ResetOutputHints, ) -> Self { ResetOutputValidator { output, @@ -54,7 +43,7 @@ impl< note_hash_siloing_amount, nullifier_siloing_amount, encrypted_log_siloing_amount, - hints + hints, } } @@ -72,27 +61,41 @@ impl< assert_eq(self.output.constants, self.previous_kernel.constants); assert_eq( - self.output.min_revertible_side_effect_counter, self.previous_kernel.min_revertible_side_effect_counter + self.output.min_revertible_side_effect_counter, + self.previous_kernel.min_revertible_side_effect_counter, ); - assert_eq(self.output.public_teardown_call_request, self.previous_kernel.public_teardown_call_request); + assert_eq( + self.output.public_teardown_call_request, + self.previous_kernel.public_teardown_call_request, + ); assert_eq(self.output.fee_payer, self.previous_kernel.fee_payer); // accumulated_data assert_eq(self.output.end.l2_to_l1_msgs, self.previous_kernel.end.l2_to_l1_msgs); - assert_eq(self.output.end.unencrypted_logs_hashes, self.previous_kernel.end.unencrypted_logs_hashes); - assert_eq(self.output.end.public_call_requests, self.previous_kernel.end.public_call_requests); + assert_eq( + self.output.end.unencrypted_logs_hashes, + self.previous_kernel.end.unencrypted_logs_hashes, + ); + assert_eq( + self.output.end.public_call_requests, + self.previous_kernel.end.public_call_requests, + ); assert_eq(self.output.end.private_call_stack, self.previous_kernel.end.private_call_stack); } fn validate_transient_data(self) { if NUM_TRANSIENT_DATA_INDEX_HINTS == 0 { assert_eq( - self.hints.kept_note_hashes, self.previous_kernel.end.note_hashes, "mismatch kept note hashes" + self.hints.kept_note_hashes, + self.previous_kernel.end.note_hashes, + "mismatch kept note hashes", ); assert_eq( - self.hints.kept_nullifiers, self.previous_kernel.end.nullifiers, "mismatch kept nullifiers" + self.hints.kept_nullifiers, + self.previous_kernel.end.nullifiers, + "mismatch kept nullifiers", ); } else { verify_squashed_transient_data( @@ -104,7 +107,7 @@ impl< self.hints.kept_note_encrypted_log_hashes, self.transient_data_index_hints, self.hints.transient_or_propagated_note_hash_indexes_for_logs, - self.output.validation_requests.split_counter.unwrap_unchecked() + self.output.validation_requests.split_counter.unwrap_unchecked(), ); } } @@ -113,9 +116,15 @@ impl< // note_hashes // note_encrypted_logs_hashes if self.note_hash_siloing_amount == 0 { - assert_eq(self.output.end.note_hashes, self.hints.kept_note_hashes, "output note hashes mismatch"); assert_eq( - self.output.end.note_encrypted_logs_hashes, self.hints.kept_note_encrypted_log_hashes, "output note logs mismatch" + self.output.end.note_hashes, + self.hints.kept_note_hashes, + "output note hashes mismatch", + ); + assert_eq( + self.output.end.note_encrypted_logs_hashes, + self.hints.kept_note_encrypted_log_hashes, + "output note logs mismatch", ); } else { self.validate_sorted_siloed_note_hashes(); @@ -124,7 +133,11 @@ impl< // nullifiers if self.nullifier_siloing_amount == 0 { - assert_eq(self.output.end.nullifiers, self.hints.kept_nullifiers, "output nullifiers mismatch"); + assert_eq( + self.output.end.nullifiers, + self.hints.kept_nullifiers, + "output nullifiers mismatch", + ); } else { self.validate_sorted_siloed_nullifiers(); } @@ -132,7 +145,9 @@ impl< // encrypted_logs_hashes if self.encrypted_log_siloing_amount == 0 { assert_eq( - self.output.end.encrypted_logs_hashes, self.previous_kernel.end.encrypted_logs_hashes, "output encrypted logs mismatch" + self.output.end.encrypted_logs_hashes, + self.previous_kernel.end.encrypted_logs_hashes, + "output encrypted logs mismatch", ); } else { self.validate_sorted_masked_encrypted_logs(); @@ -146,7 +161,8 @@ impl< // The first item should either be empty or not siloed (contract_address != 0). let note_hash = self.previous_kernel.end.note_hashes[0]; assert( - is_empty(note_hash) | !note_hash.contract_address.is_zero(), "note hashes have been siloed in a previous reset" + is_empty(note_hash) | !note_hash.contract_address.is_zero(), + "note hashes have been siloed in a previous reset", ); // Check siloing. @@ -171,9 +187,11 @@ impl< assert_sorted_transformed_value_array_capped_size( kept_note_hashes, siloed_note_hashes, - |prev: ScopedNoteHash, out: ScopedNoteHash| out.contract_address.is_zero() & (out.counter() == prev.counter()), + |prev: ScopedNoteHash, out: ScopedNoteHash| { + out.contract_address.is_zero() & (out.counter() == prev.counter()) + }, sorted_indexes, - self.note_hash_siloing_amount + self.note_hash_siloing_amount, ); } @@ -183,13 +201,14 @@ impl< assert_sorted_transformed_value_array_capped_size( self.hints.kept_nullifiers, self.output.end.nullifiers, - |prev: ScopedNullifier, out: ScopedNullifier| - (out.value() == silo_nullifier(prev)) & - (out.counter() == prev.counter()) & - (out.nullifier.note_hash == prev.nullifier.note_hash) & - out.contract_address.is_zero(), + |prev: ScopedNullifier, out: ScopedNullifier| { + (out.value() == silo_nullifier(prev)) + & (out.counter() == prev.counter()) + & (out.nullifier.note_hash == prev.nullifier.note_hash) + & out.contract_address.is_zero() + }, self.hints.sorted_nullifier_indexes, - self.nullifier_siloing_amount + self.nullifier_siloing_amount, ); } @@ -199,22 +218,21 @@ impl< // This is fine because we don't allow emitting logs for notes emitted in another function at the moment. // All the note logs emitted in a function call must link to note hashes emitted in the same call. // This is checked in PrivateCallDataValidator > validate_note_logs. - // note_hash_counter was used when squashing the note log along with its corresponding note hash. // It won't be used later on, so we can set it to 0 here. // It serves as a clue for the tail circuit to check that all the note logs are sorted in a reset circuit. - // This is not capped because we don't know how many logs there are. There can be any number of logs for each note hash. // Consider adding a constant for it only when this becomes too costly. assert_sorted_transformed_value_array( self.hints.kept_note_encrypted_log_hashes, self.output.end.note_encrypted_logs_hashes, - |prev: NoteLogHash, out: NoteLogHash| - (out.value == prev.value) & - (out.length == prev.length) & - (out.counter == prev.counter) & - (out.note_hash_counter == 0), - self.hints.sorted_note_encrypted_log_hash_indexes + |prev: NoteLogHash, out: NoteLogHash| { + (out.value == prev.value) + & (out.length == prev.length) + & (out.counter == prev.counter) + & (out.note_hash_counter == 0) + }, + self.hints.sorted_note_encrypted_log_hash_indexes, ); } @@ -224,14 +242,15 @@ impl< assert_sorted_transformed_value_array_capped_size( self.previous_kernel.end.encrypted_logs_hashes, self.output.end.encrypted_logs_hashes, - |prev: ScopedEncryptedLogHash, out: ScopedEncryptedLogHash| - (out.contract_address == mask_encrypted_log_hash(prev)) & - (out.log_hash.value == prev.log_hash.value) & - (out.log_hash.length == prev.log_hash.length) & - (out.log_hash.counter == prev.log_hash.counter) & - (out.log_hash.randomness == 0), + |prev: ScopedEncryptedLogHash, out: ScopedEncryptedLogHash| { + (out.contract_address == mask_encrypted_log_hash(prev)) + & (out.log_hash.value == prev.log_hash.value) + & (out.log_hash.length == prev.log_hash.length) + & (out.log_hash.counter == prev.log_hash.counter) + & (out.log_hash.randomness == 0) + }, self.hints.sorted_encrypted_log_hash_indexes, - self.encrypted_log_siloing_amount + self.encrypted_log_siloing_amount, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr index fea9bb3c97d..50ebb157830 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer.nr @@ -2,16 +2,15 @@ mod meter_gas_used; use crate::components::{ private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer, - tail_output_composer::meter_gas_used::meter_gas_used + tail_output_composer::meter_gas_used::meter_gas_used, }; use dep::types::{ abis::{ - accumulated_data::combined_accumulated_data::CombinedAccumulatedData, - kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs}, - log_hash::{ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash}, note_hash::ScopedNoteHash, - nullifier::ScopedNullifier -}, - messaging::l2_to_l1_message::ScopedL2ToL1Message + accumulated_data::combined_accumulated_data::CombinedAccumulatedData, + kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs}, + log_hash::{ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash}, note_hash::ScopedNoteHash, + nullifier::ScopedNullifier, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, }; pub struct TailOutputComposer { @@ -20,7 +19,8 @@ pub struct TailOutputComposer { impl TailOutputComposer { pub unconstrained fn new(previous_kernel: PrivateKernelCircuitPublicInputs) -> Self { - let mut output_composer = PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel); + let mut output_composer = + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel); output_composer.sort_ordered_values(); TailOutputComposer { output_composer } @@ -41,14 +41,29 @@ impl TailOutputComposer { let mut data = CombinedAccumulatedData::empty(); data.note_hashes = source.note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash.value); data.nullifiers = source.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier.value); - data.l2_to_l1_msgs = source.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| m.expose_to_public()); - data.note_encrypted_logs_hashes = source.note_encrypted_logs_hashes.storage.map(|l: NoteLogHash| l.expose_to_public()); - data.encrypted_logs_hashes = source.encrypted_logs_hashes.storage.map(|l: ScopedEncryptedLogHash| l.expose_to_public()); - data.unencrypted_logs_hashes = source.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| l.expose_to_public()); - data.note_encrypted_log_preimages_length = source.note_encrypted_logs_hashes.storage.fold(0, |len, l: NoteLogHash| len + l.length); - data.encrypted_log_preimages_length = source.encrypted_logs_hashes.storage.fold(0, |len, l: ScopedEncryptedLogHash| len + l.log_hash.length); - data.unencrypted_log_preimages_length = source.unencrypted_logs_hashes.storage.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); - data.gas_used = meter_gas_used(data, self.output_composer.public_inputs.constants.tx_context.gas_settings); + data.l2_to_l1_msgs = + source.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| m.expose_to_public()); + data.note_encrypted_logs_hashes = + source.note_encrypted_logs_hashes.storage.map(|l: NoteLogHash| l.expose_to_public()); + data.encrypted_logs_hashes = source.encrypted_logs_hashes.storage.map( + |l: ScopedEncryptedLogHash| l.expose_to_public(), + ); + data.unencrypted_logs_hashes = + source.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| l.expose_to_public()); + data.note_encrypted_log_preimages_length = + source.note_encrypted_logs_hashes.storage.fold(0, |len, l: NoteLogHash| len + l.length); + data.encrypted_log_preimages_length = source.encrypted_logs_hashes.storage.fold( + 0, + |len, l: ScopedEncryptedLogHash| len + l.log_hash.length, + ); + data.unencrypted_log_preimages_length = source.unencrypted_logs_hashes.storage.fold( + 0, + |len, l: ScopedLogHash| len + l.log_hash.length, + ); + data.gas_used = meter_gas_used( + data, + self.output_composer.public_inputs.constants.tx_context.gas_settings, + ); data } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer/meter_gas_used.nr index 350c9d69f7f..cbe17a44eb0 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer/meter_gas_used.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_composer/meter_gas_used.nr @@ -1,10 +1,12 @@ use dep::types::{ abis::{ - accumulated_data::combined_accumulated_data::CombinedAccumulatedData, gas::Gas, - gas_settings::GasSettings -}, - constants::{DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE}, - utils::arrays::array_length + accumulated_data::combined_accumulated_data::CombinedAccumulatedData, gas::Gas, + gas_settings::GasSettings, + }, + constants::{ + DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, + L2_GAS_PER_LOG_BYTE, + }, utils::arrays::array_length, }; pub fn meter_gas_used(data: CombinedAccumulatedData, gas_settings: GasSettings) -> Gas { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr index a4071b50910..87b11475ae8 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator.nr @@ -2,15 +2,14 @@ mod tail_output_hints; use crate::components::{ tail_output_composer::meter_gas_used::meter_gas_used, - tail_output_validator::{tail_output_hints::{generate_tail_output_hints, TailOutputHints}} + tail_output_validator::tail_output_hints::{generate_tail_output_hints, TailOutputHints}, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs}, - log_hash::{NoteLogHash, ScopedEncryptedLogHash, ScopedLogHash} -}, - messaging::l2_to_l1_message::ScopedL2ToL1Message, traits::is_empty, - utils::arrays::assert_exposed_sorted_transformed_value_array + kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs}, + log_hash::{NoteLogHash, ScopedEncryptedLogHash, ScopedLogHash}, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, traits::is_empty, + utils::arrays::assert_exposed_sorted_transformed_value_array, }; pub struct TailOutputValidator { @@ -22,11 +21,9 @@ pub struct TailOutputValidator { impl TailOutputValidator { pub fn new( output: KernelCircuitPublicInputs, - previous_kernel: PrivateKernelCircuitPublicInputs + previous_kernel: PrivateKernelCircuitPublicInputs, ) -> Self { - let hints = unsafe { - generate_tail_output_hints(previous_kernel) - }; + let hints = unsafe { generate_tail_output_hints(previous_kernel) }; TailOutputValidator { output, previous_kernel, hints } } @@ -46,7 +43,9 @@ impl TailOutputValidator { assert_eq(self.output.constants, self.previous_kernel.constants, "mismatch constants"); assert_eq( - self.output.rollup_validation_requests, self.previous_kernel.validation_requests.for_rollup, "mismatch rollup_validation_requests" + self.output.rollup_validation_requests, + self.previous_kernel.validation_requests.for_rollup, + "mismatch rollup_validation_requests", ); assert_eq(self.output.fee_payer, self.previous_kernel.fee_payer, "mismatch fee_payer"); @@ -54,7 +53,11 @@ impl TailOutputValidator { // note_hashes let note_hashes = self.previous_kernel.end.note_hashes; for i in 0..note_hashes.len() { - assert_eq(note_hashes[i].value(), self.output.end.note_hashes[i], "mismatch note_hashes"); + assert_eq( + note_hashes[i].value(), + self.output.end.note_hashes[i], + "mismatch note_hashes", + ); } // nullifiers @@ -65,12 +68,20 @@ impl TailOutputValidator { // note_encrypted_logs_hashes assert_eq( - self.previous_kernel.end.note_encrypted_logs_hashes.map(|log: NoteLogHash| log.expose_to_public()), self.output.end.note_encrypted_logs_hashes, "mismatch note_encrypted_logs_hashes" + self.previous_kernel.end.note_encrypted_logs_hashes.map(|log: NoteLogHash| { + log.expose_to_public() + }), + self.output.end.note_encrypted_logs_hashes, + "mismatch note_encrypted_logs_hashes", ); // encrypted_logs_hashes assert_eq( - self.previous_kernel.end.encrypted_logs_hashes.map(|log: ScopedEncryptedLogHash| log.expose_to_public()), self.output.end.encrypted_logs_hashes, "mismatch encrypted_logs_hashes" + self.previous_kernel.end.encrypted_logs_hashes.map(|log: ScopedEncryptedLogHash| { + log.expose_to_public() + }), + self.output.end.encrypted_logs_hashes, + "mismatch encrypted_logs_hashes", ); } @@ -80,7 +91,7 @@ impl TailOutputValidator { self.previous_kernel.end.l2_to_l1_msgs, self.output.end.l2_to_l1_msgs, |prev: ScopedL2ToL1Message, out: ScopedL2ToL1Message| out == prev.expose_to_public(), - self.hints.sorted_l2_to_l1_msg_hints + self.hints.sorted_l2_to_l1_msg_hints, ); // unencrypted_log_hashes @@ -88,14 +99,14 @@ impl TailOutputValidator { self.previous_kernel.end.unencrypted_logs_hashes, self.output.end.unencrypted_logs_hashes, |prev: ScopedLogHash, out: ScopedLogHash| out == prev.expose_to_public(), - self.hints.sorted_unencrypted_log_hash_hints + self.hints.sorted_unencrypted_log_hash_hints, ); } fn validate_gas_used(self) { let gas_used = meter_gas_used( self.output.end, - self.output.constants.tx_context.gas_settings + self.output.constants.tx_context.gas_settings, ); assert(self.output.end.gas_used == gas_used, "incorrect metered gas used"); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator/tail_output_hints.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator/tail_output_hints.nr index beecc52bc9f..171a5547035 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator/tail_output_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_output_validator/tail_output_hints.nr @@ -1,7 +1,7 @@ use dep::types::{ abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, log_hash::ScopedLogHash}, constants::{MAX_L2_TO_L1_MSGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX}, - utils::arrays::{OrderHint, sort_by_counter_asc, get_order_hints_asc} + utils::arrays::{OrderHint, sort_by_counter_asc, get_order_hints_asc}, }; pub struct TailOutputHints { @@ -12,13 +12,21 @@ pub struct TailOutputHints { sorted_unencrypted_log_hash_hints: [OrderHint; MAX_UNENCRYPTED_LOGS_PER_TX], } -pub unconstrained fn generate_tail_output_hints(previous_kernel: PrivateKernelCircuitPublicInputs) -> TailOutputHints { +pub unconstrained fn generate_tail_output_hints( + previous_kernel: PrivateKernelCircuitPublicInputs, +) -> TailOutputHints { // l2_to_l1_msgs let sorted_l2_to_l1_msg_hints = get_order_hints_asc(previous_kernel.end.l2_to_l1_msgs); // unencrypted_logs - let sorted_unencrypted_log_hashes = sort_by_counter_asc(previous_kernel.end.unencrypted_logs_hashes); - let sorted_unencrypted_log_hash_hints = get_order_hints_asc(previous_kernel.end.unencrypted_logs_hashes); + let sorted_unencrypted_log_hashes = + sort_by_counter_asc(previous_kernel.end.unencrypted_logs_hashes); + let sorted_unencrypted_log_hash_hints = + get_order_hints_asc(previous_kernel.end.unencrypted_logs_hashes); - TailOutputHints { sorted_l2_to_l1_msg_hints, sorted_unencrypted_log_hashes, sorted_unencrypted_log_hash_hints } + TailOutputHints { + sorted_l2_to_l1_msg_hints, + sorted_unencrypted_log_hashes, + sorted_unencrypted_log_hash_hints, + } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr index 10c5fa7688d..241256003e7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer.nr @@ -4,13 +4,14 @@ mod split_to_public; use crate::components::{ private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer, tail_to_public_output_composer::{ - meter_gas_used::{meter_gas_used_non_revertible, meter_gas_used_revertible}, - split_to_public::split_to_public -} + meter_gas_used::{meter_gas_used_non_revertible, meter_gas_used_revertible}, + split_to_public::split_to_public, + }, }; use dep::types::abis::{ - kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs}, - validation_requests::PublicValidationRequests + kernel_circuit_public_inputs::{ + PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, + }, validation_requests::PublicValidationRequests, }; pub struct TailToPublicOutputComposer { @@ -19,7 +20,8 @@ pub struct TailToPublicOutputComposer { impl TailToPublicOutputComposer { pub unconstrained fn new(previous_kernel: PrivateKernelCircuitPublicInputs) -> Self { - let mut output_composer = PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel); + let mut output_composer = + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel); output_composer.sort_ordered_values(); TailToPublicOutputComposer { output_composer } @@ -34,10 +36,12 @@ impl TailToPublicOutputComposer { let mut output = PublicKernelCircuitPublicInputs::empty(); output.validation_requests = validation_requests; output.constants = source.constants; - output.public_teardown_call_request = source.public_teardown_call_request.expose_to_public(); + output.public_teardown_call_request = + source.public_teardown_call_request.expose_to_public(); output.fee_payer = source.fee_payer; - let mut (end_non_revertible, end) = split_to_public(source.end, source.min_revertible_side_effect_counter); + let mut (end_non_revertible, end) = + split_to_public(source.end, source.min_revertible_side_effect_counter); end_non_revertible.gas_used = meter_gas_used_non_revertible(end_non_revertible); let teardown_gas = source.constants.tx_context.gas_settings.teardown_gas_limits; end.gas_used = meter_gas_used_revertible(end, teardown_gas); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr index 0f3d2a7183a..cc56b9bac00 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/meter_gas_used.nr @@ -1,10 +1,9 @@ use dep::types::{ abis::{accumulated_data::PublicAccumulatedData, gas::Gas, log_hash::{LogHash, ScopedLogHash}}, constants::{ - DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, FIXED_AVM_STARTUP_L2_GAS, L2_GAS_PER_NOTE_HASH, - L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE -}, - utils::arrays::array_length + DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, FIXED_AVM_STARTUP_L2_GAS, L2_GAS_PER_NOTE_HASH, + L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE, + }, utils::arrays::array_length, }; fn meter_gas_used(data: PublicAccumulatedData) -> Gas { @@ -21,15 +20,18 @@ fn meter_gas_used(data: PublicAccumulatedData) -> Gas { metered_da_bytes += array_length(data.l2_to_l1_msgs) * DA_BYTES_PER_FIELD; - let note_encrypted_log_preimages_length = data.note_encrypted_logs_hashes.fold(0, |len, l: LogHash| len + l.length); + let note_encrypted_log_preimages_length = + data.note_encrypted_logs_hashes.fold(0, |len, l: LogHash| len + l.length); metered_da_bytes += note_encrypted_log_preimages_length as u32; metered_l2_gas += note_encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - let encrypted_log_preimages_length = data.encrypted_logs_hashes.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); + let encrypted_log_preimages_length = + data.encrypted_logs_hashes.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); metered_da_bytes += encrypted_log_preimages_length as u32; metered_l2_gas += encrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; - let unencrypted_log_preimages_length = data.unencrypted_logs_hashes.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); + let unencrypted_log_preimages_length = + data.unencrypted_logs_hashes.fold(0, |len, l: ScopedLogHash| len + l.log_hash.length); metered_da_bytes += unencrypted_log_preimages_length as u32; metered_l2_gas += unencrypted_log_preimages_length as u32 * L2_GAS_PER_LOG_BYTE; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr index 0e69b2cbf89..702e6a330da 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_composer/split_to_public.nr @@ -1,14 +1,12 @@ -use dep::types::abis::{ - accumulated_data::{ +use dep::types::abis::accumulated_data::{ private_accumulated_data_builder::PrivateAccumulatedDataBuilder, public_accumulated_data::PublicAccumulatedData, - public_accumulated_data_builder::PublicAccumulatedDataBuilder -} + public_accumulated_data_builder::PublicAccumulatedDataBuilder, }; pub unconstrained fn split_to_public( data: PrivateAccumulatedDataBuilder, - min_revertible_side_effect_counter: u32 + min_revertible_side_effect_counter: u32, ) -> (PublicAccumulatedData, PublicAccumulatedData) { let mut non_revertible_builder = PublicAccumulatedDataBuilder::empty(); let mut revertible_builder = PublicAccumulatedDataBuilder::empty(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr index bbb1058d44f..2a80338180d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator.nr @@ -1,20 +1,25 @@ mod tail_to_public_output_hints; use crate::components::{ - tail_to_public_output_composer::meter_gas_used::{meter_gas_used_non_revertible, meter_gas_used_revertible}, - tail_to_public_output_validator::tail_to_public_output_hints::{generate_tail_to_public_output_hints, TailToPublicOutputHints} + tail_to_public_output_composer::meter_gas_used::{ + meter_gas_used_non_revertible, meter_gas_used_revertible, + }, + tail_to_public_output_validator::tail_to_public_output_hints::{ + generate_tail_to_public_output_hints, TailToPublicOutputHints, + }, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs}, - log_hash::{LogHash, ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash}, note_hash::ScopedNoteHash, - nullifier::{Nullifier, ScopedNullifier}, public_call_request::PublicCallRequest -}, - messaging::l2_to_l1_message::ScopedL2ToL1Message, traits::is_empty_array, + kernel_circuit_public_inputs::{ + PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, + }, log_hash::{LogHash, ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash}, + note_hash::ScopedNoteHash, nullifier::{Nullifier, ScopedNullifier}, + public_call_request::PublicCallRequest, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, traits::is_empty_array, utils::arrays::{ - assert_split_sorted_transformed_value_arrays_asc, assert_split_sorted_transformed_value_arrays_desc, - assert_split_transformed_value_arrays -} + assert_split_sorted_transformed_value_arrays_asc, + assert_split_sorted_transformed_value_arrays_desc, assert_split_transformed_value_arrays, + }, }; pub struct TailToPublicOutputValidator { @@ -26,11 +31,9 @@ pub struct TailToPublicOutputValidator { impl TailToPublicOutputValidator { pub fn new( output: PublicKernelCircuitPublicInputs, - previous_kernel: PrivateKernelCircuitPublicInputs + previous_kernel: PrivateKernelCircuitPublicInputs, ) -> Self { - let hints = unsafe { - generate_tail_to_public_output_hints(previous_kernel) - }; + let hints = unsafe { generate_tail_to_public_output_hints(previous_kernel) }; TailToPublicOutputValidator { output, previous_kernel, hints } } @@ -46,18 +49,22 @@ impl TailToPublicOutputValidator { assert_eq(self.output.revert_code, 0, "revert_code must be empty"); assert( - is_empty_array(self.output.end_non_revertible.public_data_update_requests), "non-revertible public_data_update_requests must be empty" + is_empty_array(self.output.end_non_revertible.public_data_update_requests), + "non-revertible public_data_update_requests must be empty", ); assert( - is_empty_array(self.output.end.public_data_update_requests), "revertible public_data_update_requests must be empty" + is_empty_array(self.output.end.public_data_update_requests), + "revertible public_data_update_requests must be empty", ); // public_data_update_requests assert( - is_empty_array(self.output.end_non_revertible.public_data_update_requests), "unexpected non-revertible public_data_update_requests" + is_empty_array(self.output.end_non_revertible.public_data_update_requests), + "unexpected non-revertible public_data_update_requests", ); assert( - is_empty_array(self.output.end.public_data_update_requests), "unexpected revertible public_data_update_requests" + is_empty_array(self.output.end.public_data_update_requests), + "unexpected revertible public_data_update_requests", ); } @@ -65,13 +72,17 @@ impl TailToPublicOutputValidator { assert_eq(self.output.constants, self.previous_kernel.constants, "mismatch constants"); assert_eq( - self.output.validation_requests.for_rollup, self.previous_kernel.validation_requests.for_rollup, "mismatch rollup_validation_requests" + self.output.validation_requests.for_rollup, + self.previous_kernel.validation_requests.for_rollup, + "mismatch rollup_validation_requests", ); assert_eq(self.output.fee_payer, self.previous_kernel.fee_payer, "mismatch fee_payer"); assert_eq( - self.output.public_teardown_call_request, self.previous_kernel.public_teardown_call_request.expose_to_public(), "mismatch public_teardown_call_request" + self.output.public_teardown_call_request, + self.previous_kernel.public_teardown_call_request.expose_to_public(), + "mismatch public_teardown_call_request", ); } @@ -87,7 +98,7 @@ impl TailToPublicOutputValidator { output_non_revertible.note_hashes, output_revertible.note_hashes, |prev: ScopedNoteHash, out: ScopedNoteHash| out == prev.expose_to_public(), - split_counter + split_counter, ); // nullifiers @@ -96,7 +107,7 @@ impl TailToPublicOutputValidator { output_non_revertible.nullifiers, output_revertible.nullifiers, |prev: ScopedNullifier, out: Nullifier| out == prev.expose_to_public(), - split_counter + split_counter, ); // note_encrypted_logs_hashes @@ -105,7 +116,7 @@ impl TailToPublicOutputValidator { output_non_revertible.note_encrypted_logs_hashes, output_revertible.note_encrypted_logs_hashes, |prev: NoteLogHash, out: LogHash| out == prev.expose_to_public(), - split_counter + split_counter, ); // encrypted_logs_hashes @@ -114,7 +125,7 @@ impl TailToPublicOutputValidator { output_non_revertible.encrypted_logs_hashes, output_revertible.encrypted_logs_hashes, |prev: ScopedEncryptedLogHash, out: ScopedLogHash| out == prev.expose_to_public(), - split_counter + split_counter, ); } @@ -132,7 +143,7 @@ impl TailToPublicOutputValidator { split_counter, output_non_revertible.l2_to_l1_msgs, output_revertible.l2_to_l1_msgs, - hints.sorted_l2_to_l1_msg_hints + hints.sorted_l2_to_l1_msg_hints, ); // unencrypted_logs_hashes @@ -142,7 +153,7 @@ impl TailToPublicOutputValidator { split_counter, output_non_revertible.unencrypted_logs_hashes, output_revertible.unencrypted_logs_hashes, - hints.sorted_unencrypted_log_hash_hints + hints.sorted_unencrypted_log_hash_hints, ); // public_call_requests @@ -152,19 +163,20 @@ impl TailToPublicOutputValidator { split_counter, output_non_revertible.public_call_stack, output_revertible.public_call_stack, - hints.sorted_public_call_request_hints + hints.sorted_public_call_request_hints, ) } fn validate_gas_used(self) { let gas_used = meter_gas_used_non_revertible(self.output.end_non_revertible); assert( - self.output.end_non_revertible.gas_used == gas_used, "incorrect metered non-revertible gas used" + self.output.end_non_revertible.gas_used == gas_used, + "incorrect metered non-revertible gas used", ); let gas_used = meter_gas_used_revertible( self.output.end, - self.output.constants.tx_context.gas_settings.teardown_gas_limits + self.output.constants.tx_context.gas_settings.teardown_gas_limits, ); assert(self.output.end.gas_used == gas_used, "incorrect metered revertible gas used"); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator/tail_to_public_output_hints.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator/tail_to_public_output_hints.nr index 3086bbb6cbd..f46f0af3422 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator/tail_to_public_output_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/tail_to_public_output_validator/tail_to_public_output_hints.nr @@ -1,7 +1,8 @@ use dep::types::{ - abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs}, - constants::{MAX_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX}, - utils::arrays::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints} + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + constants::{ + MAX_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX, + }, utils::arrays::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints}, }; pub struct TailToPublicOutputHints { @@ -13,17 +14,26 @@ pub struct TailToPublicOutputHints { sorted_public_call_request_hints: SplitOrderHints, } -pub unconstrained fn generate_tail_to_public_output_hints(previous_kernel: PrivateKernelCircuitPublicInputs) -> TailToPublicOutputHints { +pub unconstrained fn generate_tail_to_public_output_hints( + previous_kernel: PrivateKernelCircuitPublicInputs, +) -> TailToPublicOutputHints { let split_counter = previous_kernel.min_revertible_side_effect_counter; // l2_to_l1_msgss - let sorted_l2_to_l1_msg_hints = get_split_order_hints_asc(previous_kernel.end.l2_to_l1_msgs, split_counter); + let sorted_l2_to_l1_msg_hints = + get_split_order_hints_asc(previous_kernel.end.l2_to_l1_msgs, split_counter); // unencrypted_logs - let sorted_unencrypted_log_hash_hints = get_split_order_hints_asc(previous_kernel.end.unencrypted_logs_hashes, split_counter); + let sorted_unencrypted_log_hash_hints = + get_split_order_hints_asc(previous_kernel.end.unencrypted_logs_hashes, split_counter); // public_call_requests - let sorted_public_call_request_hints = get_split_order_hints_desc(previous_kernel.end.public_call_requests, split_counter); + let sorted_public_call_request_hints = + get_split_order_hints_desc(previous_kernel.end.public_call_requests, split_counter); - TailToPublicOutputHints { sorted_l2_to_l1_msg_hints, sorted_unencrypted_log_hash_hints, sorted_public_call_request_hints } + TailToPublicOutputHints { + sorted_l2_to_l1_msg_hints, + sorted_unencrypted_log_hash_hints, + sorted_public_call_request_hints, + } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_empty.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_empty.nr index 2456ea79062..e13bee75379 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_empty.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_empty.nr @@ -1,6 +1,9 @@ use dep::types::{ header::Header, KernelCircuitPublicInputs, traits::Empty, - recursion::{verification_key::{VerificationKey, HonkVerificationKey}, proof::RecursiveProof, traits::Verifiable} + recursion::{ + verification_key::{VerificationKey, HonkVerificationKey}, proof::RecursiveProof, + traits::Verifiable, + }, }; pub struct EmptyNestedCircuitPublicInputs { @@ -52,13 +55,15 @@ impl Empty for PrivateKernelEmptyPrivateInputs { chain_id: 0, version: 0, vk_tree_root: 0, - protocol_contract_tree_root: 0 + protocol_contract_tree_root: 0, } } } mod tests { - use crate::private_kernel_empty::{PrivateKernelEmptyPrivateInputs, EmptyNestedCircuitPublicInputs}; + use crate::private_kernel_empty::{ + PrivateKernelEmptyPrivateInputs, EmptyNestedCircuitPublicInputs, + }; use dep::types::header::Header; #[test] @@ -69,7 +74,7 @@ mod tests { chain_id: 1, version: 2, vk_tree_root: 3, - protocol_contract_tree_root: 4 + protocol_contract_tree_root: 4, }; let public_inputs = private_inputs.execute(); assert_eq(public_inputs.constants.tx_context.chain_id, 1); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index e915a6c3a62..d794b3f92af 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -1,17 +1,14 @@ -use crate::{ - components::{ +use crate::components::{ private_call_data_validator::PrivateCallDataValidator, private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, - private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer -} + private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - private_kernel::private_call_data::{PrivateCallData, PrivateCallDataWithoutPublicInputs}, - private_circuit_public_inputs::PrivateCircuitPublicInputs -}, - transaction::tx_request::TxRequest + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + private_kernel::private_call_data::{PrivateCallData, PrivateCallDataWithoutPublicInputs}, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + }, transaction::tx_request::TxRequest, }; // Initialization struct for private inputs to the private kernel @@ -28,13 +25,13 @@ impl PrivateKernelInitCircuitPrivateInputs { vk_tree_root: Field, protocol_contract_tree_root: Field, private_call: PrivateCallDataWithoutPublicInputs, - app_public_inputs: PrivateCircuitPublicInputs + app_public_inputs: PrivateCircuitPublicInputs, ) -> Self { Self { tx_request, vk_tree_root, protocol_contract_tree_root, - private_call: private_call.to_private_call_data(app_public_inputs) + private_call: private_call.to_private_call_data(app_public_inputs), } } @@ -44,21 +41,24 @@ impl PrivateKernelInitCircuitPrivateInputs { self.tx_request, private_call_public_inputs, self.vk_tree_root, - self.protocol_contract_tree_root - ).with_private_call(private_call_public_inputs).finish() + self.protocol_contract_tree_root, + ) + .with_private_call(private_call_public_inputs) + .finish() } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { // Generate output. - let output = unsafe { - self.generate_output() - }; + let output = unsafe { self.generate_output() }; // Validate inputs. let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); private_call_data_validator.validate_as_first_call(); private_call_data_validator.validate_against_tx_request(self.tx_request); - private_call_data_validator.validate(output.end.note_hashes, self.protocol_contract_tree_root); + private_call_data_validator.validate( + output.end.note_hashes, + self.protocol_contract_tree_root, + ); // Validate output. if dep::types::validate::should_validate_output() { @@ -67,7 +67,7 @@ impl PrivateKernelInitCircuitPrivateInputs { self.private_call.public_inputs, private_call_data_validator.array_lengths, self.vk_tree_root, - self.protocol_contract_tree_root + self.protocol_contract_tree_root, ); } output @@ -77,9 +77,9 @@ impl PrivateKernelInitCircuitPrivateInputs { mod tests { use crate::private_kernel_init::PrivateKernelInitCircuitPrivateInputs; use dep::types::{ - abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs}, + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq}, - transaction::tx_request::TxRequest + transaction::tx_request::TxRequest, }; struct PrivateKernelInitInputsBuilder { @@ -100,8 +100,9 @@ mod tests { tx_request: self.tx_request, private_call, vk_tree_root: FixtureBuilder::vk_tree_root(), - protocol_contract_tree_root: 0 - }.execute() + protocol_contract_tree_root: 0, + } + .execute() } } @@ -120,11 +121,11 @@ mod tests { let public_inputs = builder.execute(); assert_array_eq( public_inputs.validation_requests.note_hash_read_requests, - [note_hash_read_requests[0], note_hash_read_requests[1]] + [note_hash_read_requests[0], note_hash_read_requests[1]], ); assert_array_eq( public_inputs.end.encrypted_logs_hashes, - [encrypted_log_hashes[0]] + [encrypted_log_hashes[0]], ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index ab95790123f..40321bb4cb1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -1,26 +1,22 @@ -use crate::{ - components::{ +use crate::components::{ previous_kernel_validator::PreviousKernelValidator, private_call_data_validator::PrivateCallDataValidator, private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, - private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer -} + private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}, - private_kernel_data::{PrivateKernelData, PrivateKernelDataWithoutPublicInputs}, - private_kernel::private_call_data::{PrivateCallData, PrivateCallDataWithoutPublicInputs}, - private_circuit_public_inputs::PrivateCircuitPublicInputs -}, - constants::{PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX} + kernel_circuit_public_inputs::{ + PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths, + }, private_kernel_data::{PrivateKernelData, PrivateKernelDataWithoutPublicInputs}, + private_kernel::private_call_data::{PrivateCallData, PrivateCallDataWithoutPublicInputs}, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + }, + constants::{PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX}, }; -global ALLOWED_PREVIOUS_CIRCUITS = [ - PRIVATE_KERNEL_INIT_INDEX, - PRIVATE_KERNEL_INNER_INDEX, - PRIVATE_KERNEL_RESET_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = + [PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX]; pub struct PrivateKernelInnerCircuitPrivateInputs { previous_kernel: PrivateKernelData, @@ -32,37 +28,44 @@ impl PrivateKernelInnerCircuitPrivateInputs { previous_kernel: PrivateKernelDataWithoutPublicInputs, previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, private_call: PrivateCallDataWithoutPublicInputs, - app_public_inputs: PrivateCircuitPublicInputs + app_public_inputs: PrivateCircuitPublicInputs, ) -> Self { Self { previous_kernel: previous_kernel.to_private_kernel_data(previous_kernel_public_inputs), - private_call: private_call.to_private_call_data(app_public_inputs) + private_call: private_call.to_private_call_data(app_public_inputs), } } unconstrained fn generate_output(self) -> PrivateKernelCircuitPublicInputs { - PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).pop_top_call_request().with_private_call(self.private_call.public_inputs).finish() + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel( + self.previous_kernel.public_inputs, + ) + .pop_top_call_request() + .with_private_call(self.private_call.public_inputs) + .finish() } pub fn execute(self) -> PrivateKernelCircuitPublicInputs { // Generate output. - let output = unsafe { - self.generate_output() - }; + let output = unsafe { self.generate_output() }; // Validate inputs. let previous_kernel_validator = PreviousKernelValidator::new(self.previous_kernel); previous_kernel_validator.validate_proof(ALLOWED_PREVIOUS_CIRCUITS); let private_call_data_validator = PrivateCallDataValidator::new(self.private_call); - let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(self.previous_kernel.public_inputs); + let previous_kernel_array_lengths = + PrivateKernelCircuitPublicInputsArrayLengths::new(self.previous_kernel.public_inputs); let private_call_stack_size = previous_kernel_array_lengths.private_call_stack; - let call_request = self.previous_kernel.public_inputs.end.private_call_stack[private_call_stack_size - 1]; + let call_request = + self.previous_kernel.public_inputs.end.private_call_stack[private_call_stack_size - 1]; private_call_data_validator.validate_against_call_request(call_request); - private_call_data_validator.validate_against_previous_kernel(self.previous_kernel.public_inputs); + private_call_data_validator.validate_against_previous_kernel( + self.previous_kernel.public_inputs, + ); private_call_data_validator.validate( output.end.note_hashes, - self.previous_kernel.public_inputs.constants.protocol_contract_tree_root + self.previous_kernel.public_inputs.constants.protocol_contract_tree_root, ); // Validate output. @@ -71,7 +74,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { self.previous_kernel.public_inputs, previous_kernel_array_lengths, self.private_call.public_inputs, - private_call_data_validator.array_lengths + private_call_data_validator.array_lengths, ); } output @@ -79,11 +82,13 @@ impl PrivateKernelInnerCircuitPrivateInputs { } mod tests { - use crate::private_kernel_inner::{PrivateKernelInnerCircuitPrivateInputs, ALLOWED_PREVIOUS_CIRCUITS}; + use crate::private_kernel_inner::{ + PrivateKernelInnerCircuitPrivateInputs, ALLOWED_PREVIOUS_CIRCUITS, + }; use dep::types::{ - abis::{kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs}, + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, constants::{PRIVATE_KERNEL_INIT_INDEX, BASE_ROLLUP_INDEX}, - tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq} + tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq}, }; struct PrivateKernelInnerInputsBuilder { @@ -93,7 +98,9 @@ mod tests { impl PrivateKernelInnerInputsBuilder { pub fn new() -> Self { - let mut previous_kernel = FixtureBuilder::new_from_counter(15).in_vk_tree(PRIVATE_KERNEL_INIT_INDEX).as_parent_contract(); + let mut previous_kernel = FixtureBuilder::new_from_counter(15) + .in_vk_tree(PRIVATE_KERNEL_INIT_INDEX) + .as_parent_contract(); let private_call = FixtureBuilder::new_from_counter(200); // 0th nullifier must be non-zero. @@ -133,12 +140,18 @@ mod tests { assert_array_eq( public_inputs.validation_requests.note_hash_read_requests, [ - prev_note_hash_read_requests[0], curr_note_hash_read_requests[0], curr_note_hash_read_requests[1] - ] + prev_note_hash_read_requests[0], + curr_note_hash_read_requests[0], + curr_note_hash_read_requests[1], + ], ); assert_array_eq( public_inputs.end.encrypted_logs_hashes, - [prev_encrypted_log_hashes[0], prev_encrypted_log_hashes[1], curr_encrypted_log_hashes[0]] + [ + prev_encrypted_log_hashes[0], + prev_encrypted_log_hashes[1], + curr_encrypted_log_hashes[0], + ], ); } @@ -146,7 +159,8 @@ mod tests { fn valid_previous_kernel() { for i in 0..ALLOWED_PREVIOUS_CIRCUITS.len() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.previous_kernel = builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); + builder.previous_kernel = + builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); let _res = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr index cc339828154..d862f5c3eb0 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_reset.nr @@ -1,23 +1,20 @@ use crate::components::{ previous_kernel_validator::PreviousKernelValidator, reset_output_composer::{ResetOutputComposer, ResetOutputHints}, - reset_output_validator::ResetOutputValidator + reset_output_validator::ResetOutputValidator, }; use dep::reset_kernel_lib::{ KeyValidationHint, NoteHashReadRequestHints, NullifierReadRequestHints, - PrivateValidationRequestProcessor, TransientDataIndexHint + PrivateValidationRequestProcessor, TransientDataIndexHint, }; use dep::types::{ abis::private_kernel_data::{PrivateKernelData, PrivateKernelDataWithoutPublicInputs}, constants::{PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX}, - PrivateKernelCircuitPublicInputs + PrivateKernelCircuitPublicInputs, }; -global ALLOWED_PREVIOUS_CIRCUITS = [ - PRIVATE_KERNEL_INIT_INDEX, - PRIVATE_KERNEL_INNER_INDEX, - PRIVATE_KERNEL_RESET_INDEX -]; +global ALLOWED_PREVIOUS_CIRCUITS = + [PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX]; pub struct PrivateKernelResetHints { note_hash_read_request_hints: NoteHashReadRequestHints, @@ -32,20 +29,16 @@ pub struct PrivateKernelResetCircuitPrivateInputs, } -impl< - let NH_RR_PENDING: u32, - let NH_RR_SETTLED: u32, - let NLL_RR_PENDING: u32, - let NLL_RR_SETTLED: u32, - let KEY_VALIDATION_REQUESTS: u32, - let TRANSIENT_DATA_AMOUNT: u32 -> PrivateKernelResetCircuitPrivateInputs { +impl PrivateKernelResetCircuitPrivateInputs { fn new( previous_kernel: PrivateKernelDataWithoutPublicInputs, previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, - hints: PrivateKernelResetHints + hints: PrivateKernelResetHints, ) -> Self { - Self { previous_kernel: previous_kernel.to_private_kernel_data(previous_kernel_public_inputs), hints } + Self { + previous_kernel: previous_kernel.to_private_kernel_data(previous_kernel_public_inputs), + hints, + } } unconstrained fn generate_output( @@ -53,7 +46,7 @@ impl< validation_request_processor: PrivateValidationRequestProcessor, note_hash_siloing_amount: u32, nullifier_siloing_amount: u32, - encrypted_log_siloing_amount: u32 + encrypted_log_siloing_amount: u32, ) -> (PrivateKernelCircuitPublicInputs, ResetOutputHints) { let composer = ResetOutputComposer::new( self.previous_kernel.public_inputs, @@ -61,7 +54,7 @@ impl< self.hints.transient_data_index_hints, note_hash_siloing_amount, nullifier_siloing_amount, - encrypted_log_siloing_amount + encrypted_log_siloing_amount, ); (composer.finish(), composer.hints) } @@ -70,19 +63,31 @@ impl< self, note_hash_siloing_amount: u32, nullifier_siloing_amount: u32, - encrypted_log_siloing_amount: u32 + encrypted_log_siloing_amount: u32, ) -> PrivateKernelCircuitPublicInputs { let previous_public_inputs = self.previous_kernel.public_inputs; let validation_request_processor = PrivateValidationRequestProcessor { validation_requests: previous_public_inputs.validation_requests, note_hash_read_request_hints: self.hints.note_hash_read_request_hints, pending_note_hashes: previous_public_inputs.end.note_hashes, - note_hash_tree_root: previous_public_inputs.constants.historical_header.state.partial.note_hash_tree.root, + note_hash_tree_root: previous_public_inputs + .constants + .historical_header + .state + .partial + .note_hash_tree + .root, nullifier_read_request_hints: self.hints.nullifier_read_request_hints, pending_nullifiers: previous_public_inputs.end.nullifiers, - nullifier_tree_root: previous_public_inputs.constants.historical_header.state.partial.nullifier_tree.root, + nullifier_tree_root: previous_public_inputs + .constants + .historical_header + .state + .partial + .nullifier_tree + .root, key_validation_hints: self.hints.key_validation_hints, - validation_requests_split_counter: self.hints.validation_requests_split_counter + validation_requests_split_counter: self.hints.validation_requests_split_counter, }; // Generate output. @@ -91,7 +96,7 @@ impl< validation_request_processor, note_hash_siloing_amount, nullifier_siloing_amount, - encrypted_log_siloing_amount + encrypted_log_siloing_amount, ) }; @@ -109,8 +114,9 @@ impl< note_hash_siloing_amount, nullifier_siloing_amount, encrypted_log_siloing_amount, - output_hints - ).validate(); + output_hints, + ) + .validate(); } output @@ -118,31 +124,31 @@ impl< } mod tests { - use crate::private_kernel_reset::{PrivateKernelResetCircuitPrivateInputs, PrivateKernelResetHints, ALLOWED_PREVIOUS_CIRCUITS}; + use crate::private_kernel_reset::{ + PrivateKernelResetCircuitPrivateInputs, PrivateKernelResetHints, ALLOWED_PREVIOUS_CIRCUITS, + }; use dep::reset_kernel_lib::{ tests::{ - note_hash_read_request_hints_builder::NoteHashReadRequestHintsBuilder, - nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder - }, - TransientDataIndexHint, + note_hash_read_request_hints_builder::NoteHashReadRequestHintsBuilder, + nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder, + }, TransientDataIndexHint, reset::{ - read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus}, - key_validation_hint::KeyValidationHint - } + read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus}, + key_validation_hint::KeyValidationHint, + }, }; use dep::types::constants::{ MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_KEY_VALIDATION_REQUESTS_PER_TX, - GENERATOR_INDEX__OVSK_M, PRIVATE_KERNEL_INNER_INDEX, BASE_ROLLUP_INDEX + GENERATOR_INDEX__OVSK_M, PRIVATE_KERNEL_INNER_INDEX, BASE_ROLLUP_INDEX, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - max_block_number::MaxBlockNumber, note_hash::ScopedNoteHash, nullifier::ScopedNullifier, - log_hash::{NoteLogHash, ScopedEncryptedLogHash} - }, - address::AztecAddress, hash::{mask_encrypted_log_hash, silo_note_hash, silo_nullifier}, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + max_block_number::MaxBlockNumber, note_hash::ScopedNoteHash, nullifier::ScopedNullifier, + log_hash::{NoteLogHash, ScopedEncryptedLogHash}, + }, address::AztecAddress, hash::{mask_encrypted_log_hash, silo_note_hash, silo_nullifier}, tests::{fixture_builder::FixtureBuilder, utils::{assert_array_eq, swap_items}}, - utils::{arrays::find_index_hint}, traits::is_empty_array, point::Point + utils::arrays::find_index_hint, traits::is_empty_array, point::Point, }; struct PrivateKernelResetInputsBuilder { @@ -163,13 +169,15 @@ mod tests { Self { previous_kernel, - transient_data_index_hints: [TransientDataIndexHint::nada(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX); 6], + transient_data_index_hints: [ + TransientDataIndexHint::nada(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX); 6 + ], note_hash_read_request_hints_builder: NoteHashReadRequestHintsBuilder::new(), nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder::new(), validation_requests_split_counter: 0, note_hash_siloing_amount: 0, nullifier_siloing_amount: 0, - encrypted_log_siloing_amount: 0 + encrypted_log_siloing_amount: 0, } } } @@ -183,35 +191,44 @@ mod tests { } pub fn add_pending_note_hash_read_request(&mut self, note_hash_index: u32) { - let read_request_index = self.previous_kernel.add_read_request_for_pending_note_hash(note_hash_index); + let read_request_index = + self.previous_kernel.add_read_request_for_pending_note_hash(note_hash_index); let hint_index = self.note_hash_read_request_hints_builder.pending_read_hints.len(); let hint = PendingReadHint { read_request_index, pending_value_index: note_hash_index }; self.note_hash_read_request_hints_builder.pending_read_hints.push(hint); - self.note_hash_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; + self.note_hash_read_request_hints_builder.read_request_statuses[read_request_index] = + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; } pub fn add_pending_nullifier_read_request(&mut self, nullifier_index_offset_one: u32) { let nullifier_index = nullifier_index_offset_one + 1; // + 1 is for the first nullifier - let read_request_index = self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); + let read_request_index = + self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); let hint_index = self.nullifier_read_request_hints_builder.pending_read_hints.len(); let hint = PendingReadHint { read_request_index, pending_value_index: nullifier_index }; self.nullifier_read_request_hints_builder.pending_read_hints.push(hint); - self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; + self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; } pub fn nullify_pending_note_hash(&mut self, nullifier_index: u32, note_hash_index: u32) { let note_hash = self.previous_kernel.note_hashes.get(note_hash_index).note_hash; - self.previous_kernel.nullifiers.storage[nullifier_index].nullifier.note_hash = note_hash.value; + self.previous_kernel.nullifiers.storage[nullifier_index].nullifier.note_hash = + note_hash.value; let num_hints = unsafe { find_index_hint( self.transient_data_index_hints, - |hint: TransientDataIndexHint| hint.nullifier_index == MAX_NULLIFIERS_PER_TX + |hint: TransientDataIndexHint| hint.nullifier_index == MAX_NULLIFIERS_PER_TX, ) }; - self.transient_data_index_hints[num_hints] = TransientDataIndexHint { nullifier_index, note_hash_index }; + self.transient_data_index_hints[num_hints] = + TransientDataIndexHint { nullifier_index, note_hash_index }; } - pub fn compute_output_note_hashes(self, note_hashes: [ScopedNoteHash; N]) -> [ScopedNoteHash; N] { + pub fn compute_output_note_hashes( + self, + note_hashes: [ScopedNoteHash; N], + ) -> [ScopedNoteHash; N] { // First nullifier is tx hash. let tx_hash = self.previous_kernel.nullifiers.get_unchecked(0).value(); let mut output = note_hashes; @@ -222,7 +239,10 @@ mod tests { output } - pub fn compute_output_nullifiers(_self: Self, nullifiers: [ScopedNullifier; N]) -> [ScopedNullifier; N] { + pub fn compute_output_nullifiers( + _self: Self, + nullifiers: [ScopedNullifier; N], + ) -> [ScopedNullifier; N] { let mut output = nullifiers; for i in 1..N { output[i].nullifier.value = silo_nullifier(nullifiers[i]); @@ -231,7 +251,10 @@ mod tests { output } - pub fn compute_output_note_logs(_self: Self, logs: [NoteLogHash; N]) -> [NoteLogHash; N] { + pub fn compute_output_note_logs( + _self: Self, + logs: [NoteLogHash; N], + ) -> [NoteLogHash; N] { let mut output = logs; for i in 0..N { output[i].note_hash_counter = 0; @@ -241,7 +264,7 @@ mod tests { pub fn compute_output_encrypted_logs( _self: Self, - logs: [ScopedEncryptedLogHash; N] + logs: [ScopedEncryptedLogHash; N], ) -> [ScopedEncryptedLogHash; N] { let mut output = logs; for i in 0..N { @@ -252,25 +275,28 @@ mod tests { } pub fn execute(&mut self) -> PrivateKernelCircuitPublicInputs { - let note_hash_read_request_hints = unsafe { - self.note_hash_read_request_hints_builder.to_hints() - }; - let nullifier_read_request_hints = unsafe { - self.nullifier_read_request_hints_builder.to_hints() - }; + let note_hash_read_request_hints = + unsafe { self.note_hash_read_request_hints_builder.to_hints() }; + let nullifier_read_request_hints = + unsafe { self.nullifier_read_request_hints_builder.to_hints() }; let hints = PrivateKernelResetHints { note_hash_read_request_hints, nullifier_read_request_hints, - key_validation_hints: [KeyValidationHint::nada(MAX_KEY_VALIDATION_REQUESTS_PER_TX); 2], + key_validation_hints: [ + KeyValidationHint::nada(MAX_KEY_VALIDATION_REQUESTS_PER_TX); 2 + ], transient_data_index_hints: self.transient_data_index_hints, - validation_requests_split_counter: self.validation_requests_split_counter + validation_requests_split_counter: self.validation_requests_split_counter, }; - let kernel = PrivateKernelResetCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_data(), hints }; + let kernel = PrivateKernelResetCircuitPrivateInputs { + previous_kernel: self.previous_kernel.to_private_kernel_data(), + hints, + }; kernel.execute( self.note_hash_siloing_amount, self.nullifier_siloing_amount, - self.encrypted_log_siloing_amount + self.encrypted_log_siloing_amount, ) } @@ -382,25 +408,35 @@ mod tests { builder.add_pending_nullifier_read_request(1); // Now add some read requests that will be propagated - let remaining_note_hash_rr_index = builder.previous_kernel.add_read_request_for_pending_note_hash(1); - let note_hash_rr = builder.previous_kernel.note_hash_read_requests.storage[remaining_note_hash_rr_index]; + let remaining_note_hash_rr_index = + builder.previous_kernel.add_read_request_for_pending_note_hash(1); + let note_hash_rr = + builder.previous_kernel.note_hash_read_requests.storage[remaining_note_hash_rr_index]; - let remaining_nullifier_rr_index = builder.previous_kernel.add_read_request_for_pending_nullifier(1); - let nullifier_rr = builder.previous_kernel.nullifier_read_requests.storage[remaining_nullifier_rr_index]; + let remaining_nullifier_rr_index = + builder.previous_kernel.add_read_request_for_pending_nullifier(1); + let nullifier_rr = + builder.previous_kernel.nullifier_read_requests.storage[remaining_nullifier_rr_index]; let key_validation_index = builder.previous_kernel.add_request_for_key_validation( Point { x: 1, y: 2, is_infinite: false }, 27, - GENERATOR_INDEX__OVSK_M as Field + GENERATOR_INDEX__OVSK_M as Field, ); - let key_validation = builder.previous_kernel.scoped_key_validation_requests_and_generators.storage[key_validation_index]; + let key_validation = builder + .previous_kernel + .scoped_key_validation_requests_and_generators + .storage[key_validation_index]; // Check that they have been propagated to the next kernel let result = builder.execute(); assert_eq(result.validation_requests.note_hash_read_requests[0], note_hash_rr); assert_eq(result.validation_requests.nullifier_read_requests[0], nullifier_rr); - assert_eq(result.validation_requests.scoped_key_validation_requests_and_generators[0], key_validation); + assert_eq( + result.validation_requests.scoped_key_validation_requests_and_generators[0], + key_validation, + ); } #[test] @@ -468,15 +504,19 @@ mod tests { builder.previous_kernel.append_note_hashes_with_logs(3); // Shuffle the note hashes so they will have to be re-ordered. let tmp = builder.previous_kernel.note_hashes.storage[0]; - builder.previous_kernel.note_hashes.storage[0] = builder.previous_kernel.note_hashes.storage[1]; - builder.previous_kernel.note_hashes.storage[1] = builder.previous_kernel.note_hashes.storage[2]; + builder.previous_kernel.note_hashes.storage[0] = + builder.previous_kernel.note_hashes.storage[1]; + builder.previous_kernel.note_hashes.storage[1] = + builder.previous_kernel.note_hashes.storage[2]; builder.previous_kernel.note_hashes.storage[2] = tmp; builder.previous_kernel.append_nullifiers(3); // Shuffle the nullifers so they will have to be re-ordered. let tmp = builder.previous_kernel.nullifiers.storage[1]; - builder.previous_kernel.nullifiers.storage[1] = builder.previous_kernel.nullifiers.storage[3]; - builder.previous_kernel.nullifiers.storage[3] = builder.previous_kernel.nullifiers.storage[2]; + builder.previous_kernel.nullifiers.storage[1] = + builder.previous_kernel.nullifiers.storage[3]; + builder.previous_kernel.nullifiers.storage[3] = + builder.previous_kernel.nullifiers.storage[2]; builder.previous_kernel.nullifiers.storage[2] = tmp; // The nullifier at index 1 is nullifying the note hash at index 1; @@ -527,7 +567,8 @@ mod tests { fn valid_previous_kernel() { for i in 0..ALLOWED_PREVIOUS_CIRCUITS.len() { let mut builder = PrivateKernelResetInputsBuilder::new(); - builder.previous_kernel = builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); + builder.previous_kernel = + builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); let _res = builder.execute(); } @@ -550,7 +591,11 @@ mod tests { swap_items(&mut builder.previous_kernel.note_hashes, 1, 0); swap_items(&mut builder.previous_kernel.note_hashes, 3, 2); swap_items(&mut builder.previous_kernel.nullifiers, 2, 3); - swap_items(&mut builder.previous_kernel.note_encrypted_logs_hashes, 1, 3); + swap_items( + &mut builder.previous_kernel.note_encrypted_logs_hashes, + 1, + 3, + ); swap_items(&mut builder.previous_kernel.encrypted_logs_hashes, 1, 2); // The nullifier at index 1 is nullifying the note hash at index 3 (original index 2). builder.nullify_pending_note_hash(1, 3); @@ -558,21 +603,28 @@ mod tests { let public_inputs = builder.execute(); // The note hash at index 2 is chopped. - let output_note_hashes = builder.compute_output_note_hashes([note_hashes[0], note_hashes[1], note_hashes[3]]); + let output_note_hashes = + builder.compute_output_note_hashes([note_hashes[0], note_hashes[1], note_hashes[3]]); assert_array_eq(public_inputs.end.note_hashes, output_note_hashes); // The nullifier at index 1 is chopped. - let output_nullifiers = builder.compute_output_nullifiers([nullifiers[0], nullifiers[2], nullifiers[3]]); + let output_nullifiers = + builder.compute_output_nullifiers([nullifiers[0], nullifiers[2], nullifiers[3]]); assert_array_eq(public_inputs.end.nullifiers, output_nullifiers); // The note log at index 2 is chopped. - let output_note_logs = builder.compute_output_note_logs([note_logs[0], note_logs[1], note_logs[3]]); + let output_note_logs = + builder.compute_output_note_logs([note_logs[0], note_logs[1], note_logs[3]]); assert_array_eq( public_inputs.end.note_encrypted_logs_hashes, - output_note_logs + output_note_logs, ); - let output_logs = builder.compute_output_encrypted_logs([encrypted_logs[0], encrypted_logs[1], encrypted_logs[2]]); + let output_logs = builder.compute_output_encrypted_logs([ + encrypted_logs[0], + encrypted_logs[1], + encrypted_logs[2], + ]); assert_array_eq(public_inputs.end.encrypted_logs_hashes, output_logs); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index 3639fade081..d1fecb668cc 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -1,21 +1,18 @@ use crate::components::{ previous_kernel_validator::PreviousKernelValidator, tail_output_composer::TailOutputComposer, - tail_output_validator::TailOutputValidator + tail_output_validator::TailOutputValidator, }; use dep::types::{ abis::{ - private_kernel_data::{PrivateKernelData, PrivateKernelDataWithoutPublicInputs}, - kernel_circuit_public_inputs::KernelCircuitPublicInputs -}, + private_kernel_data::{PrivateKernelData, PrivateKernelDataWithoutPublicInputs}, + kernel_circuit_public_inputs::KernelCircuitPublicInputs, + }, constants::{PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX}, - PrivateKernelCircuitPublicInputs + PrivateKernelCircuitPublicInputs, }; -global ALLOWED_PREVIOUS_CIRCUITS = [ - PRIVATE_KERNEL_INIT_INDEX, - PRIVATE_KERNEL_INNER_INDEX, - PRIVATE_KERNEL_RESET_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = + [PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX]; pub struct PrivateKernelTailCircuitPrivateInputs { previous_kernel: PrivateKernelData, @@ -24,9 +21,11 @@ pub struct PrivateKernelTailCircuitPrivateInputs { impl PrivateKernelTailCircuitPrivateInputs { pub fn new( previous_kernel: PrivateKernelDataWithoutPublicInputs, - previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs + previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, ) -> Self { - Self { previous_kernel: previous_kernel.to_private_kernel_data(previous_kernel_public_inputs) } + Self { + previous_kernel: previous_kernel.to_private_kernel_data(previous_kernel_public_inputs), + } } unconstrained fn generate_output(self) -> KernelCircuitPublicInputs { @@ -35,9 +34,7 @@ impl PrivateKernelTailCircuitPrivateInputs { pub fn execute(self) -> KernelCircuitPublicInputs { // Generate output. - let output = unsafe { - self.generate_output() - }; + let output = unsafe { self.generate_output() }; // Validate inputs. let previous_kernel_validator = PreviousKernelValidator::new(self.previous_kernel); @@ -54,18 +51,19 @@ impl PrivateKernelTailCircuitPrivateInputs { } mod tests { - use crate::private_kernel_tail::{PrivateKernelTailCircuitPrivateInputs, ALLOWED_PREVIOUS_CIRCUITS}; + use crate::private_kernel_tail::{ + PrivateKernelTailCircuitPrivateInputs, ALLOWED_PREVIOUS_CIRCUITS, + }; use dep::types::constants::{ DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, GENERATOR_INDEX__IVSK_M, L2_GAS_PER_LOG_BYTE, - L2_GAS_PER_NULLIFIER, PRIVATE_KERNEL_INNER_INDEX, BASE_ROLLUP_INDEX + L2_GAS_PER_NULLIFIER, PRIVATE_KERNEL_INNER_INDEX, BASE_ROLLUP_INDEX, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::KernelCircuitPublicInputs, max_block_number::MaxBlockNumber, - gas::Gas, log_hash::ScopedLogHash - }, - address::{AztecAddress, EthAddress}, tests::fixture_builder::FixtureBuilder, traits::is_empty, - point::Point + kernel_circuit_public_inputs::KernelCircuitPublicInputs, + max_block_number::MaxBlockNumber, gas::Gas, log_hash::ScopedLogHash, + }, address::{AztecAddress, EthAddress}, tests::fixture_builder::FixtureBuilder, + traits::is_empty, point::Point, }; // TODO: Reduce the duplicated code/tests for PrivateKernelTailInputs and PrivateKernelTailToPublicInputs. @@ -83,7 +81,9 @@ mod tests { } pub fn execute(&mut self) -> KernelCircuitPublicInputs { - let kernel = PrivateKernelTailCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_data() }; + let kernel = PrivateKernelTailCircuitPrivateInputs { + previous_kernel: self.previous_kernel.to_private_kernel_data(), + }; kernel.execute() } @@ -121,21 +121,31 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.add_masked_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_kernel.add_masked_encrypted_log_hash( + prev_encrypted_logs_hash, + prev_encrypted_log_preimages_length, + ); builder.previous_kernel.add_unencrypted_log_hash( prev_unencrypted_logs_hash, - prev_unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length, ); // Logs for the current call stack. let unencrypted_logs_hash = 26; let unencrypted_log_preimages_length = 50; - builder.previous_kernel.add_unencrypted_log_hash(unencrypted_logs_hash, unencrypted_log_preimages_length); + builder.previous_kernel.add_unencrypted_log_hash( + unencrypted_logs_hash, + unencrypted_log_preimages_length, + ); let public_inputs = builder.execute(); - assert_eq(public_inputs.end.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); assert_eq( - public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length + public_inputs.end.encrypted_log_preimages_length, + prev_encrypted_log_preimages_length, + ); + assert_eq( + public_inputs.end.unencrypted_log_preimages_length, + unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length, ); } @@ -158,12 +168,11 @@ mod tests { let resulting_encrypted_logs = public_inputs.end.unencrypted_logs_hashes; assert_eq( - resulting_encrypted_logs, original_logs.map( - |mut log: ScopedLogHash| { - log.log_hash.counter = 0; - log - } - ) + resulting_encrypted_logs, + original_logs.map(|mut log: ScopedLogHash| { + log.log_hash.counter = 0; + log + }), ); } @@ -217,7 +226,7 @@ mod tests { let _void = builder.previous_kernel.add_request_for_key_validation( Point { x: 1, y: 2, is_infinite: false }, 27, - GENERATOR_INDEX__IVSK_M as Field + GENERATOR_INDEX__IVSK_M as Field, ); builder.failed(); } @@ -232,10 +241,12 @@ mod tests { // teardown gas // tx overhead // tx nullifier (which has DA and L2 gas) - let expected_gas_consumed = Gas::new(300, 300) + Gas::tx_overhead() + Gas::new( - DA_GAS_PER_BYTE * DA_BYTES_PER_FIELD * 1, - L2_GAS_PER_NULLIFIER * 1 - ); + let expected_gas_consumed = Gas::new(300, 300) + + Gas::tx_overhead() + + Gas::new( + DA_GAS_PER_BYTE * DA_BYTES_PER_FIELD * 1, + L2_GAS_PER_NULLIFIER * 1, + ); assert_eq(public_inputs.end.gas_used, expected_gas_consumed); } @@ -251,10 +262,12 @@ mod tests { let public_inputs = builder.execute(); assert_eq( - Gas::tx_overhead() + Gas::new( - 4 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, - 1 * L2_GAS_PER_NULLIFIER - ), public_inputs.end.gas_used + Gas::tx_overhead() + + Gas::new( + 4 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, + 1 * L2_GAS_PER_NULLIFIER, + ), + public_inputs.end.gas_used, ); } @@ -271,10 +284,12 @@ mod tests { let public_inputs = builder.execute(); assert_eq( - Gas::tx_overhead() + Gas::new( - (1 * DA_BYTES_PER_FIELD + 25) * DA_GAS_PER_BYTE , - 1 * L2_GAS_PER_NULLIFIER + 25 * L2_GAS_PER_LOG_BYTE - ), public_inputs.end.gas_used + Gas::tx_overhead() + + Gas::new( + (1 * DA_BYTES_PER_FIELD + 25) * DA_GAS_PER_BYTE, + 1 * L2_GAS_PER_NULLIFIER + 25 * L2_GAS_PER_LOG_BYTE, + ), + public_inputs.end.gas_used, ); } @@ -305,7 +320,8 @@ mod tests { fn valid_previous_kernel() { for i in 0..ALLOWED_PREVIOUS_CIRCUITS.len() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.previous_kernel = builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); + builder.previous_kernel = + builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); let _res = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr index e6bf91ede9a..93023d588c7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -1,22 +1,19 @@ use crate::components::{ previous_kernel_validator::PreviousKernelValidator, tail_to_public_output_composer::TailToPublicOutputComposer, - tail_to_public_output_validator::TailToPublicOutputValidator + tail_to_public_output_validator::TailToPublicOutputValidator, }; use dep::types::{ abis::{ - private_kernel_data::{PrivateKernelData, PrivateKernelDataWithoutPublicInputs}, - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs -}, + private_kernel_data::{PrivateKernelData, PrivateKernelDataWithoutPublicInputs}, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + }, constants::{PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX}, - PrivateKernelCircuitPublicInputs + PrivateKernelCircuitPublicInputs, }; -global ALLOWED_PREVIOUS_CIRCUITS = [ - PRIVATE_KERNEL_INIT_INDEX, - PRIVATE_KERNEL_INNER_INDEX, - PRIVATE_KERNEL_RESET_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = + [PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX]; pub struct PrivateKernelTailToPublicCircuitPrivateInputs { previous_kernel: PrivateKernelData, @@ -25,9 +22,11 @@ pub struct PrivateKernelTailToPublicCircuitPrivateInputs { impl PrivateKernelTailToPublicCircuitPrivateInputs { pub fn new( previous_kernel: PrivateKernelDataWithoutPublicInputs, - previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs + previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, ) -> Self { - Self { previous_kernel: previous_kernel.to_private_kernel_data(previous_kernel_public_inputs) } + Self { + previous_kernel: previous_kernel.to_private_kernel_data(previous_kernel_public_inputs), + } } unconstrained fn generate_output(self) -> PublicKernelCircuitPublicInputs { @@ -36,9 +35,7 @@ impl PrivateKernelTailToPublicCircuitPrivateInputs { pub fn execute(self) -> PublicKernelCircuitPublicInputs { // Generate output. - let output = unsafe { - self.generate_output() - }; + let output = unsafe { self.generate_output() }; // Validate inputs. let previous_kernel_validator = PreviousKernelValidator::new(self.previous_kernel); @@ -55,20 +52,21 @@ impl PrivateKernelTailToPublicCircuitPrivateInputs { } mod tests { - use crate::private_kernel_tail_to_public::{PrivateKernelTailToPublicCircuitPrivateInputs, ALLOWED_PREVIOUS_CIRCUITS}; + use crate::private_kernel_tail_to_public::{ + PrivateKernelTailToPublicCircuitPrivateInputs, ALLOWED_PREVIOUS_CIRCUITS, + }; use dep::types::constants::{ DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, GENERATOR_INDEX__TSK_M, L2_GAS_PER_LOG_BYTE, - L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, FIXED_AVM_STARTUP_L2_GAS + L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, FIXED_AVM_STARTUP_L2_GAS, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, gas::Gas, - note_hash::ScopedNoteHash, nullifier::{Nullifier, ScopedNullifier}, - log_hash::{LogHash, NoteLogHash} - }, - address::{AztecAddress, EthAddress}, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, gas::Gas, + note_hash::ScopedNoteHash, nullifier::{Nullifier, ScopedNullifier}, + log_hash::{LogHash, NoteLogHash}, + }, address::{AztecAddress, EthAddress}, tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq}, point::Point, - constants::PRIVATE_KERNEL_INNER_INDEX + constants::PRIVATE_KERNEL_INNER_INDEX, }; // TODO: Reduce the duplicated code/tests for PrivateKernelTailToPublicInputs and PrivateKernelTailInputs. @@ -89,7 +87,10 @@ mod tests { // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed // note_hashes for the given note_hashes. - pub fn compute_output_note_hashes(_self: Self, note_hashes: [ScopedNoteHash; N]) -> [ScopedNoteHash; N] { + pub fn compute_output_note_hashes( + _self: Self, + note_hashes: [ScopedNoteHash; N], + ) -> [ScopedNoteHash; N] { let mut output = [ScopedNoteHash::empty(); N]; for i in 0..N { output[i].note_hash.value = note_hashes[i].value(); @@ -97,7 +98,10 @@ mod tests { output } - pub fn compute_output_nullifiers(_self: Self, nullifiers: [ScopedNullifier; N]) -> [Nullifier; N] { + pub fn compute_output_nullifiers( + _self: Self, + nullifiers: [ScopedNullifier; N], + ) -> [Nullifier; N] { let mut output = [Nullifier::empty(); N]; for i in 0..N { output[i].value = nullifiers[i].value(); @@ -105,7 +109,10 @@ mod tests { output } - pub fn compute_output_note_logs(_self: Self, logs: [NoteLogHash; N]) -> [LogHash; N] { + pub fn compute_output_note_logs( + _self: Self, + logs: [NoteLogHash; N], + ) -> [LogHash; N] { let mut output = [LogHash::empty(); N]; for i in 0..N { if logs[i].value != 0 { @@ -116,7 +123,9 @@ mod tests { } pub fn execute(&mut self) -> PublicKernelCircuitPublicInputs { - let kernel = PrivateKernelTailToPublicCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_data() }; + let kernel = PrivateKernelTailToPublicCircuitPrivateInputs { + previous_kernel: self.previous_kernel.to_private_kernel_data(), + }; kernel.execute() } @@ -186,26 +195,28 @@ mod tests { assert_array_eq( public_inputs.end_non_revertible.nullifiers, - [output_nullifiers[0], output_nullifiers[1], output_nullifiers[2]] + [output_nullifiers[0], output_nullifiers[1], output_nullifiers[2]], ); assert_array_eq( public_inputs.end.nullifiers, - [output_nullifiers[3], output_nullifiers[4]] + [output_nullifiers[3], output_nullifiers[4]], ); assert_eq( - public_inputs.end.gas_used, Gas::new( + public_inputs.end.gas_used, + Gas::new( 2 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, - 2 * L2_GAS_PER_NULLIFIER - ) + 2 * L2_GAS_PER_NULLIFIER, + ), ); assert_eq( - public_inputs.end_non_revertible.gas_used, Gas::new( - 3 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, - FIXED_AVM_STARTUP_L2_GAS + 3 * L2_GAS_PER_NULLIFIER - ) - + Gas::tx_overhead() + public_inputs.end_non_revertible.gas_used, + Gas::new( + 3 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, + FIXED_AVM_STARTUP_L2_GAS + 3 * L2_GAS_PER_NULLIFIER, + ) + + Gas::tx_overhead(), ); } @@ -227,26 +238,28 @@ mod tests { assert_array_eq( public_inputs.end_non_revertible.note_hashes, - [exposed_note_hashes[0], exposed_note_hashes[1]] + [exposed_note_hashes[0], exposed_note_hashes[1]], ); assert_array_eq( public_inputs.end.note_hashes, - [exposed_note_hashes[2], exposed_note_hashes[3]] + [exposed_note_hashes[2], exposed_note_hashes[3]], ); assert_eq( - public_inputs.end.gas_used, Gas::new( + public_inputs.end.gas_used, + Gas::new( (2 * DA_BYTES_PER_FIELD) * DA_GAS_PER_BYTE, - 2 * L2_GAS_PER_NOTE_HASH - ) + 2 * L2_GAS_PER_NOTE_HASH, + ), ); assert_eq( - public_inputs.end_non_revertible.gas_used, Gas::new( - (3 * DA_BYTES_PER_FIELD) * DA_GAS_PER_BYTE, - FIXED_AVM_STARTUP_L2_GAS + L2_GAS_PER_NULLIFIER + 2 * L2_GAS_PER_NOTE_HASH - ) - + Gas::tx_overhead() + public_inputs.end_non_revertible.gas_used, + Gas::new( + (3 * DA_BYTES_PER_FIELD) * DA_GAS_PER_BYTE, + FIXED_AVM_STARTUP_L2_GAS + L2_GAS_PER_NULLIFIER + 2 * L2_GAS_PER_NOTE_HASH, + ) + + Gas::tx_overhead(), ); } @@ -272,7 +285,7 @@ mod tests { let _void = builder.previous_kernel.add_request_for_key_validation( Point { x: 1, y: 2, is_infinite: false }, 27, - GENERATOR_INDEX__TSK_M as Field + GENERATOR_INDEX__TSK_M as Field, ); builder.failed(); } @@ -287,9 +300,10 @@ mod tests { let expected_revertible_gas_used = Gas::new(300, 300); assert_eq(public_inputs.end.gas_used, expected_revertible_gas_used); - let expected_non_revertible_gas_used = Gas::tx_overhead() + Gas::new( + let expected_non_revertible_gas_used = Gas::tx_overhead() + + Gas::new( DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE * 1, - L2_GAS_PER_NULLIFIER * 1 + FIXED_AVM_STARTUP_L2_GAS + L2_GAS_PER_NULLIFIER * 1 + FIXED_AVM_STARTUP_L2_GAS, ); assert_eq(public_inputs.end_non_revertible.gas_used, expected_non_revertible_gas_used); @@ -308,9 +322,10 @@ mod tests { let expected_revertible_gas_used = Gas::new(0, 3 * FIXED_AVM_STARTUP_L2_GAS); assert_eq(public_inputs.end.gas_used, expected_revertible_gas_used); - let expected_non_revertible_gas_used = Gas::tx_overhead() + Gas::new( + let expected_non_revertible_gas_used = Gas::tx_overhead() + + Gas::new( DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE * 1, - L2_GAS_PER_NULLIFIER * 1 + 2 * FIXED_AVM_STARTUP_L2_GAS + L2_GAS_PER_NULLIFIER * 1 + 2 * FIXED_AVM_STARTUP_L2_GAS, ); assert_eq(public_inputs.end_non_revertible.gas_used, expected_non_revertible_gas_used); @@ -327,12 +342,17 @@ mod tests { let public_inputs = builder.execute(); - assert_eq(Gas::new(1 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, 0), public_inputs.end.gas_used); assert_eq( - Gas::tx_overhead() + Gas::new( - 3 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, - FIXED_AVM_STARTUP_L2_GAS + 1 * L2_GAS_PER_NULLIFIER - ), public_inputs.end_non_revertible.gas_used + Gas::new(1 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, 0), + public_inputs.end.gas_used, + ); + assert_eq( + Gas::tx_overhead() + + Gas::new( + 3 * DA_BYTES_PER_FIELD * DA_GAS_PER_BYTE, + FIXED_AVM_STARTUP_L2_GAS + 1 * L2_GAS_PER_NULLIFIER, + ), + public_inputs.end_non_revertible.gas_used, ); } @@ -348,13 +368,18 @@ mod tests { let public_inputs = builder.execute(); - assert_eq(Gas::new(13 * DA_GAS_PER_BYTE, 13 * L2_GAS_PER_LOG_BYTE), public_inputs.end.gas_used); + assert_eq( + Gas::new(13 * DA_GAS_PER_BYTE, 13 * L2_GAS_PER_LOG_BYTE), + public_inputs.end.gas_used, + ); assert_eq( - Gas::tx_overhead() + Gas::new( - (1 * DA_BYTES_PER_FIELD + 12) * DA_GAS_PER_BYTE , - FIXED_AVM_STARTUP_L2_GAS + 1 * L2_GAS_PER_NULLIFIER + 12 * L2_GAS_PER_LOG_BYTE - ), public_inputs.end_non_revertible.gas_used + Gas::tx_overhead() + + Gas::new( + (1 * DA_BYTES_PER_FIELD + 12) * DA_GAS_PER_BYTE, + FIXED_AVM_STARTUP_L2_GAS + 1 * L2_GAS_PER_NULLIFIER + 12 * L2_GAS_PER_LOG_BYTE, + ), + public_inputs.end_non_revertible.gas_used, ); } @@ -385,7 +410,8 @@ mod tests { fn valid_previous_kernel() { for i in 0..ALLOWED_PREVIOUS_CIRCUITS.len() { let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); - builder.previous_kernel = builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); + builder.previous_kernel = + builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); let _res = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/previous_kernel_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/previous_kernel_validator_builder/mod.nr index 4ecb38dc8be..904d1f8d44b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/previous_kernel_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/previous_kernel_validator_builder/mod.nr @@ -4,7 +4,7 @@ use crate::components::previous_kernel_validator::PreviousKernelValidator; use dep::types::tests::fixture_builder::FixtureBuilder; pub struct PreviousKernelValidatorBuilder { - previous_kernel: FixtureBuilder + previous_kernel: FixtureBuilder, } impl PreviousKernelValidatorBuilder { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr index 07828f8beac..5f0d70f292b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/mod.nr @@ -13,10 +13,9 @@ mod validate_private_call_requests; use crate::components::private_call_data_validator::PrivateCallDataValidator; use dep::types::{ abis::{ - note_hash::ScopedNoteHash, private_call_request::PrivateCallRequest, - private_kernel::private_call_data::PrivateCallData -}, - tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest + note_hash::ScopedNoteHash, private_call_request::PrivateCallRequest, + private_kernel::private_call_data::PrivateCallData, + }, tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest, }; pub struct PrivateCallDataValidatorBuilder { @@ -56,7 +55,7 @@ impl PrivateCallDataValidatorBuilder { accumulated_note_hashes.extend_from_bounded_vec(self.private_call.note_hashes); PrivateCallDataValidator::new(private_call).validate( accumulated_note_hashes.storage, - self.private_call.protocol_contract_tree_root + self.private_call.protocol_contract_tree_root, ); } @@ -79,7 +78,7 @@ impl PrivateCallDataValidatorBuilder { let accumulated_note_hashes = self.previous_note_hashes; PrivateCallDataValidator::new(data).validate( accumulated_note_hashes.storage, - self.private_call.protocol_contract_tree_root + self.private_call.protocol_contract_tree_root, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr index e8a547d4a1b..6878159ee2e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_against_previous_kernel.nr @@ -1,16 +1,21 @@ use crate::{ components::private_call_data_validator::PrivateCallDataValidator, - tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder + tests::private_call_data_validator_builder::PrivateCallDataValidatorBuilder, }; use dep::types::{ abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - tests::fixture_builder::FixtureBuilder + tests::fixture_builder::FixtureBuilder, }; impl PrivateCallDataValidatorBuilder { - pub fn validate_against_previous_kernel(self, previous_kernel: PrivateKernelCircuitPublicInputs) { + pub fn validate_against_previous_kernel( + self, + previous_kernel: PrivateKernelCircuitPublicInputs, + ) { let private_call = self.private_call.to_private_call_data(); - PrivateCallDataValidator::new(private_call).validate_against_previous_kernel(previous_kernel); + PrivateCallDataValidator::new(private_call).validate_against_previous_kernel( + previous_kernel, + ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr index 34eac0ae3b7..4e376e0f635 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_arrays.nr @@ -33,7 +33,9 @@ fn validate_arrays_malformed_key_validation_requests_fails() { let mut builder = PrivateCallDataValidatorBuilder::new(); builder.private_call.append_key_validation_requests(1); - unshift_empty_item(&mut builder.private_call.scoped_key_validation_requests_and_generators); + unshift_empty_item( + &mut builder.private_call.scoped_key_validation_requests_and_generators, + ); builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr index 42246ff5b14..d1a6139eb49 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_call_requests.nr @@ -27,7 +27,8 @@ fn validate_public_call_requests_incorrect_msg_sender_for_regular_call_fails() { builder.private_call.append_public_call_requests(1); // Change the msg_sender to be the caller's msg_sender. - builder.private_call.public_call_requests.storage[0].call_context.msg_sender = builder.private_call.msg_sender; + builder.private_call.public_call_requests.storage[0].call_context.msg_sender = + builder.private_call.msg_sender; builder.validate(); } @@ -70,7 +71,8 @@ fn validate_teardown_call_request_incorrect_msg_sender_for_regular_call_fails() builder.private_call.set_public_teardown_call_request(); // Change the msg_sender to be the caller's msg_sender. - builder.private_call.public_teardown_call_request.call_context.msg_sender = builder.private_call.msg_sender; + builder.private_call.public_teardown_call_request.call_context.msg_sender = + builder.private_call.msg_sender; builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr index 5272049cbf3..aba970eb404 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_contract_address.nr @@ -51,7 +51,8 @@ fn validate_contract_address_incorrect_function_leaf_sibling_path_fails() { fn validate_contract_address_incorrect_contract_class_preimage_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); - builder.private_call.contract_class_artifact_hash = builder.private_call.contract_class_artifact_hash + 1; + builder.private_call.contract_class_artifact_hash = + builder.private_call.contract_class_artifact_hash + 1; builder.validate(); } @@ -60,7 +61,8 @@ fn validate_contract_address_incorrect_contract_class_preimage_fails() { fn validate_contract_address_incorrect_partial_address_preimage_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); - builder.private_call.salted_initialization_hash.inner = builder.private_call.salted_initialization_hash.inner + 1; + builder.private_call.salted_initialization_hash.inner = + builder.private_call.salted_initialization_hash.inner + 1; builder.validate(); } @@ -69,7 +71,8 @@ fn validate_contract_address_incorrect_partial_address_preimage_fails() { fn validate_contract_address_incorrect_address_preimage_fails() { let mut builder = PrivateCallDataValidatorBuilder::new_with_regular_contract(); - builder.private_call.public_keys.ivpk_m.inner.x = builder.private_call.public_keys.ivpk_m.inner.x + 1; + builder.private_call.public_keys.ivpk_m.inner.x = + builder.private_call.public_keys.ivpk_m.inner.x + 1; builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr index aef197599da..0ee10d9b513 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_counters.nr @@ -51,7 +51,8 @@ fn validate_counters_note_hash_counter_same_as_call_counter_start_fails() { builder.private_call.append_note_hashes(1); // Tweak the counter of the first note hash to EQUAL the start counter of the call. - builder.private_call.note_hashes.storage[0].note_hash.counter = builder.private_call.counter_start; + builder.private_call.note_hashes.storage[0].note_hash.counter = + builder.private_call.counter_start; builder.validate(); } @@ -62,7 +63,8 @@ fn validate_counters_note_hash_counter_smaller_than_call_fails() { builder.private_call.append_note_hashes(1); // Tweak the counter of the first note hash to be LESS than the start counter of the call. - builder.private_call.note_hashes.storage[0].note_hash.counter = builder.private_call.counter_start - 1; + builder.private_call.note_hashes.storage[0].note_hash.counter = + builder.private_call.counter_start - 1; builder.validate(); } @@ -99,7 +101,8 @@ fn validate_counters_note_hash_counter_larger_than_call_fails() { builder.private_call.append_note_hashes(2); // Tweak the counter of the second note hash to be GREATER than the end counter of the call. - builder.private_call.note_hashes.storage[1].note_hash.counter = builder.private_call.counter + 1; + builder.private_call.note_hashes.storage[1].note_hash.counter = + builder.private_call.counter + 1; builder.validate(); } @@ -134,7 +137,8 @@ fn validate_counters_private_call_requests_less_than_call_start_fails() { builder.private_call.append_private_call_requests(1); // Tweak the start counter of the first nested call to be LESS than the start counter of the call. let counter_start = builder.private_call.counter_start; - builder.private_call.private_call_requests.storage[0].start_side_effect_counter = counter_start - 1; + builder.private_call.private_call_requests.storage[0].start_side_effect_counter = + counter_start - 1; builder.validate(); } @@ -158,7 +162,8 @@ fn validate_counters_private_call_requests_less_than_previous_end_fails() { builder.private_call.append_private_call_requests(2); // Tweak the start counter of the second nested call to be LESS than the end counter of the first nested call. let counter_end = builder.private_call.private_call_requests.get(0).end_side_effect_counter; - builder.private_call.private_call_requests.storage[1].start_side_effect_counter = counter_end - 1; + builder.private_call.private_call_requests.storage[1].start_side_effect_counter = + counter_end - 1; builder.validate(); } @@ -182,7 +187,8 @@ fn validate_counters_private_call_requests_end_less_than_start_fails() { builder.private_call.append_private_call_requests(1); // Tweak the end counter of the first nested call to be LESS than its start counter. let counter_start = builder.private_call.private_call_requests.get(0).start_side_effect_counter; - builder.private_call.private_call_requests.storage[0].end_side_effect_counter = counter_start - 1; + builder.private_call.private_call_requests.storage[0].end_side_effect_counter = + counter_start - 1; builder.validate(); } @@ -217,7 +223,8 @@ fn validate_counters_private_call_requests_equal_call_end_fails() { builder.private_call.append_private_call_requests(1); // Tweak the end counter of the nested call to EQUAL the end counter of the call. - builder.private_call.private_call_requests.storage[0].end_side_effect_counter = builder.private_call.counter; + builder.private_call.private_call_requests.storage[0].end_side_effect_counter = + builder.private_call.counter; builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr index b4d2ecbf1a2..306a637c819 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_call_data_validator_builder/validate_private_call_requests.nr @@ -13,8 +13,10 @@ impl PrivateCallDataValidatorBuilder { pub fn add_private_call_request(&mut self, counter_start: u32, counter_end: u32) { let index = self.private_call.private_call_requests.len(); self.private_call.append_private_call_requests(1); - self.private_call.private_call_requests.storage[index].start_side_effect_counter = counter_start; - self.private_call.private_call_requests.storage[index].end_side_effect_counter = counter_end; + self.private_call.private_call_requests.storage[index].start_side_effect_counter = + counter_start; + self.private_call.private_call_requests.storage[index].end_side_effect_counter = + counter_end; self.private_call.counter = counter_end + 1; } } @@ -43,7 +45,8 @@ fn validate_private_call_requests_incorrect_msg_sender_for_regular_call_fails() builder.private_call.append_private_call_requests(1); // Change the msg_sender to be the caller's msg_sender. - builder.private_call.private_call_requests.storage[0].call_context.msg_sender = builder.private_call.msg_sender; + builder.private_call.private_call_requests.storage[0].call_context.msg_sender = + builder.private_call.msg_sender; builder.validate(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr index d806bd4e0dc..f614d5ed1e4 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/mod.nr @@ -3,20 +3,17 @@ mod validate_initial_values; mod validate_propagated_from_previous_kernel; mod validate_propagated_from_private_call; -use crate::{ - components::{ +use crate::components::{ private_kernel_circuit_output_validator::PrivateKernelCircuitOutputValidator, - private_kernel_circuit_public_inputs_composer::create_first_nullifier -} + private_kernel_circuit_public_inputs_composer::create_first_nullifier, }; use dep::types::{ abis::{ - private_call_request::PrivateCallRequest, - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, - private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths -}, - tests::{fixture_builder::FixtureBuilder}, transaction::tx_request::TxRequest, - constants::PRIVATE_KERNEL_INIT_INDEX + private_call_request::PrivateCallRequest, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, + private_circuit_public_inputs::PrivateCircuitPublicInputsArrayLengths, + }, tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest, + constants::PRIVATE_KERNEL_INIT_INDEX, }; pub struct PrivateKernelCircuitOutputValidatorBuilder { @@ -37,7 +34,12 @@ impl PrivateKernelCircuitOutputValidatorBuilder { previous_kernel.nullifiers.push(first_nullifier); previous_kernel = previous_kernel.in_vk_tree(PRIVATE_KERNEL_INIT_INDEX); - PrivateKernelCircuitOutputValidatorBuilder { previous_kernel, private_call, output, tx_request } + PrivateKernelCircuitOutputValidatorBuilder { + previous_kernel, + private_call, + output, + tx_request, + } } pub fn with_previous_kernel_vk_index(&mut self, vk_index: u32) { @@ -61,7 +63,7 @@ impl PrivateKernelCircuitOutputValidatorBuilder { private_call.public_inputs, array_lengths, FixtureBuilder::vk_tree_root(), - self.private_call.protocol_contract_tree_root + self.private_call.protocol_contract_tree_root, ); } @@ -69,18 +71,21 @@ impl PrivateKernelCircuitOutputValidatorBuilder { let mut previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); // Append one private call request for the current call. let num_private_call_requests = self.previous_kernel.private_call_requests.len(); - previous_kernel.end.private_call_stack[num_private_call_requests] = PrivateCallRequest::empty(); + previous_kernel.end.private_call_stack[num_private_call_requests] = + PrivateCallRequest::empty(); previous_kernel.end.private_call_stack[num_private_call_requests].args_hash = 98765432; - let previous_kernel_array_lengths = PrivateKernelCircuitPublicInputsArrayLengths::new(previous_kernel); + let previous_kernel_array_lengths = + PrivateKernelCircuitPublicInputsArrayLengths::new(previous_kernel); let private_call = self.private_call.to_private_call_data(); - let private_call_array_lengths = PrivateCircuitPublicInputsArrayLengths::new(private_call.public_inputs); + let private_call_array_lengths = + PrivateCircuitPublicInputsArrayLengths::new(private_call.public_inputs); let output = self.output.to_private_kernel_circuit_public_inputs(); PrivateKernelCircuitOutputValidator::new(output).validate_as_inner_call( previous_kernel, previous_kernel_array_lengths, private_call.public_inputs, - private_call_array_lengths + private_call_array_lengths, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr index 275eea46eea..897267ba89f 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_output_validator_builder/validate_propagated_from_private_call.nr @@ -74,7 +74,8 @@ fn validate_propagated_from_private_call_note_hash_read_requests_output_extra_no builder.output.append_note_hash_read_requests(2); // Add a non-empty item to the end of the output. let len = builder.output.note_hash_read_requests.storage.len(); - builder.output.note_hash_read_requests.storage[len - 1] = builder.output.note_hash_read_requests.storage[0]; + builder.output.note_hash_read_requests.storage[len - 1] = + builder.output.note_hash_read_requests.storage[0]; builder.validate_as_inner_call(); } @@ -83,7 +84,10 @@ fn validate_propagated_from_private_call_note_hash_read_requests_output_extra_no * note_hash_read_requests * With previous kernel. */ -fn append_note_hash_read_requests_to_previous_kernel(builder: &mut PrivateKernelCircuitOutputValidatorBuilder, num_requests: u32) { +fn append_note_hash_read_requests_to_previous_kernel( + builder: &mut PrivateKernelCircuitOutputValidatorBuilder, + num_requests: u32, +) { builder.previous_kernel.append_note_hash_read_requests(num_requests); builder.output.append_note_hash_read_requests(num_requests); builder.offset_values(num_requests as Field); @@ -159,7 +163,8 @@ fn validate_propagated_from_private_call_note_hash_read_requests_with_previous_o builder.output.append_note_hash_read_requests(2); // Add a non-empty item to the end of the output. let len = builder.output.note_hash_read_requests.storage.len(); - builder.output.note_hash_read_requests.storage[len - 1] = builder.output.note_hash_read_requests.storage[0]; + builder.output.note_hash_read_requests.storage[len - 1] = + builder.output.note_hash_read_requests.storage[0]; builder.validate_as_inner_call(); } @@ -408,7 +413,8 @@ fn validate_propagated_from_private_call_private_call_requests_not_reversed_fail builder.output.append_private_call_requests(2); // Swap the call requests. let first_call_request = builder.output.private_call_requests.storage[0]; - builder.output.private_call_requests.storage[0] = builder.output.private_call_requests.storage[1]; + builder.output.private_call_requests.storage[0] = + builder.output.private_call_requests.storage[1]; builder.output.private_call_requests.storage[1] = first_call_request; builder.validate_as_inner_call(); @@ -421,7 +427,6 @@ fn validate_propagated_from_private_call_private_call_requests_with_previous_out builder.output.append_private_call_requests(5); let requests = builder.output.private_call_requests.storage; // The private_call_stack in the output will be: [requests[4], requests[3], requests[2], requests[1], requests[0]]. - // First 2 are propagated from the previous kernel. builder.previous_kernel.private_call_requests.push(requests[3]); builder.previous_kernel.private_call_requests.push(requests[4]); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr index 424f2eada3e..adc4b05947d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/mod.nr @@ -5,10 +5,9 @@ mod propagate_from_private_call; use crate::components::private_kernel_circuit_public_inputs_composer::PrivateKernelCircuitPublicInputsComposer; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - private_call_request::PrivateCallRequest -}, - tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + private_call_request::PrivateCallRequest, + }, tests::fixture_builder::FixtureBuilder, transaction::tx_request::TxRequest, }; pub struct PrivateKernelCircuitPublicInputsComposerBuilder { @@ -26,7 +25,11 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { private_call.value_offset = 9999; let tx_request = private_call.build_tx_request(); - PrivateKernelCircuitPublicInputsComposerBuilder { tx_request, previous_kernel, private_call } + PrivateKernelCircuitPublicInputsComposerBuilder { + tx_request, + previous_kernel, + private_call, + } } pub fn new_from_tx_request(self) -> PrivateKernelCircuitPublicInputsComposer { @@ -35,7 +38,7 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { self.tx_request, private_call, FixtureBuilder::vk_tree_root(), - self.private_call.protocol_contract_tree_root + self.private_call.protocol_contract_tree_root, ) } @@ -53,11 +56,15 @@ impl PrivateKernelCircuitPublicInputsComposerBuilder { // Append one private call request for the previous kernel. let mut previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); let num_private_call_requests = self.previous_kernel.private_call_requests.len(); - previous_kernel.end.private_call_stack[num_private_call_requests] = PrivateCallRequest::empty(); + previous_kernel.end.private_call_stack[num_private_call_requests] = + PrivateCallRequest::empty(); previous_kernel.end.private_call_stack[num_private_call_requests].args_hash = 98765432; let private_call = self.private_call.to_private_call_data(); - PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel).pop_top_call_request().with_private_call(private_call.public_inputs).finish() + PrivateKernelCircuitPublicInputsComposer::new_from_previous_kernel(previous_kernel) + .pop_top_call_request() + .with_private_call(private_call.public_inputs) + .finish() } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr index a82ee6b7f87..092cf5a2529 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_previous_kernel_with_private_call.nr @@ -1,7 +1,7 @@ -use crate::{tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder}; +use crate::tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder; use dep::types::{ - abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty, - tests::utils::assert_array_eq + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, + traits::is_empty, tests::utils::assert_array_eq, }; #[test] @@ -110,7 +110,7 @@ fn new_from_previous_kernel_with_private_call_note_hash_read_requests_succeeds() assert_array_eq( output.validation_requests.note_hash_read_requests, - [prev[0], prev[1], curr[0], curr[1]] + [prev[0], prev[1], curr[0], curr[1]], ); } @@ -127,7 +127,7 @@ fn new_from_previous_kernel_with_private_call_nullifier_read_requests_succeeds() assert_array_eq( output.validation_requests.nullifier_read_requests, - [prev[0], prev[1], curr[0], curr[1]] + [prev[0], prev[1], curr[0], curr[1]], ); } @@ -144,7 +144,7 @@ fn new_from_previous_kernel_with_private_call_key_validation_requests_succeeds() assert_array_eq( output.validation_requests.scoped_key_validation_requests_and_generators, - [prev[0], prev[1], curr[0], curr[1]] + [prev[0], prev[1], curr[0], curr[1]], ); } @@ -203,7 +203,7 @@ fn new_from_previous_kernel_with_private_call_note_encrypted_log_hashes_succeeds assert_array_eq( output.end.note_encrypted_logs_hashes, - [prev[0], prev[1], curr[0], curr[1]] + [prev[0], prev[1], curr[0], curr[1]], ); } @@ -220,7 +220,7 @@ fn new_from_previous_kernel_with_private_call_encrypted_log_hashes_succeeds() { assert_array_eq( output.end.encrypted_logs_hashes, - [prev[0], prev[1], curr[0], curr[1]] + [prev[0], prev[1], curr[0], curr[1]], ); } @@ -237,7 +237,7 @@ fn new_from_previous_kernel_with_private_call_unencrypted_log_hashes_succeeds() assert_array_eq( output.end.unencrypted_logs_hashes, - [prev[0], prev[1], curr[0], curr[1]] + [prev[0], prev[1], curr[0], curr[1]], ); } @@ -255,7 +255,7 @@ fn new_from_previous_kernel_with_private_call_private_call_requests_succeeds() { // Call requests from private call will be propagated in reversed order. assert_array_eq( output.end.private_call_stack, - [prev[1], prev[0], curr[1], curr[0]] + [prev[1], prev[0], curr[1], curr[0]], ); } @@ -272,7 +272,7 @@ fn new_from_previous_kernel_with_private_call_public_call_requests_succeeds() { assert_array_eq( output.end.public_call_requests, - [prev[0], prev[1], curr[0], curr[1]] + [prev[0], prev[1], curr[0], curr[1]], ); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr index 9fdca3bce25..16dcce34eae 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/new_from_tx_request.nr @@ -1,8 +1,11 @@ use crate::{ components::private_kernel_circuit_public_inputs_composer::create_first_nullifier, - tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder + tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder, +}; +use dep::types::{ + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, + traits::is_empty, }; -use dep::types::{abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty}; #[test] fn new_from_tx_request_succeeds() { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr index c84c936d5e3..75f70cad1ac 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/private_kernel_circuit_public_inputs_composer_builder/propagate_from_private_call.nr @@ -1,10 +1,10 @@ use crate::{ components::private_kernel_circuit_public_inputs_composer::create_first_nullifier, - tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder + tests::private_kernel_circuit_public_inputs_composer_builder::PrivateKernelCircuitPublicInputsComposerBuilder, }; use dep::types::{ - abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, traits::is_empty, - tests::utils::assert_array_eq + abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsArrayLengths, + traits::is_empty, tests::utils::assert_array_eq, }; #[test] @@ -63,7 +63,7 @@ fn propagate_from_private_call_note_hash_read_requests_succeeds() { assert_array_eq( output.validation_requests.note_hash_read_requests, - [res[0], res[1]] + [res[0], res[1]], ); } @@ -78,7 +78,7 @@ fn propagate_from_private_call_nullifier_read_requests_succeeds() { assert_array_eq( output.validation_requests.nullifier_read_requests, - [res[0], res[1]] + [res[0], res[1]], ); } @@ -93,7 +93,7 @@ fn propagate_from_private_call_key_validation_requests_succeeds() { assert_array_eq( output.validation_requests.scoped_key_validation_requests_and_generators, - [res[0], res[1]] + [res[0], res[1]], ); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/mod.nr index dc58d472d73..46fbe569a48 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/mod.nr @@ -2,16 +2,17 @@ mod validate_sorted_siloed_note_hashes; mod validate_sorted_siloed_nullifiers; use crate::components::{ - reset_output_composer::{reset_output_hints::{generate_reset_output_hints, ResetOutputHints}}, - reset_output_validator::ResetOutputValidator + reset_output_composer::reset_output_hints::{generate_reset_output_hints, ResetOutputHints}, + reset_output_validator::ResetOutputValidator, }; use dep::reset_kernel_lib::{ KeyValidationHint, PrivateValidationRequestProcessor, - tests::{NoteHashReadRequestHintsBuilder, NullifierReadRequestHintsBuilder}, TransientDataIndexHint + tests::{NoteHashReadRequestHintsBuilder, NullifierReadRequestHintsBuilder}, + TransientDataIndexHint, }; use dep::types::{ constants::{MAX_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX}, - tests::fixture_builder::FixtureBuilder + tests::fixture_builder::FixtureBuilder, }; pub struct ResetOutputValidatorBuilder { @@ -38,7 +39,8 @@ impl ResetOutputValidatorBuilder { let note_hash_read_request_hints_builder = NoteHashReadRequestHintsBuilder::new(); let nullifier_read_request_hints_builder = NullifierReadRequestHintsBuilder::new(); let key_validation_hints = [KeyValidationHint::nada(MAX_KEY_VALIDATION_REQUESTS_PER_TX); 2]; - let transient_data_index_hints = [TransientDataIndexHint::nada(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX); 5]; + let transient_data_index_hints = + [TransientDataIndexHint::nada(MAX_NULLIFIERS_PER_TX, MAX_NOTE_HASHES_PER_TX); 5]; ResetOutputValidatorBuilder { output, @@ -49,18 +51,18 @@ impl ResetOutputValidatorBuilder { transient_data_index_hints, note_hash_siloing_amount: 0, nullifier_siloing_amount: 0, - encrypted_log_siloing_amount: 0 + encrypted_log_siloing_amount: 0, } } - pub fn get_validation_request_processor(self) -> PrivateValidationRequestProcessor<6, 3, 5, 2, 2> { + pub fn get_validation_request_processor( + self, + ) -> PrivateValidationRequestProcessor<6, 3, 5, 2, 2> { let previous_kernel = self.previous_kernel.to_private_kernel_circuit_public_inputs(); - let note_hash_read_request_hints = unsafe { - self.note_hash_read_request_hints_builder.to_hints() - }; - let nullifier_read_request_hints = unsafe { - self.nullifier_read_request_hints_builder.to_hints() - }; + let note_hash_read_request_hints = + unsafe { self.note_hash_read_request_hints_builder.to_hints() }; + let nullifier_read_request_hints = + unsafe { self.nullifier_read_request_hints_builder.to_hints() }; PrivateValidationRequestProcessor { validation_requests: previous_kernel.validation_requests, @@ -71,7 +73,7 @@ impl ResetOutputValidatorBuilder { pending_nullifiers: previous_kernel.end.nullifiers, nullifier_tree_root: 0, key_validation_hints: self.key_validation_hints, - validation_requests_split_counter: previous_kernel.min_revertible_side_effect_counter + validation_requests_split_counter: previous_kernel.min_revertible_side_effect_counter, } } @@ -94,8 +96,9 @@ impl ResetOutputValidatorBuilder { self.note_hash_siloing_amount, self.nullifier_siloing_amount, self.encrypted_log_siloing_amount, - hints - ).validate(); + hints, + ) + .validate(); } pub fn validate(self) { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_note_hashes.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_note_hashes.nr index 11ce9f3f70c..efdc0380020 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_note_hashes.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_note_hashes.nr @@ -40,7 +40,8 @@ fn validate_sorted_siloed_note_hashes_mismatch_sorted_hash_fails() { builder.output.append_siloed_note_hashes(2); // Swap the hashes in the output. let tmp = builder.output.note_hashes.storage[0].note_hash.value; - builder.output.note_hashes.storage[0].note_hash.value = builder.output.note_hashes.storage[1].note_hash.value; + builder.output.note_hashes.storage[0].note_hash.value = + builder.output.note_hashes.storage[1].note_hash.value; builder.output.note_hashes.storage[1].note_hash.value = tmp; builder.validate(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_nullifiers.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_nullifiers.nr index e7f41c8f1df..5535dc2bcc7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_nullifiers.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/reset_output_validator_builder/validate_sorted_siloed_nullifiers.nr @@ -53,7 +53,8 @@ fn validate_sorted_siloed_nullifiers_mismatch_sorted_hash_fails() { builder.output.append_siloed_nullifiers(3); // Swap the hashes in the output. let tmp = builder.output.nullifiers.storage[0].nullifier.value; - builder.output.nullifiers.storage[0].nullifier.value = builder.output.nullifiers.storage[1].nullifier.value; + builder.output.nullifiers.storage[0].nullifier.value = + builder.output.nullifiers.storage[1].nullifier.value; builder.output.nullifiers.storage[1].nullifier.value = tmp; builder.validate(); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/meter_gas_used.nr index 4450cb2cd2f..ff5644f9c26 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/meter_gas_used.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/meter_gas_used.nr @@ -1,8 +1,10 @@ use crate::components::tail_output_composer::meter_gas_used::meter_gas_used; use dep::types::{ abis::gas::Gas, - constants::{DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE}, - tests::fixture_builder::FixtureBuilder + constants::{ + DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, L2_GAS_PER_NOTE_HASH, L2_GAS_PER_NULLIFIER, + L2_GAS_PER_LOG_BYTE, + }, tests::fixture_builder::FixtureBuilder, }; fn new_builder() -> FixtureBuilder { @@ -66,8 +68,9 @@ fn meter_gas_used_everything_succeeds() { let gas = meter_gas_used(data, gas_settings); assert_eq( - gas, Gas::new(metered_da_bytes * DA_GAS_PER_BYTE, computed_l2_gas) - + Gas::tx_overhead() - + gas_settings.teardown_gas_limits + gas, + Gas::new(metered_da_bytes * DA_GAS_PER_BYTE, computed_l2_gas) + + Gas::tx_overhead() + + gas_settings.teardown_gas_limits, ); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/mod.nr index 0e82c914a67..3f9b6ef8043 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_composer_builder/mod.nr @@ -1,7 +1,10 @@ mod meter_gas_used; use crate::components::tail_output_composer::TailOutputComposer; -use dep::types::{abis::kernel_circuit_public_inputs::KernelCircuitPublicInputs, tests::fixture_builder::FixtureBuilder}; +use dep::types::{ + abis::kernel_circuit_public_inputs::KernelCircuitPublicInputs, + tests::fixture_builder::FixtureBuilder, +}; pub struct TailOutputComposerBuilder { previous_kernel: FixtureBuilder, diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr index 98f146d5288..e3a784e5081 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/mod.nr @@ -5,11 +5,13 @@ mod validate_propagated_values; use crate::components::{ tail_output_composer::meter_gas_used::meter_gas_used, - tail_output_validator::{tail_output_hints::{generate_tail_output_hints, TailOutputHints}, TailOutputValidator} + tail_output_validator::{ + tail_output_hints::{generate_tail_output_hints, TailOutputHints}, TailOutputValidator, + }, }; use dep::types::{ abis::{gas_settings::GasSettings, kernel_circuit_public_inputs::KernelCircuitPublicInputs}, - tests::fixture_builder::FixtureBuilder + tests::fixture_builder::FixtureBuilder, }; pub struct TailOutputValidatorBuilder { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/validate_propagated_values.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/validate_propagated_values.nr index edce9cb4745..7a4d23a0941 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/validate_propagated_values.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_output_validator_builder/validate_propagated_values.nr @@ -182,7 +182,8 @@ fn validate_propagated_values_note_encrypted_log_hashes_non_zero_counter_fails() let mut output = builder.export_output(); // Set the counter at index 1. - output.end.note_encrypted_logs_hashes[1].counter = builder.previous_kernel.note_encrypted_logs_hashes.storage[1].counter; + output.end.note_encrypted_logs_hashes[1].counter = + builder.previous_kernel.note_encrypted_logs_hashes.storage[1].counter; builder.validate_with_output(output); } @@ -222,7 +223,8 @@ fn validate_propagated_values_encrypted_logs_hashes_non_zero_counter_fails() { let mut output = builder.export_output(); // Set the counter at index 1. - output.end.encrypted_logs_hashes[1].log_hash.counter = builder.previous_kernel.encrypted_logs_hashes.storage[1].log_hash.counter; + output.end.encrypted_logs_hashes[1].log_hash.counter = + builder.previous_kernel.encrypted_logs_hashes.storage[1].log_hash.counter; builder.validate_with_output(output); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr index 8dec06d95c7..2c6fb1d2e23 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/meter_gas_used.nr @@ -1,11 +1,12 @@ -use crate::components::tail_to_public_output_composer::meter_gas_used::{meter_gas_used_non_revertible, meter_gas_used_revertible}; +use crate::components::tail_to_public_output_composer::meter_gas_used::{ + meter_gas_used_non_revertible, meter_gas_used_revertible, +}; use dep::types::{ abis::gas::Gas, constants::{ - DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, FIXED_AVM_STARTUP_L2_GAS, L2_GAS_PER_NOTE_HASH, - L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE -}, - tests::fixture_builder::FixtureBuilder + DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, FIXED_AVM_STARTUP_L2_GAS, L2_GAS_PER_NOTE_HASH, + L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE, + }, tests::fixture_builder::FixtureBuilder, }; #[test] @@ -36,10 +37,14 @@ fn meter_gas_used_non_revertible_everything_succeeds() { let gas = meter_gas_used_non_revertible(data); let total_num_side_effects = 4 + 3 + 1; - let total_log_length = 12 + 8 + 20 // note_encrypted_log_hash - + 2 + 6 // encrypted_log_hash + let total_log_length = 12 + + 8 + + 20 // note_encrypted_log_hash + + 2 + + 6 // encrypted_log_hash + 51; // unencrypted_log_hash - let computed_da_gas = (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; + let computed_da_gas = + (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; let computed_l2_gas = 4 * L2_GAS_PER_NOTE_HASH + 3 * L2_GAS_PER_NULLIFIER + total_log_length * L2_GAS_PER_LOG_BYTE @@ -78,10 +83,14 @@ fn meter_gas_used_revertible_everything_succeeds() { let gas = meter_gas_used_revertible(data, teardown_gas); let total_num_side_effects = 4 + 3 + 1; - let total_log_length = 12 + 8 + 20 // note_encrypted_log_hash - + 2 + 6 // encrypted_log_hash + let total_log_length = 12 + + 8 + + 20 // note_encrypted_log_hash + + 2 + + 6 // encrypted_log_hash + 51; // unencrypted_log_hash - let computed_da_gas = (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; + let computed_da_gas = + (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; let computed_l2_gas = 4 * L2_GAS_PER_NOTE_HASH + 3 * L2_GAS_PER_NULLIFIER + total_log_length * L2_GAS_PER_LOG_BYTE diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/mod.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/mod.nr index db217294f16..c7daddc987e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/mod.nr @@ -5,7 +5,7 @@ mod tail_to_public_output_composer; use crate::components::tail_to_public_output_composer::TailToPublicOutputComposer; use dep::types::{ abis::kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, - tests::fixture_builder::FixtureBuilder + tests::fixture_builder::FixtureBuilder, }; pub struct TailToPublicOutputComposerBuilder { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr index 67b368e0dee..f81f0ef541e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/split_to_public.nr @@ -27,7 +27,7 @@ fn split_to_public_succeeds() { let (non_revertible, revertible) = unsafe { split_to_public( builder.to_private_accumulated_data_builder(), - builder.min_revertible_side_effect_counter + builder.min_revertible_side_effect_counter, ) }; @@ -36,7 +36,7 @@ fn split_to_public_succeeds() { assert_array_eq(non_revertible.note_hashes, [expected[0], expected[1]]); assert_array_eq( revertible.note_hashes, - [expected[2], expected[3], expected[4]] + [expected[2], expected[3], expected[4]], ); // nullifiers @@ -53,7 +53,7 @@ fn split_to_public_succeeds() { let expected = combined_data.note_encrypted_logs_hashes; assert_array_eq( non_revertible.note_encrypted_logs_hashes, - [expected[0], expected[1], expected[2]] + [expected[0], expected[1], expected[2]], ); assert_array_eq(revertible.note_encrypted_logs_hashes, [expected[3]]); @@ -61,7 +61,7 @@ fn split_to_public_succeeds() { let expected = combined_data.encrypted_logs_hashes; assert_array_eq( non_revertible.encrypted_logs_hashes, - [expected[0], expected[1]] + [expected[0], expected[1]], ); assert_array_eq(revertible.encrypted_logs_hashes, [expected[2], expected[3]]); diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/tail_to_public_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/tail_to_public_output_composer.nr index 7cc20511d4a..ba858cbe75d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/tail_to_public_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_composer_builder/tail_to_public_output_composer.nr @@ -2,10 +2,9 @@ use crate::tests::tail_to_public_output_composer_builder::TailToPublicOutputComp use dep::types::{ abis::gas::Gas, constants::{ - DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, FIXED_AVM_STARTUP_L2_GAS, L2_GAS_PER_NOTE_HASH, - L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE -}, - tests::utils::{assert_array_eq, swap_items} + DA_BYTES_PER_FIELD, DA_GAS_PER_BYTE, FIXED_AVM_STARTUP_L2_GAS, L2_GAS_PER_NOTE_HASH, + L2_GAS_PER_NULLIFIER, L2_GAS_PER_LOG_BYTE, + }, tests::utils::{assert_array_eq, swap_items}, }; #[test] @@ -65,7 +64,7 @@ fn tail_to_public_output_composer_succeeds() { let note_hashes = data.note_hashes; assert_array_eq( output.end_non_revertible.note_hashes, - [note_hashes[0], note_hashes[1], note_hashes[2], note_hashes[3]] + [note_hashes[0], note_hashes[1], note_hashes[2], note_hashes[3]], ); assert_array_eq(output.end.note_hashes, [note_hashes[4], note_hashes[5]]); @@ -73,7 +72,7 @@ fn tail_to_public_output_composer_succeeds() { let nullifiers = data.nullifiers; assert_array_eq( output.end_non_revertible.nullifiers, - [nullifiers[0], nullifiers[1], nullifiers[2]] + [nullifiers[0], nullifiers[1], nullifiers[2]], ); assert_array_eq(output.end.nullifiers, [nullifiers[3]]); @@ -86,7 +85,7 @@ fn tail_to_public_output_composer_succeeds() { let log_hashes = data.note_encrypted_logs_hashes; assert_array_eq( output.end_non_revertible.note_encrypted_logs_hashes, - [log_hashes[0], log_hashes[1]] + [log_hashes[0], log_hashes[1]], ); assert_array_eq(output.end.note_encrypted_logs_hashes, [log_hashes[2]]); @@ -94,18 +93,18 @@ fn tail_to_public_output_composer_succeeds() { let log_hashes = data.encrypted_logs_hashes; assert_array_eq( output.end_non_revertible.encrypted_logs_hashes, - [log_hashes[0]] + [log_hashes[0]], ); assert_array_eq( output.end.encrypted_logs_hashes, - [log_hashes[1], log_hashes[2]] + [log_hashes[1], log_hashes[2]], ); // unencrypted_logs_hashes let log_hashes = data.unencrypted_logs_hashes; assert_array_eq( output.end_non_revertible.unencrypted_logs_hashes, - [log_hashes[0], log_hashes[1]] + [log_hashes[0], log_hashes[1]], ); assert_array_eq(output.end.unencrypted_logs_hashes, [log_hashes[2]]); @@ -113,33 +112,39 @@ fn tail_to_public_output_composer_succeeds() { let call_requests = data.public_call_stack; assert_array_eq( output.end_non_revertible.public_call_stack, - [call_requests[1], call_requests[0]] + [call_requests[1], call_requests[0]], ); assert_array_eq( output.end.public_call_stack, - [call_requests[4], call_requests[3], call_requests[2]] + [call_requests[4], call_requests[3], call_requests[2]], ); // Gas: non-revertible let total_num_side_effects = 4 + 3 + 1; - let total_log_length = 12 + 8 // note_encrypted_log_hash + let total_log_length = 12 + + 8 // note_encrypted_log_hash + 2 // encrypted_log_hash - + 51 + 9; // unencrypted_log_hash - let computed_da_gas = (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; + + 51 + + 9; // unencrypted_log_hash + let computed_da_gas = + (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; let computed_l2_gas = 4 * L2_GAS_PER_NOTE_HASH + 3 * L2_GAS_PER_NULLIFIER + total_log_length * L2_GAS_PER_LOG_BYTE + 2 * FIXED_AVM_STARTUP_L2_GAS; assert_eq( - output.end_non_revertible.gas_used, Gas::new(computed_da_gas, computed_l2_gas) + Gas::tx_overhead() + output.end_non_revertible.gas_used, + Gas::new(computed_da_gas, computed_l2_gas) + Gas::tx_overhead(), ); // Gas: revertible let total_num_side_effects = 2 + 1 + 1; let total_log_length = 20 // note_encrypted_log_hash - + 6 + 24 // encrypted_log_hash + + 6 + + 24 // encrypted_log_hash + 4; // unencrypted_log_hash - let computed_da_gas = (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; + let computed_da_gas = + (total_num_side_effects * DA_BYTES_PER_FIELD + total_log_length) * DA_GAS_PER_BYTE; let computed_l2_gas = 2 * L2_GAS_PER_NOTE_HASH + 1 * L2_GAS_PER_NULLIFIER + total_log_length * L2_GAS_PER_LOG_BYTE diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_validator_builder.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_validator_builder.nr index d1a6a03b034..45280bf52b7 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_validator_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/tests/tail_to_public_output_validator_builder.nr @@ -1,9 +1,9 @@ -use crate::components::{tail_to_public_output_validator::TailToPublicOutputValidator}; +use crate::components::tail_to_public_output_validator::TailToPublicOutputValidator; use dep::types::tests::fixture_builder::FixtureBuilder; pub struct TailToPublicOutputValidatorBuilder { output: FixtureBuilder, - previous_kernel: FixtureBuilder + previous_kernel: FixtureBuilder, } impl TailToPublicOutputValidatorBuilder { diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset-simulated/src/main.nr index 3df55379852..7884b49de77 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset-simulated/src/main.nr @@ -1,10 +1,13 @@ -use dep::private_kernel_lib::private_kernel_reset::{PrivateKernelResetHints, PrivateKernelResetCircuitPrivateInputs}; +use dep::private_kernel_lib::private_kernel_reset::{ + PrivateKernelResetHints, PrivateKernelResetCircuitPrivateInputs, +}; use dep::types::{ PrivateKernelCircuitPublicInputs, constants::{ - MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_KEY_VALIDATION_REQUESTS_PER_TX -} + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, + MAX_KEY_VALIDATION_REQUESTS_PER_TX, + }, }; use types::abis::private_kernel_data::PrivateKernelDataWithoutPublicInputs; @@ -21,13 +24,17 @@ global ENCRYPTED_LOG_SILOING_AMOUNT = MAX_ENCRYPTED_LOGS_PER_TX; // 8 unconstrained fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, - hints: PrivateKernelResetHints + hints: PrivateKernelResetHints, ) -> pub PrivateKernelCircuitPublicInputs { - let private_inputs = PrivateKernelResetCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs, hints); + let private_inputs = PrivateKernelResetCircuitPrivateInputs::new( + previous_kernel, + previous_kernel_public_inputs, + hints, + ); private_inputs.execute( NOTE_HASH_SILOING_AMOUNT, NULLIFIER_SILOING_AMOUNT, - ENCRYPTED_LOG_SILOING_AMOUNT + ENCRYPTED_LOG_SILOING_AMOUNT, ) } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/src/main.nr index c898f14e10c..dc6185015d9 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-reset/src/main.nr @@ -1,10 +1,13 @@ -use dep::private_kernel_lib::private_kernel_reset::{PrivateKernelResetHints, PrivateKernelResetCircuitPrivateInputs}; +use dep::private_kernel_lib::private_kernel_reset::{ + PrivateKernelResetHints, PrivateKernelResetCircuitPrivateInputs, +}; use dep::types::{ PrivateKernelCircuitPublicInputs, constants::{ - MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_KEY_VALIDATION_REQUESTS_PER_TX -} + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, + MAX_KEY_VALIDATION_REQUESTS_PER_TX, + }, }; use types::abis::private_kernel_data::PrivateKernelDataWithoutPublicInputs; @@ -21,13 +24,17 @@ global ENCRYPTED_LOG_SILOING_AMOUNT = MAX_ENCRYPTED_LOGS_PER_TX; // 8 fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, previous_kernel_public_inputs: call_data(0) PrivateKernelCircuitPublicInputs, - hints: PrivateKernelResetHints + hints: PrivateKernelResetHints, ) -> return_data PrivateKernelCircuitPublicInputs { - let private_inputs = PrivateKernelResetCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs, hints); + let private_inputs = PrivateKernelResetCircuitPrivateInputs::new( + previous_kernel, + previous_kernel_public_inputs, + hints, + ); private_inputs.execute( NOTE_HASH_SILOING_AMOUNT, NULLIFIER_SILOING_AMOUNT, - ENCRYPTED_LOG_SILOING_AMOUNT + ENCRYPTED_LOG_SILOING_AMOUNT, ) } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr index 2d9ebe6ea0e..fa99dc2bea4 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr @@ -5,8 +5,9 @@ use types::abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs; unconstrained fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, - previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs + previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, ) -> pub KernelCircuitPublicInputs { - let private_inputs = PrivateKernelTailCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs); + let private_inputs = + PrivateKernelTailCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr index 6716b11f017..dbbc22e0df6 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr @@ -5,8 +5,11 @@ use types::abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs; unconstrained fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, - previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs + previous_kernel_public_inputs: PrivateKernelCircuitPublicInputs, ) -> pub PublicKernelCircuitPublicInputs { - let private_inputs = PrivateKernelTailToPublicCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs); + let private_inputs = PrivateKernelTailToPublicCircuitPrivateInputs::new( + previous_kernel, + previous_kernel_public_inputs, + ); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr index 57bf8c74c43..ea2bd39412e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr @@ -5,8 +5,11 @@ use types::abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs; fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, - previous_kernel_public_inputs: call_data(0) PrivateKernelCircuitPublicInputs + previous_kernel_public_inputs: call_data(0) PrivateKernelCircuitPublicInputs, ) -> pub PublicKernelCircuitPublicInputs { - let private_inputs = PrivateKernelTailToPublicCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs); + let private_inputs = PrivateKernelTailToPublicCircuitPrivateInputs::new( + previous_kernel, + previous_kernel_public_inputs, + ); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr index 8383ed5c782..675e7f082a6 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr @@ -5,8 +5,9 @@ use types::abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs; fn main( previous_kernel: PrivateKernelDataWithoutPublicInputs, - previous_kernel_public_inputs: call_data(0) PrivateKernelCircuitPublicInputs + previous_kernel_public_inputs: call_data(0) PrivateKernelCircuitPublicInputs, ) -> pub KernelCircuitPublicInputs { - let private_inputs = PrivateKernelTailCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs); + let private_inputs = + PrivateKernelTailCircuitPrivateInputs::new(previous_kernel, previous_kernel_public_inputs); private_inputs.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/enqueued_call_data_validator.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/enqueued_call_data_validator.nr index a66ea0e5169..13f96c95651 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/enqueued_call_data_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/enqueued_call_data_validator.nr @@ -1,11 +1,11 @@ use crate::public_kernel_phase::PublicKernelPhase; use dep::types::{ abis::{ - accumulated_data::PublicAccumulatedDataArrayLengths, - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, enqueued_call_data::EnqueuedCallData, - public_call_request::PublicCallRequest, validation_requests::PublicValidationRequestArrayLengths -}, - constants::MAX_L2_GAS_PER_ENQUEUED_CALL, utils::arrays::array_length + accumulated_data::PublicAccumulatedDataArrayLengths, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + enqueued_call_data::EnqueuedCallData, public_call_request::PublicCallRequest, + validation_requests::PublicValidationRequestArrayLengths, + }, constants::MAX_L2_GAS_PER_ENQUEUED_CALL, utils::arrays::array_length, }; pub struct EnqueuedCallDataValidator { @@ -31,7 +31,7 @@ impl EnqueuedCallDataValidator { previous_kernel: PublicKernelCircuitPublicInputs, previous_validation_request_array_lengths: PublicValidationRequestArrayLengths, previous_non_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths, - previous_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths + previous_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths, ) { self.validate_global_variables(previous_kernel); self.validate_against_call_request(previous_kernel); @@ -41,7 +41,7 @@ impl EnqueuedCallDataValidator { self.validate_array_lengths( previous_validation_request_array_lengths, previous_non_revertible_data_array_lengths, - previous_revertible_data_array_lengths + previous_revertible_data_array_lengths, ); } @@ -53,10 +53,13 @@ impl EnqueuedCallDataValidator { fn validate_global_variables(self, previous_kernel: PublicKernelCircuitPublicInputs) { let prev_global_variables = previous_kernel.constants.global_variables; - if !prev_global_variables.is_empty() { // It's empty when the previous kernel is from private_kernel_tail_to_pubic. + if !prev_global_variables.is_empty() { + // It's empty when the previous kernel is from private_kernel_tail_to_pubic. let enqueued_call_globals = self.enqueued_call.data.constants.global_variables; assert_eq( - enqueued_call_globals, prev_global_variables, "Global variables injected into the public call do not match constants" + enqueued_call_globals, + prev_global_variables, + "Global variables injected into the public call do not match constants", ); } } @@ -76,13 +79,16 @@ impl EnqueuedCallDataValidator { }; assert( - self.enqueued_call.data.call_request == call_request, "enqueued call does not match item at the top of the call stack" + self.enqueued_call.data.call_request == call_request, + "enqueued call does not match item at the top of the call stack", ); } fn validate_counters(self, previous_kernel: PublicKernelCircuitPublicInputs) { assert_eq( - self.enqueued_call.data.start_side_effect_counter, previous_kernel.end_side_effect_counter + 1, "enqueued call must start from the end counter of the previous call" + self.enqueued_call.data.start_side_effect_counter, + previous_kernel.end_side_effect_counter + 1, + "enqueued call must start from the end counter of the previous call", ); } @@ -94,18 +100,27 @@ impl EnqueuedCallDataValidator { if self.phase != PublicKernelPhase.TEARDOWN { // An enqueued call's start gas is the remaining gas left in the transaction after the previous kernel. let tx_gas_limits = previous_kernel.constants.tx_context.gas_settings.gas_limits; - let mut computed_start_gas = tx_gas_limits.sub(previous_kernel.end.gas_used).sub(previous_kernel.end_non_revertible.gas_used); + let mut computed_start_gas = tx_gas_limits.sub(previous_kernel.end.gas_used).sub( + previous_kernel.end_non_revertible.gas_used, + ); // Keep L2 gas below max - computed_start_gas.l2_gas = std::cmp::min(computed_start_gas.l2_gas, MAX_L2_GAS_PER_ENQUEUED_CALL); + computed_start_gas.l2_gas = + std::cmp::min(computed_start_gas.l2_gas, MAX_L2_GAS_PER_ENQUEUED_CALL); assert_eq( - enqueued_call_start_gas, computed_start_gas, "Start gas for enqueued call does not match transaction gas left (with MAX_L2_GAS_PER_ENQUEUED_CALL applied)" + enqueued_call_start_gas, + computed_start_gas, + "Start gas for enqueued call does not match transaction gas left (with MAX_L2_GAS_PER_ENQUEUED_CALL applied)", ); } else { - let mut teardown_gas_limit = previous_kernel.constants.tx_context.gas_settings.teardown_gas_limits; + let mut teardown_gas_limit = + previous_kernel.constants.tx_context.gas_settings.teardown_gas_limits; // Keep L2 gas below max - teardown_gas_limit.l2_gas = std::cmp::min(teardown_gas_limit.l2_gas, MAX_L2_GAS_PER_ENQUEUED_CALL); + teardown_gas_limit.l2_gas = + std::cmp::min(teardown_gas_limit.l2_gas, MAX_L2_GAS_PER_ENQUEUED_CALL); assert_eq( - enqueued_call_start_gas, teardown_gas_limit, "Start gas for enqueued call does not match teardown gas allocation (with MAX_L2_GAS_PER_ENQUEUED_CALL applied)" + enqueued_call_start_gas, + teardown_gas_limit, + "Start gas for enqueued call does not match teardown gas allocation (with MAX_L2_GAS_PER_ENQUEUED_CALL applied)", ); } } @@ -116,12 +131,15 @@ impl EnqueuedCallDataValidator { assert_eq(transaction_fee, 0, "Transaction fee must be zero on setup and app phases"); } else { // Note that teardown_gas is already included in end.gas_used as it was injected by the private kernel - let total_gas_used = previous_kernel.end.gas_used + previous_kernel.end_non_revertible.gas_used; + let total_gas_used = + previous_kernel.end.gas_used + previous_kernel.end_non_revertible.gas_used; let block_gas_fees = self.enqueued_call.data.constants.global_variables.gas_fees; let inclusion_fee = previous_kernel.constants.tx_context.gas_settings.inclusion_fee; - let computed_transaction_fee = total_gas_used.compute_fee(block_gas_fees) + inclusion_fee; + let computed_transaction_fee = + total_gas_used.compute_fee(block_gas_fees) + inclusion_fee; assert( - transaction_fee == computed_transaction_fee, "Transaction fee on teardown phase does not match expected value" + transaction_fee == computed_transaction_fee, + "Transaction fee on teardown phase does not match expected value", ); } } @@ -130,10 +148,12 @@ impl EnqueuedCallDataValidator { self, previous_validation_request_array_lengths: PublicValidationRequestArrayLengths, previous_non_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths, - previous_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths + previous_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths, ) { assert_eq( - self.enqueued_call.data.previous_validation_request_array_lengths, previous_validation_request_array_lengths, "mismatch previous_validation_request_array_lengths" + self.enqueued_call.data.previous_validation_request_array_lengths, + previous_validation_request_array_lengths, + "mismatch previous_validation_request_array_lengths", ); let prev_lengths = if self.phase == PublicKernelPhase.SETUP { previous_non_revertible_data_array_lengths @@ -141,7 +161,9 @@ impl EnqueuedCallDataValidator { previous_revertible_data_array_lengths }; assert_eq( - self.enqueued_call.data.previous_accumulated_data_array_lengths, prev_lengths, "mismatch previoius_accumulated_data_array_lengths" + self.enqueued_call.data.previous_accumulated_data_array_lengths, + prev_lengths, + "mismatch previoius_accumulated_data_array_lengths", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr index 3e8725df2e1..4d3bf25508f 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/previous_kernel_validator.nr @@ -21,33 +21,48 @@ impl PreviousKernelValidator { pub fn validate_phase(self, phase: u8) { let public_inputs = self.previous_kernel.public_inputs; - let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0].call_context.contract_address.is_zero(); + let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0] + .call_context + .contract_address + .is_zero(); if phase == PublicKernelPhase.SETUP { assert_eq(needs_setup, true, "Cannot run unnecessary setup circuit"); } - let needs_app_logic = !public_inputs.end.public_call_stack[0].call_context.contract_address.is_zero(); + let needs_app_logic = + !public_inputs.end.public_call_stack[0].call_context.contract_address.is_zero(); if phase == PublicKernelPhase.APP_LOGIC { assert_eq(needs_setup, false, "Cannot run app logic circuit before setup circuit"); assert_eq(needs_app_logic, true, "Cannot run unnecessary app logic circuit"); } - let needs_teardown = !public_inputs.public_teardown_call_request.call_context.contract_address.is_zero(); + let needs_teardown = + !public_inputs.public_teardown_call_request.call_context.contract_address.is_zero(); if phase == PublicKernelPhase.TEARDOWN { assert_eq(needs_setup, false, "Cannot run teardown circuit before setup circuit"); - assert_eq(needs_app_logic, false, "Cannot run teardown circuit before app logic circuit"); + assert_eq( + needs_app_logic, + false, + "Cannot run teardown circuit before app logic circuit", + ); assert_eq(needs_teardown, true, "Cannot run unnecessary teardown circuit"); } if phase == PublicKernelPhase.TAIL { assert_eq( - needs_setup, false, "Revertible call stack must be empty when executing the tail circuit" + needs_setup, + false, + "Revertible call stack must be empty when executing the tail circuit", ); assert_eq( - needs_app_logic, false, "Non-revertible call stack must be empty when executing the tail circuit" + needs_app_logic, + false, + "Non-revertible call stack must be empty when executing the tail circuit", ); assert_eq( - needs_teardown, false, "Teardown call stack must be empty when executing the tail circuit" + needs_teardown, + false, + "Teardown call stack must be empty when executing the tail circuit", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer.nr index 7f9964cacd2..e073a9d9bc5 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer.nr @@ -2,15 +2,16 @@ mod propagate_accumulated_data; use crate::{ components::public_kernel_output_composer::propagate_accumulated_data::propagate_accumulated_data, - public_kernel_phase::PublicKernelPhase + public_kernel_phase::PublicKernelPhase, }; use dep::types::{ abis::{ - accumulated_data::PublicAccumulatedDataBuilder, - kernel_circuit_public_inputs::{PublicKernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder, VMCircuitPublicInputs}, - public_call_request::PublicCallRequest -}, - traits::is_empty + accumulated_data::PublicAccumulatedDataBuilder, + kernel_circuit_public_inputs::{ + PublicKernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder, + VMCircuitPublicInputs, + }, public_call_request::PublicCallRequest, + }, traits::is_empty, }; pub struct PublicKernelOutputComposer { @@ -36,7 +37,11 @@ impl PublicKernelOutputComposer { *self } - pub fn propagate_from_enqueued_call(&mut self, enqueued_call: VMCircuitPublicInputs, phase: u8) -> Self { + pub fn propagate_from_enqueued_call( + &mut self, + enqueued_call: VMCircuitPublicInputs, + phase: u8, + ) -> Self { self.output_builder.constants.global_variables = enqueued_call.constants.global_variables; self.propagate_revert_code(enqueued_call, phase); self.propagate_validation_requests(enqueued_call); @@ -75,7 +80,6 @@ impl PublicKernelOutputComposer { fn propagate_validation_requests(&mut self, enqueued_call: VMCircuitPublicInputs) { let data = enqueued_call.validation_requests; // Note that the public kernel cannot modify the max block number value - it simply forwards it to the rollup - let note_hash_read_requests = data.note_hash_read_requests; for i in 0..note_hash_read_requests.len() { let request = note_hash_read_requests[i]; @@ -96,7 +100,9 @@ impl PublicKernelOutputComposer { for i in 0..nullifier_non_existent_read_requests.len() { let request = nullifier_non_existent_read_requests[i]; if !is_empty(request) { - self.output_builder.validation_requests.nullifier_non_existent_read_requests.push(request); + self.output_builder.validation_requests.nullifier_non_existent_read_requests.push( + request, + ); } } @@ -119,10 +125,16 @@ impl PublicKernelOutputComposer { fn propagate_accumulated_data(&mut self, enqueued_call: VMCircuitPublicInputs, phase: u8) { if phase == PublicKernelPhase.SETUP { - self.output_builder.end_non_revertible = propagate_accumulated_data(&mut self.output_builder.end_non_revertible, enqueued_call.accumulated_data); + self.output_builder.end_non_revertible = propagate_accumulated_data( + &mut self.output_builder.end_non_revertible, + enqueued_call.accumulated_data, + ); } if (phase == PublicKernelPhase.APP_LOGIC) | (phase == PublicKernelPhase.TEARDOWN) { - self.output_builder.end = propagate_accumulated_data(&mut self.output_builder.end, enqueued_call.accumulated_data); + self.output_builder.end = propagate_accumulated_data( + &mut self.output_builder.end, + enqueued_call.accumulated_data, + ); } // TODO: Should keep the data even when reverts. diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer/propagate_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer/propagate_accumulated_data.nr index 8b024825d8b..2024caf0444 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer/propagate_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_composer/propagate_accumulated_data.nr @@ -1,8 +1,8 @@ -use dep::types::{abis::{accumulated_data::{PublicAccumulatedData, PublicAccumulatedDataBuilder}}}; +use dep::types::abis::accumulated_data::{PublicAccumulatedData, PublicAccumulatedDataBuilder}; pub fn propagate_accumulated_data( data: &mut PublicAccumulatedDataBuilder, - from_data: PublicAccumulatedData + from_data: PublicAccumulatedData, ) -> PublicAccumulatedDataBuilder { propagate_note_hashes(data, from_data); propagate_nullifiers(data, from_data); @@ -12,7 +12,10 @@ pub fn propagate_accumulated_data( *data } -fn propagate_note_hashes(data: &mut PublicAccumulatedDataBuilder, from_data: PublicAccumulatedData) { +fn propagate_note_hashes( + data: &mut PublicAccumulatedDataBuilder, + from_data: PublicAccumulatedData, +) { let note_hashes = from_data.note_hashes; for i in 0..note_hashes.len() { let note_hash = note_hashes[i]; @@ -34,7 +37,7 @@ fn propagate_nullifiers(data: &mut PublicAccumulatedDataBuilder, from_data: Publ fn propagate_l2_to_l1_messages( data: &mut PublicAccumulatedDataBuilder, - from_data: PublicAccumulatedData + from_data: PublicAccumulatedData, ) { let msgs = from_data.l2_to_l1_msgs; for i in 0..msgs.len() { @@ -47,7 +50,7 @@ fn propagate_l2_to_l1_messages( fn propagate_unencrypted_logs( data: &mut PublicAccumulatedDataBuilder, - from_data: PublicAccumulatedData + from_data: PublicAccumulatedData, ) { let logs = from_data.unencrypted_logs_hashes; for i in 0..logs.len() { @@ -60,7 +63,7 @@ fn propagate_unencrypted_logs( fn propagate_public_data_writes( data: &mut PublicAccumulatedDataBuilder, - from_data: PublicAccumulatedData + from_data: PublicAccumulatedData, ) { let writes = from_data.public_data_update_requests; for i in 0..writes.len() { diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_validator.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_validator.nr index a2ea6b73821..52e0af2d111 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_validator.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_kernel_output_validator.nr @@ -1,11 +1,12 @@ -use crate::{public_kernel_phase::PublicKernelPhase}; +use crate::public_kernel_phase::PublicKernelPhase; use dep::types::{ abis::{ - accumulated_data::public_accumulated_data::{PublicAccumulatedData, PublicAccumulatedDataArrayLengths}, - kernel_circuit_public_inputs::{PublicKernelCircuitPublicInputs, VMCircuitPublicInputs}, - validation_requests::public_validation_requests::PublicValidationRequestArrayLengths -}, - traits::is_empty, utils::arrays::{array_length, assert_array_appended, assert_array_prepended} + accumulated_data::public_accumulated_data::{ + PublicAccumulatedData, PublicAccumulatedDataArrayLengths, + }, kernel_circuit_public_inputs::{PublicKernelCircuitPublicInputs, VMCircuitPublicInputs}, + validation_requests::public_validation_requests::PublicValidationRequestArrayLengths, + }, traits::is_empty, + utils::arrays::{array_length, assert_array_appended, assert_array_prepended}, }; pub struct PublicKernelOutputValidator { @@ -16,7 +17,7 @@ pub struct PublicKernelOutputValidator { revertible: bool, previous_validation_request_array_lengths: PublicValidationRequestArrayLengths, previous_non_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths, - previous_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths + previous_revertible_data_array_lengths: PublicAccumulatedDataArrayLengths, } impl PublicKernelOutputValidator { @@ -24,12 +25,15 @@ impl PublicKernelOutputValidator { output: PublicKernelCircuitPublicInputs, previous_kernel: PublicKernelCircuitPublicInputs, enqueued_call: VMCircuitPublicInputs, - phase: u8 + phase: u8, ) -> Self { let revertible = phase != PublicKernelPhase.SETUP; - let previous_validation_request_array_lengths = PublicValidationRequestArrayLengths::new(previous_kernel.validation_requests); - let previous_non_revertible_data_array_lengths = PublicAccumulatedDataArrayLengths::new(previous_kernel.end_non_revertible); - let previous_revertible_data_array_lengths = PublicAccumulatedDataArrayLengths::new(previous_kernel.end); + let previous_validation_request_array_lengths = + PublicValidationRequestArrayLengths::new(previous_kernel.validation_requests); + let previous_non_revertible_data_array_lengths = + PublicAccumulatedDataArrayLengths::new(previous_kernel.end_non_revertible); + let previous_revertible_data_array_lengths = + PublicAccumulatedDataArrayLengths::new(previous_kernel.end); PublicKernelOutputValidator { output, previous_kernel, @@ -38,7 +42,7 @@ impl PublicKernelOutputValidator { revertible, previous_validation_request_array_lengths, previous_non_revertible_data_array_lengths, - previous_revertible_data_array_lengths + previous_revertible_data_array_lengths, } } @@ -59,10 +63,14 @@ impl PublicKernelOutputValidator { assert_eq(out.tx_context, prev.tx_context, "mismatch tx_context"); assert_eq(out.vk_tree_root, prev.vk_tree_root, "mismatch vk_tree_root"); assert_eq( - out.protocol_contract_tree_root, prev.protocol_contract_tree_root, "mismatch protocol_contract_tree_root" + out.protocol_contract_tree_root, + prev.protocol_contract_tree_root, + "mismatch protocol_contract_tree_root", ); assert_eq( - out.global_variables, self.enqueued_call.constants.global_variables, "mismatch global_variables" + out.global_variables, + self.enqueued_call.constants.global_variables, + "mismatch global_variables", ); } @@ -72,7 +80,9 @@ impl PublicKernelOutputValidator { assert(is_empty(out), "public_teardown_call_request must be empty after teardown"); } else { assert_eq( - out, self.previous_kernel.public_teardown_call_request, "mismatch public_teardown_call_request" + out, + self.previous_kernel.public_teardown_call_request, + "mismatch public_teardown_call_request", ); } } @@ -96,31 +106,31 @@ impl PublicKernelOutputValidator { assert_array_prepended( out.note_hash_read_requests, prev.note_hash_read_requests, - prev_lengths.note_hash_read_requests + prev_lengths.note_hash_read_requests, ); assert_array_prepended( out.nullifier_read_requests, prev.nullifier_read_requests, - prev_lengths.nullifier_read_requests + prev_lengths.nullifier_read_requests, ); assert_array_prepended( out.nullifier_non_existent_read_requests, prev.nullifier_non_existent_read_requests, - prev_lengths.nullifier_non_existent_read_requests + prev_lengths.nullifier_non_existent_read_requests, ); assert_array_prepended( out.l1_to_l2_msg_read_requests, prev.l1_to_l2_msg_read_requests, - prev_lengths.l1_to_l2_msg_read_requests + prev_lengths.l1_to_l2_msg_read_requests, ); assert_array_prepended( out.public_data_reads, prev.public_data_reads, - prev_lengths.public_data_reads + prev_lengths.public_data_reads, ); } @@ -131,40 +141,39 @@ impl PublicKernelOutputValidator { let prev_lengths = self.previous_validation_request_array_lengths; // Note that the enqueued call cannot modify the max block number value - it simply forwards it to the rollup. - assert_array_appended( out.note_hash_read_requests, curr.note_hash_read_requests, curr_lengths.note_hash_read_requests, - prev_lengths.note_hash_read_requests + prev_lengths.note_hash_read_requests, ); assert_array_appended( out.nullifier_read_requests, curr.nullifier_read_requests, curr_lengths.nullifier_read_requests, - prev_lengths.nullifier_read_requests + prev_lengths.nullifier_read_requests, ); assert_array_appended( out.nullifier_non_existent_read_requests, curr.nullifier_non_existent_read_requests, curr_lengths.nullifier_non_existent_read_requests, - prev_lengths.nullifier_non_existent_read_requests + prev_lengths.nullifier_non_existent_read_requests, ); assert_array_appended( out.l1_to_l2_msg_read_requests, curr.l1_to_l2_msg_read_requests, curr_lengths.l1_to_l2_msg_read_requests, - prev_lengths.l1_to_l2_msg_read_requests + prev_lengths.l1_to_l2_msg_read_requests, ); assert_array_appended( out.public_data_reads, curr.public_data_reads, curr_lengths.public_data_reads, - prev_lengths.public_data_reads + prev_lengths.public_data_reads, ); } @@ -172,7 +181,6 @@ impl PublicKernelOutputValidator { // TODO: Should keep the data even when reverts. let revert_in_phase = (self.output.revert_code != 0) & ((self.phase != PublicKernelPhase.TEARDOWN) | (self.output.revert_code != 1)); // Revert in APP_LOGIC - self.validate_accumulated_data_from_private(revert_in_phase); self.validate_combined_accumulated_data(revert_in_phase); self.validate_gas_used(); @@ -182,27 +190,39 @@ impl PublicKernelOutputValidator { let out = self.output.end_non_revertible; let prev = self.previous_kernel.end_non_revertible; assert_eq( - out.note_encrypted_logs_hashes, prev.note_encrypted_logs_hashes, "mismatch non-revertible note_encrypted_logs_hashes" + out.note_encrypted_logs_hashes, + prev.note_encrypted_logs_hashes, + "mismatch non-revertible note_encrypted_logs_hashes", ); assert_eq( - out.encrypted_logs_hashes, prev.encrypted_logs_hashes, "mismatch non-revertible encrypted_logs_hashes" + out.encrypted_logs_hashes, + prev.encrypted_logs_hashes, + "mismatch non-revertible encrypted_logs_hashes", ); let out = self.output.end; let prev = self.previous_kernel.end; if revert_in_phase { assert_eq( - array_length(out.note_encrypted_logs_hashes), 0, "revertible note_encrypted_logs_hashes must be cleared after revert" + array_length(out.note_encrypted_logs_hashes), + 0, + "revertible note_encrypted_logs_hashes must be cleared after revert", ); assert_eq( - array_length(out.encrypted_logs_hashes), 0, "revertible encrypted_logs_hashes must be cleared after revert" + array_length(out.encrypted_logs_hashes), + 0, + "revertible encrypted_logs_hashes must be cleared after revert", ); } else { assert_eq( - out.note_encrypted_logs_hashes, prev.note_encrypted_logs_hashes, "mismatch revertible note_encrypted_logs_hashes" + out.note_encrypted_logs_hashes, + prev.note_encrypted_logs_hashes, + "mismatch revertible note_encrypted_logs_hashes", ); assert_eq( - out.encrypted_logs_hashes, prev.encrypted_logs_hashes, "mismatch revertible encrypted_logs_hashes" + out.encrypted_logs_hashes, + prev.encrypted_logs_hashes, + "mismatch revertible encrypted_logs_hashes", ); } } @@ -226,14 +246,18 @@ impl PublicKernelOutputValidator { self.validate_prepended_accumulated_data( out_non_revertible, prev_non_revertible, - prev_non_revertible_lengths + prev_non_revertible_lengths, ); let prepended_revertible_lengths = if revert_in_phase { empty_lengths } else { prev_revertible_lengths }; - self.validate_prepended_accumulated_data(out_revertible, prev_revertible, prepended_revertible_lengths); + self.validate_prepended_accumulated_data( + out_revertible, + prev_revertible, + prepended_revertible_lengths, + ); // Appended from enqueued call. let curr_data = self.enqueued_call.accumulated_data; @@ -252,13 +276,13 @@ impl PublicKernelOutputValidator { out_non_revertible, curr_data, prev_non_revertible_lengths, - appended_non_revertible_lengths + appended_non_revertible_lengths, ); self.validate_appended_accumulated_data( out_revertible, curr_data, prev_revertible_lengths, - appended_revertible_lengths + appended_revertible_lengths, ); } @@ -266,7 +290,7 @@ impl PublicKernelOutputValidator { _self: Self, out: PublicAccumulatedData, prev: PublicAccumulatedData, - lengths: PublicAccumulatedDataArrayLengths + lengths: PublicAccumulatedDataArrayLengths, ) { assert_array_prepended(out.note_hashes, prev.note_hashes, lengths.note_hashes); assert_array_prepended(out.nullifiers, prev.nullifiers, lengths.nullifiers); @@ -274,17 +298,17 @@ impl PublicKernelOutputValidator { assert_array_prepended( out.unencrypted_logs_hashes, prev.unencrypted_logs_hashes, - lengths.unencrypted_logs_hashes + lengths.unencrypted_logs_hashes, ); assert_array_prepended( out.public_data_update_requests, prev.public_data_update_requests, - lengths.public_data_update_requests + lengths.public_data_update_requests, ); assert_array_prepended( out.public_call_stack, prev.public_call_stack, - lengths.public_call_stack + lengths.public_call_stack, ); } @@ -293,37 +317,37 @@ impl PublicKernelOutputValidator { out: PublicAccumulatedData, curr: PublicAccumulatedData, prev_lengths: PublicAccumulatedDataArrayLengths, - curr_lengths: PublicAccumulatedDataArrayLengths + curr_lengths: PublicAccumulatedDataArrayLengths, ) { assert_array_appended( out.note_hashes, curr.note_hashes, curr_lengths.note_hashes, - prev_lengths.note_hashes + prev_lengths.note_hashes, ); assert_array_appended( out.nullifiers, curr.nullifiers, curr_lengths.nullifiers, - prev_lengths.nullifiers + prev_lengths.nullifiers, ); assert_array_appended( out.l2_to_l1_msgs, curr.l2_to_l1_msgs, curr_lengths.l2_to_l1_msgs, - prev_lengths.l2_to_l1_msgs + prev_lengths.l2_to_l1_msgs, ); assert_array_appended( out.unencrypted_logs_hashes, curr.unencrypted_logs_hashes, curr_lengths.unencrypted_logs_hashes, - prev_lengths.unencrypted_logs_hashes + prev_lengths.unencrypted_logs_hashes, ); assert_array_appended( out.public_data_update_requests, curr.public_data_update_requests, curr_lengths.public_data_update_requests, - prev_lengths.public_data_update_requests + prev_lengths.public_data_update_requests, ); } @@ -339,14 +363,22 @@ impl PublicKernelOutputValidator { expected_revertible_gas_used += curr_gas_used; } assert_eq( - out_non_revertible_gas_used, expected_non_revertible_gas_used, "wrong non-revertible gas used" + out_non_revertible_gas_used, + expected_non_revertible_gas_used, + "wrong non-revertible gas used", + ); + assert_eq( + out_revertible_gas_used, + expected_revertible_gas_used, + "wrong revertible gas used", ); - assert_eq(out_revertible_gas_used, expected_revertible_gas_used, "wrong revertible gas used"); } fn validate_end_side_effect_counter(self) { assert_eq( - self.output.end_side_effect_counter, self.enqueued_call.end_side_effect_counter, "mismatch end_side_effect_counter" + self.output.end_side_effect_counter, + self.enqueued_call.end_side_effect_counter, + "mismatch end_side_effect_counter", ); } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer.nr index d7898c51a26..61a302e5187 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer.nr @@ -6,10 +6,13 @@ mod generate_public_data_leaves; pub use generate_output_hints::{OutputHints, SiloedNoteHashHint}; pub use generate_overridable_public_data_writes::LinkedIndexHint; -use crate::components::public_tail_output_composer::{combine_data::combine_data, generate_output_hints::generate_output_hints}; +use crate::components::public_tail_output_composer::{ + combine_data::combine_data, generate_output_hints::generate_output_hints, +}; use dep::types::{ - abis::{kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PublicKernelCircuitPublicInputs}}, - data::PublicDataLeafHint, partial_state_reference::PartialStateReference + abis::kernel_circuit_public_inputs::{ + KernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, + }, data::PublicDataLeafHint, partial_state_reference::PartialStateReference, }; pub struct PublicTailOutputComposer { @@ -22,27 +25,31 @@ impl PublicTailOutputComposer Self { PublicTailOutputComposer { previous_kernel, start_state, public_data_leaf_hints } } - pub unconstrained fn finish(self) -> (KernelCircuitPublicInputs, OutputHints) { + pub unconstrained fn finish( + self, + ) -> (KernelCircuitPublicInputs, OutputHints) { let output_hints = generate_output_hints(self.previous_kernel, self.public_data_leaf_hints); let end = combine_data( self.previous_kernel.end_non_revertible, self.previous_kernel.end, - output_hints + output_hints, ); - (KernelCircuitPublicInputs { - rollup_validation_requests: self.previous_kernel.validation_requests.for_rollup, - end, - constants: self.previous_kernel.constants, - start_state: self.start_state, - revert_code: self.previous_kernel.revert_code, - fee_payer: self.previous_kernel.fee_payer - }, output_hints) + ( + KernelCircuitPublicInputs { + rollup_validation_requests: self.previous_kernel.validation_requests.for_rollup, + end, + constants: self.previous_kernel.constants, + start_state: self.start_state, + revert_code: self.previous_kernel.revert_code, + fee_payer: self.previous_kernel.fee_payer, + }, output_hints, + ) } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/combine_data.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/combine_data.nr index 896616409ab..01c537cf41f 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/combine_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/combine_data.nr @@ -1,46 +1,49 @@ use crate::components::public_tail_output_composer::generate_output_hints::OutputHints; use dep::types::{ abis::{ - accumulated_data::{CombinedAccumulatedData, PublicAccumulatedData}, - log_hash::{LogHash, ScopedLogHash}, nullifier::Nullifier -}, - utils::arrays::{array_merge, dedupe_array, sort_by_counter_asc} + accumulated_data::{CombinedAccumulatedData, PublicAccumulatedData}, + log_hash::{LogHash, ScopedLogHash}, nullifier::Nullifier, + }, utils::arrays::{array_merge, dedupe_array, sort_by_counter_asc}, }; pub unconstrained fn combine_data( non_revertible: PublicAccumulatedData, revertible: PublicAccumulatedData, - output_hints: OutputHints + output_hints: OutputHints, ) -> CombinedAccumulatedData { - let nullifiers = sort_by_counter_asc(array_merge(non_revertible.nullifiers, revertible.nullifiers)).map(|n: Nullifier| n.value); + let nullifiers = sort_by_counter_asc(array_merge( + non_revertible.nullifiers, + revertible.nullifiers, + )) + .map(|n: Nullifier| n.value); - let l2_to_l1_msgs = sort_by_counter_asc(array_merge(non_revertible.l2_to_l1_msgs, revertible.l2_to_l1_msgs)); + let l2_to_l1_msgs = sort_by_counter_asc(array_merge( + non_revertible.l2_to_l1_msgs, + revertible.l2_to_l1_msgs, + )); let public_data_update_requests = dedupe_array(output_hints.public_data_writes); - let note_encrypted_logs_hashes = sort_by_counter_asc( - array_merge( - non_revertible.note_encrypted_logs_hashes, - revertible.note_encrypted_logs_hashes - ) - ); - let note_encrypted_log_preimages_length = note_encrypted_logs_hashes.fold(0, |a, b: LogHash| a + b.length); + let note_encrypted_logs_hashes = sort_by_counter_asc(array_merge( + non_revertible.note_encrypted_logs_hashes, + revertible.note_encrypted_logs_hashes, + )); + let note_encrypted_log_preimages_length = + note_encrypted_logs_hashes.fold(0, |a, b: LogHash| a + b.length); - let encrypted_logs_hashes = sort_by_counter_asc( - array_merge( - non_revertible.encrypted_logs_hashes, - revertible.encrypted_logs_hashes - ) - ); - let encrypted_log_preimages_length = encrypted_logs_hashes.fold(0, |a, b: ScopedLogHash| a + b.log_hash.length); + let encrypted_logs_hashes = sort_by_counter_asc(array_merge( + non_revertible.encrypted_logs_hashes, + revertible.encrypted_logs_hashes, + )); + let encrypted_log_preimages_length = + encrypted_logs_hashes.fold(0, |a, b: ScopedLogHash| a + b.log_hash.length); - let unencrypted_logs_hashes = sort_by_counter_asc( - array_merge( - non_revertible.unencrypted_logs_hashes, - revertible.unencrypted_logs_hashes - ) - ); - let unencrypted_log_preimages_length = unencrypted_logs_hashes.fold(0, |a, b: ScopedLogHash| a + b.log_hash.length); + let unencrypted_logs_hashes = sort_by_counter_asc(array_merge( + non_revertible.unencrypted_logs_hashes, + revertible.unencrypted_logs_hashes, + )); + let unencrypted_log_preimages_length = + unencrypted_logs_hashes.fold(0, |a, b: ScopedLogHash| a + b.log_hash.length); CombinedAccumulatedData { note_hashes: output_hints.siloed_note_hashes, @@ -53,6 +56,6 @@ pub unconstrained fn combine_data( encrypted_log_preimages_length, unencrypted_log_preimages_length, public_data_update_requests, - gas_used: revertible.gas_used + non_revertible.gas_used + gas_used: revertible.gas_used + non_revertible.gas_used, } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_output_hints.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_output_hints.nr index 7de87149d65..17d38d69f39 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_output_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_output_hints.nr @@ -1,19 +1,23 @@ use crate::components::public_tail_output_composer::{ - generate_overridable_public_data_writes::{generate_overridable_public_data_writes, LinkedIndexHint}, - generate_public_data_leaves::generate_public_data_leaves + generate_overridable_public_data_writes::{ + generate_overridable_public_data_writes, LinkedIndexHint, + }, generate_public_data_leaves::generate_public_data_leaves, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, - public_data_write::OverridablePublicDataWrite -}, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + public_data_write::OverridablePublicDataWrite, + }, constants::{ - MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX -}, - data::{OverridablePublicDataTreeLeaf, PublicDataLeafHint}, hash::silo_note_hash, traits::Empty, - utils::arrays::{array_merge, CombinedOrderHint, get_combined_order_hints_asc, sort_by_counter_asc, SortedResult} + MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + }, data::{OverridablePublicDataTreeLeaf, PublicDataLeafHint}, hash::silo_note_hash, + traits::Empty, + utils::arrays::{ + array_merge, CombinedOrderHint, get_combined_order_hints_asc, sort_by_counter_asc, + SortedResult, + }, }; pub struct SiloedNoteHashHint { @@ -50,7 +54,7 @@ pub struct OutputHints { pub unconstrained fn generate_output_hints( previous_kernel: PublicKernelCircuitPublicInputs, - public_data_leaf_hints: [PublicDataLeafHint; NUM_PUBLIC_DATA_LEAVES] + public_data_leaf_hints: [PublicDataLeafHint; NUM_PUBLIC_DATA_LEAVES], ) -> OutputHints { let non_revertible = previous_kernel.end_non_revertible; let revertible = previous_kernel.end; @@ -58,7 +62,10 @@ pub unconstrained fn generate_output_hints( // Note hashes. let mut siloed_note_hashes = [0; MAX_NOTE_HASHES_PER_TX]; let mut siloed_note_hash_hints = [SiloedNoteHashHint::empty(); MAX_NOTE_HASHES_PER_TX]; - let sorted_unsiloed_note_hashes = sort_by_counter_asc(array_merge(non_revertible.note_hashes, revertible.note_hashes)); + let sorted_unsiloed_note_hashes = sort_by_counter_asc(array_merge( + non_revertible.note_hashes, + revertible.note_hashes, + )); let tx_hash = non_revertible.nullifiers[0].value; for i in 0..sorted_unsiloed_note_hashes.len() { let note_hash = sorted_unsiloed_note_hashes[i]; @@ -77,36 +84,46 @@ pub unconstrained fn generate_output_hints( // Public data. let combined_writes = array_merge( previous_kernel.end_non_revertible.public_data_update_requests, - previous_kernel.end.public_data_update_requests + previous_kernel.end.public_data_update_requests, ); let (public_data_leaves, unique_slot_index_hints) = generate_public_data_leaves( previous_kernel.validation_requests.public_data_reads, combined_writes, - public_data_leaf_hints + public_data_leaf_hints, ); - let (public_data_writes, public_data_linked_index_hints) = generate_overridable_public_data_writes(combined_writes, public_data_leaves); + let (public_data_writes, public_data_linked_index_hints) = + generate_overridable_public_data_writes(combined_writes, public_data_leaves); OutputHints { siloed_note_hashes, siloed_note_hash_hints, - sorted_note_hash_hints: get_combined_order_hints_asc(non_revertible.note_hashes, revertible.note_hashes), - sorted_nullifier_hints: get_combined_order_hints_asc(non_revertible.nullifiers, revertible.nullifiers), - sorted_l2_to_l1_msg_hints: get_combined_order_hints_asc(non_revertible.l2_to_l1_msgs, revertible.l2_to_l1_msgs), + sorted_note_hash_hints: get_combined_order_hints_asc( + non_revertible.note_hashes, + revertible.note_hashes, + ), + sorted_nullifier_hints: get_combined_order_hints_asc( + non_revertible.nullifiers, + revertible.nullifiers, + ), + sorted_l2_to_l1_msg_hints: get_combined_order_hints_asc( + non_revertible.l2_to_l1_msgs, + revertible.l2_to_l1_msgs, + ), sorted_note_encrypted_log_hash_hints: get_combined_order_hints_asc( non_revertible.note_encrypted_logs_hashes, - revertible.note_encrypted_logs_hashes + revertible.note_encrypted_logs_hashes, ), sorted_encrypted_log_hash_hints: get_combined_order_hints_asc( non_revertible.encrypted_logs_hashes, - revertible.encrypted_logs_hashes + revertible.encrypted_logs_hashes, ), sorted_unencrypted_log_hash_hints: get_combined_order_hints_asc( non_revertible.unencrypted_logs_hashes, - revertible.unencrypted_logs_hashes + revertible.unencrypted_logs_hashes, ), public_data_writes, public_data_leaves, unique_slot_index_hints, - public_data_linked_index_hints + public_data_linked_index_hints, } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_overridable_public_data_writes.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_overridable_public_data_writes.nr index d49503dd011..f67768f322c 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_overridable_public_data_writes.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_composer/generate_overridable_public_data_writes.nr @@ -1,6 +1,9 @@ use dep::types::{ - abis::{public_data_update_request::PublicDataUpdateRequest, public_data_write::OverridablePublicDataWrite}, - data::OverridablePublicDataTreeLeaf, traits::Empty, utils::arrays::{array_length, find_index_hint} + abis::{ + public_data_update_request::PublicDataUpdateRequest, + public_data_write::OverridablePublicDataWrite, + }, data::OverridablePublicDataTreeLeaf, traits::Empty, + utils::arrays::{array_length, find_index_hint}, }; pub struct LinkedIndexHint { @@ -16,7 +19,7 @@ impl Empty for LinkedIndexHint { pub unconstrained fn generate_overridable_public_data_writes( public_data_writes: [PublicDataUpdateRequest; NUM_WRITES], - public_data_leaves: [OverridablePublicDataTreeLeaf; NUM_LEAVES] + public_data_leaves: [OverridablePublicDataTreeLeaf; NUM_LEAVES], ) -> ([OverridablePublicDataWrite; NUM_WRITES], [LinkedIndexHint; NUM_WRITES]) { let mut overridable_public_data_writes = [OverridablePublicDataWrite::empty(); NUM_WRITES]; let mut hints = [LinkedIndexHint::empty(); NUM_WRITES]; @@ -47,7 +50,10 @@ pub unconstrained fn generate_overridable_public_data_writes bool { pub unconstrained fn generate_public_data_leaves( reads: [PublicDataRead; NUM_READS], writes: [PublicDataUpdateRequest; NUM_WRITES], - hints: [PublicDataLeafHint; NUM_HINTS] + hints: [PublicDataLeafHint; NUM_HINTS], ) -> ([OverridablePublicDataTreeLeaf; NUM_HINTS], SortedResult) { // Combine reads and writes. The combined data has the slots and original indexes. // Original indexes for writes are modified to have an offset of NUM_READS, ensuring that writes are placed after reads. @@ -51,7 +51,9 @@ pub unconstrained fn generate_public_data_leaves { @@ -38,9 +38,15 @@ impl PublicTailOutputValidator, - public_data_leaf_hints: [PublicDataLeafHint; NUM_PUBLIC_DATA_LEAVES] + public_data_leaf_hints: [PublicDataLeafHint; NUM_PUBLIC_DATA_LEAVES], ) -> Self { - PublicTailOutputValidator { output, previous_kernel, start_state, hints, public_data_leaf_hints } + PublicTailOutputValidator { + output, + previous_kernel, + start_state, + hints, + public_data_leaf_hints, + } } pub fn validate(self) { @@ -55,11 +61,17 @@ impl PublicTailOutputValidator PublicTailOutputValidator PublicTailOutputValidator PublicTailOutputValidator PublicTailOutputValidator PublicTailOutputValidator PublicTailOutputValidator PublicTailOutputValidator( public_data_writes: [OverridablePublicDataWrite; NUM_WRITES], public_data_leaves: [OverridablePublicDataTreeLeaf; NUM_LEAVES], - hints: [LinkedIndexHint; NUM_WRITES] + hints: [LinkedIndexHint; NUM_WRITES], ) { for i in 0..public_data_writes.len() { let write = public_data_writes[i]; @@ -16,17 +18,32 @@ pub fn validate_linked_public_data_writes Self { let public_data_writes = pad_end( [ - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 33, new_value: 300, counter: 30 }, override_counter: 0 }, - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 22, new_value: 202, counter: 40 }, override_counter: 50 }, - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 11, new_value: 100, counter: 10 }, override_counter: 0 }, - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 22, new_value: 201, counter: 20 }, override_counter: 40 }, - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 22, new_value: 203, counter: 50 }, override_counter: 0 } - ], - OverridablePublicDataWrite::empty() + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 33, + new_value: 300, + counter: 30, + }, + override_counter: 0, + }, + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 22, + new_value: 202, + counter: 40, + }, + override_counter: 50, + }, + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 11, + new_value: 100, + counter: 10, + }, + override_counter: 0, + }, + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 22, + new_value: 201, + counter: 20, + }, + override_counter: 40, + }, + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 22, + new_value: 203, + counter: 50, + }, + override_counter: 0, + }, + ], + OverridablePublicDataWrite::empty(), ); let public_data_leaves = pad_end( [ - OverridablePublicDataTreeLeaf { leaf: PublicDataTreeLeaf { slot: 0, value: 0 }, override_counter: 0 }, - OverridablePublicDataTreeLeaf { leaf: PublicDataTreeLeaf { slot: 22, value: 200 }, override_counter: 20 }, - OverridablePublicDataTreeLeaf { leaf: PublicDataTreeLeaf { slot: 44, value: 0 }, override_counter: 0 }, - OverridablePublicDataTreeLeaf { leaf: PublicDataTreeLeaf { slot: 11, value: 0 }, override_counter: 10 }, - OverridablePublicDataTreeLeaf { leaf: PublicDataTreeLeaf { slot: 33, value: 0 }, override_counter: 30 } - ], - OverridablePublicDataTreeLeaf::empty() + OverridablePublicDataTreeLeaf { + leaf: PublicDataTreeLeaf { slot: 0, value: 0 }, + override_counter: 0, + }, + OverridablePublicDataTreeLeaf { + leaf: PublicDataTreeLeaf { slot: 22, value: 200 }, + override_counter: 20, + }, + OverridablePublicDataTreeLeaf { + leaf: PublicDataTreeLeaf { slot: 44, value: 0 }, + override_counter: 0, + }, + OverridablePublicDataTreeLeaf { + leaf: PublicDataTreeLeaf { slot: 11, value: 0 }, + override_counter: 10, + }, + OverridablePublicDataTreeLeaf { + leaf: PublicDataTreeLeaf { slot: 33, value: 0 }, + override_counter: 30, + }, + ], + OverridablePublicDataTreeLeaf::empty(), ); let hints = pad_end( [ - LinkedIndexHint { is_first_write: true, prev_index: 4 }, - LinkedIndexHint { is_first_write: false, prev_index: 3 }, - LinkedIndexHint { is_first_write: true, prev_index: 3 }, - LinkedIndexHint { is_first_write: true, prev_index: 1 }, - LinkedIndexHint { is_first_write: false, prev_index: 1 } - ], - LinkedIndexHint::empty() + LinkedIndexHint { is_first_write: true, prev_index: 4 }, + LinkedIndexHint { is_first_write: false, prev_index: 3 }, + LinkedIndexHint { is_first_write: true, prev_index: 3 }, + LinkedIndexHint { is_first_write: true, prev_index: 1 }, + LinkedIndexHint { is_first_write: false, prev_index: 1 }, + ], + LinkedIndexHint::empty(), ); TestBuilder { public_data_writes, public_data_leaves, hints } } pub fn execute(self) { - validate_linked_public_data_writes(self.public_data_writes, self.public_data_leaves, self.hints); + validate_linked_public_data_writes( + self.public_data_writes, + self.public_data_leaves, + self.hints, + ); } } @@ -148,7 +221,8 @@ mod tests { // Change from leaf -> write[3] -> write[1] -> write[4] to leaf -> write[1] -> write[3] -> write[4] let leaf_index = builder.hints[3].prev_index; // Link the leaf to the 1st write. - builder.public_data_leaves[leaf_index].override_counter = builder.public_data_writes[1].counter(); + builder.public_data_leaves[leaf_index].override_counter = + builder.public_data_writes[1].counter(); // Link the 1st write to the leaf and the 3rd write. builder.hints[1].is_first_write = true; builder.hints[1].prev_index = leaf_index; diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_public_data_leaf_memberships.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_public_data_leaf_memberships.nr index 1bd7f6b3c2d..c5c184ff8c2 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_public_data_leaf_memberships.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_public_data_leaf_memberships.nr @@ -1,6 +1,6 @@ use dep::types::{ data::{OverridablePublicDataTreeLeaf, PublicDataLeafHint}, - merkle_tree::conditionally_assert_check_membership + merkle_tree::conditionally_assert_check_membership, }; // Perform membership check for all non-zero leaf slots, ensuring that the values being read are correct and the public data tree is updated with the correct low leaves. @@ -8,7 +8,7 @@ use dep::types::{ pub fn validate_public_data_leaf_memberships( leaves: [OverridablePublicDataTreeLeaf; N], leaf_hints: [PublicDataLeafHint; N], - tree_root: Field + tree_root: Field, ) { for i in 0..leaves.len() { let leaf = leaves[i].leaf; @@ -17,7 +17,8 @@ pub fn validate_public_data_leaf_memberships( let exists_in_tree = leaf.slot == hint.preimage.slot; if exists_in_tree { assert( - leaf.value == hint.preimage.value, "Hinted public data value does not match the value in leaf preimage" + leaf.value == hint.preimage.value, + "Hinted public data value does not match the value in leaf preimage", ); } else { assert(leaf.value == 0, "Value must be 0 for non-existent public data"); @@ -28,7 +29,7 @@ pub fn validate_public_data_leaf_memberships( exists_in_tree, hint.preimage, hint.membership_witness, - tree_root + tree_root, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_unique_leaf_slots.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_unique_leaf_slots.nr index 8e9675ae592..63fd9ffea1e 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_unique_leaf_slots.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/public_tail_output_validator/validate_unique_leaf_slots.nr @@ -3,7 +3,7 @@ use dep::types::{data::OverridablePublicDataTreeLeaf, utils::arrays::SortedResul // Validate that every non-zero slot in leaves is unique. pub fn validate_unique_leaf_slots( leaves: [OverridablePublicDataTreeLeaf; N], - unique_slot_index_hints: SortedResult + unique_slot_index_hints: SortedResult, ) { let sorted_leaf_slots = unique_slot_index_hints.sorted_array; let sorted_leaf_slot_indexes = unique_slot_index_hints.sorted_index_hints; @@ -19,7 +19,6 @@ pub fn validate_unique_leaf_slots( let hinted_leaf_slot = sorted_leaf_slots[sorted_index]; assert_eq(hinted_leaf_slot, leaf.slot, "mismatch hinted slot"); assert_eq(original_leaf_indexes[sorted_index], i, "sorted value does not link to leaf"); // This ensures that each sorted_leaf_slot can only be refered to once. - let curr_leaf_alot = sorted_leaf_slots[i]; if leaf.slot != 0 { assert(prev_slot.lt(curr_leaf_alot), "hinted slots are not sorted"); // This ensures that all non-zero slots are unique. @@ -32,7 +31,7 @@ mod tests { use crate::components::public_tail_output_validator::validate_unique_leaf_slots::validate_unique_leaf_slots; use dep::types::{ data::{OverridablePublicDataTreeLeaf, PublicDataTreeLeaf}, tests::utils::pad_end, - utils::arrays::SortedResult + utils::arrays::SortedResult, }; global NUM_TEST_LEAVES = 10; @@ -57,9 +56,12 @@ mod tests { } pub fn update_leaves(&mut self, slots: [Field; N]) { - let leaves = slots.map( - |slot: Field| OverridablePublicDataTreeLeaf { leaf: PublicDataTreeLeaf { slot, value: 1 }, override_counter: 0 } - ); + let leaves = slots.map(|slot: Field| { + OverridablePublicDataTreeLeaf { + leaf: PublicDataTreeLeaf { slot, value: 1 }, + override_counter: 0, + } + }); self.leaves = pad_end(leaves, OverridablePublicDataTreeLeaf::empty()); } @@ -83,7 +85,7 @@ mod tests { let hints = SortedResult { sorted_array: self.sorted_array, sorted_index_hints: self.sorted_index_hints, - original_index_hints: self.original_index_hints + original_index_hints: self.original_index_hints, }; validate_unique_leaf_slots(self.leaves, hints); } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr index a982e37d4f6..8318a02c6c3 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer.nr @@ -1,20 +1,20 @@ mod propagate_accumulated_data; -use crate::{components::vm_circuit_output_composer::propagate_accumulated_data::propagate_accumulated_data}; +use crate::components::vm_circuit_output_composer::propagate_accumulated_data::propagate_accumulated_data; use dep::types::{ abis::{ - accumulated_data::{PublicAccumulatedDataArrayLengths, PublicAccumulatedDataBuilder}, - combined_constant_data::CombinedConstantData, gas::Gas, - kernel_circuit_public_inputs::vm_circuit_public_inputs::VMCircuitPublicInputs, - public_call_request::PublicCallRequest, public_circuit_public_inputs::PublicCircuitPublicInputs, - public_data_read::PublicDataRead, public_inner_call_request::PublicInnerCallRequest, - validation_requests::{ - PublicValidationRequestArrayLengths, - public_validation_requests_builder::PublicValidationRequestsBuilder -} -}, - constants::MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, traits::is_empty, - utils::arrays::array_to_bounded_vec + accumulated_data::{PublicAccumulatedDataArrayLengths, PublicAccumulatedDataBuilder}, + combined_constant_data::CombinedConstantData, gas::Gas, + kernel_circuit_public_inputs::vm_circuit_public_inputs::VMCircuitPublicInputs, + public_call_request::PublicCallRequest, + public_circuit_public_inputs::PublicCircuitPublicInputs, public_data_read::PublicDataRead, + public_inner_call_request::PublicInnerCallRequest, + validation_requests::{ + PublicValidationRequestArrayLengths, + public_validation_requests_builder::PublicValidationRequestsBuilder, + }, + }, constants::MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, traits::is_empty, + utils::arrays::array_to_bounded_vec, }; // TODO(#7124): To be deprecated. @@ -37,21 +37,24 @@ impl VMCircuitOutputComposer { pub fn new_from_previous_kernel(previous_kernel: VMCircuitPublicInputs) -> Self { let mut public_call_stack = array_to_bounded_vec(previous_kernel.public_call_stack); let _ = public_call_stack.pop(); - let validation_requests = PublicValidationRequestsBuilder::new(previous_kernel.validation_requests); + let validation_requests = + PublicValidationRequestsBuilder::new(previous_kernel.validation_requests); let accumulated_data = PublicAccumulatedDataBuilder::new(previous_kernel.accumulated_data); VMCircuitOutputComposer { constants: previous_kernel.constants, call_request: previous_kernel.call_request, public_call_stack, - previous_validation_request_array_lengths: previous_kernel.previous_validation_request_array_lengths, + previous_validation_request_array_lengths: previous_kernel + .previous_validation_request_array_lengths, validation_requests, - previous_accumulated_data_array_lengths: previous_kernel.previous_accumulated_data_array_lengths, + previous_accumulated_data_array_lengths: previous_kernel + .previous_accumulated_data_array_lengths, accumulated_data, start_side_effect_counter: previous_kernel.start_side_effect_counter, end_side_effect_counter: previous_kernel.end_side_effect_counter, start_gas_left: previous_kernel.start_gas_left, transaction_fee: previous_kernel.transaction_fee, - reverted: previous_kernel.reverted + reverted: previous_kernel.reverted, } } @@ -70,7 +73,8 @@ impl VMCircuitOutputComposer { constants: self.constants, call_request: self.call_request, public_call_stack: self.public_call_stack.storage, - previous_validation_request_array_lengths: self.previous_validation_request_array_lengths, + previous_validation_request_array_lengths: self + .previous_validation_request_array_lengths, validation_requests: self.validation_requests.finish(), previous_accumulated_data_array_lengths: self.previous_accumulated_data_array_lengths, accumulated_data: self.accumulated_data.finish(), @@ -78,7 +82,7 @@ impl VMCircuitOutputComposer { end_side_effect_counter: self.end_side_effect_counter, start_gas_left: self.start_gas_left, transaction_fee: self.transaction_fee, - reverted: self.reverted + reverted: self.reverted, } } @@ -90,7 +94,6 @@ impl VMCircuitOutputComposer { fn propagate_validation_requests(&mut self, public_call: PublicCircuitPublicInputs) { // Note that the public kernel cannot modify the max block number value - it simply forwards it to the rollup - let contract_address = public_call.call_context.contract_address; let note_hash_read_requests = public_call.note_hash_read_requests; @@ -105,7 +108,9 @@ impl VMCircuitOutputComposer { for i in 0..nullifier_read_requests.len() { let request = nullifier_read_requests[i]; if !is_empty(request) { - self.validation_requests.nullifier_read_requests.push(request.scope(contract_address)); + self.validation_requests.nullifier_read_requests.push(request.scope( + contract_address, + )); } } @@ -113,7 +118,9 @@ impl VMCircuitOutputComposer { for i in 0..nullifier_non_existent_read_requests.len() { let request = nullifier_non_existent_read_requests[i]; if !is_empty(request) { - self.validation_requests.nullifier_non_existent_read_requests.push(request.scope(contract_address)); + self.validation_requests.nullifier_non_existent_read_requests.push(request.scope( + contract_address, + )); } } @@ -129,7 +136,9 @@ impl VMCircuitOutputComposer { for i in 0..read_requests.len() { let read_request = read_requests[i]; if !is_empty(read_request) { - self.validation_requests.public_data_reads.push(PublicDataRead::from_contract_storage_read(contract_address, read_request)); + self.validation_requests.public_data_reads.push( + PublicDataRead::from_contract_storage_read(contract_address, read_request), + ); } } } @@ -141,7 +150,8 @@ impl VMCircuitOutputComposer { if self.reverted { self.accumulated_data = PublicAccumulatedDataBuilder::empty(); } else { - self.accumulated_data = propagate_accumulated_data(&mut self.accumulated_data, public_call); + self.accumulated_data = + propagate_accumulated_data(&mut self.accumulated_data, public_call); self.propagate_call_requests(public_call); } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr index 1c396c03eb8..3c1df8c3fbf 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/components/vm_circuit_output_composer/propagate_accumulated_data.nr @@ -1,15 +1,14 @@ use dep::types::{ abis::{ - accumulated_data::PublicAccumulatedDataBuilder, nullifier::Nullifier, - public_circuit_public_inputs::PublicCircuitPublicInputs, - public_data_update_request::PublicDataUpdateRequest -}, - hash::compute_siloed_nullifier + accumulated_data::PublicAccumulatedDataBuilder, nullifier::Nullifier, + public_circuit_public_inputs::PublicCircuitPublicInputs, + public_data_update_request::PublicDataUpdateRequest, + }, hash::compute_siloed_nullifier, }; pub fn propagate_accumulated_data( data: &mut PublicAccumulatedDataBuilder, - public_call: PublicCircuitPublicInputs + public_call: PublicCircuitPublicInputs, ) -> PublicAccumulatedDataBuilder { propagate_note_hashes(data, public_call); propagate_nullifiers(data, public_call); @@ -19,7 +18,10 @@ pub fn propagate_accumulated_data( *data } -fn propagate_note_hashes(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { +fn propagate_note_hashes( + data: &mut PublicAccumulatedDataBuilder, + public_call: PublicCircuitPublicInputs, +) { let contract_address = public_call.call_context.contract_address; let note_hashes = public_call.note_hashes; for i in 0..note_hashes.len() { @@ -30,7 +32,10 @@ fn propagate_note_hashes(data: &mut PublicAccumulatedDataBuilder, public_call: P } } -fn propagate_nullifiers(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { +fn propagate_nullifiers( + data: &mut PublicAccumulatedDataBuilder, + public_call: PublicCircuitPublicInputs, +) { let contract_address = public_call.call_context.contract_address; let nullifiers = public_call.nullifiers; for i in 0..nullifiers.len() { @@ -38,13 +43,20 @@ fn propagate_nullifiers(data: &mut PublicAccumulatedDataBuilder, public_call: Pu if nullifier.counter != 0 { let siloed_value = compute_siloed_nullifier(contract_address, nullifier.value); data.nullifiers.push( - Nullifier { value: siloed_value, counter: nullifier.counter, note_hash: nullifier.note_hash } + Nullifier { + value: siloed_value, + counter: nullifier.counter, + note_hash: nullifier.note_hash, + }, ); } } } -fn propagate_l2_to_l1_messages(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { +fn propagate_l2_to_l1_messages( + data: &mut PublicAccumulatedDataBuilder, + public_call: PublicCircuitPublicInputs, +) { let contract_address = public_call.call_context.contract_address; let msgs = public_call.l2_to_l1_msgs; for i in 0..msgs.len() { @@ -55,7 +67,10 @@ fn propagate_l2_to_l1_messages(data: &mut PublicAccumulatedDataBuilder, public_c } } -fn propagate_unencrypted_logs(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { +fn propagate_unencrypted_logs( + data: &mut PublicAccumulatedDataBuilder, + public_call: PublicCircuitPublicInputs, +) { let contract_address = public_call.call_context.contract_address; let logs = public_call.unencrypted_logs_hashes; for i in 0..logs.len() { @@ -66,13 +81,21 @@ fn propagate_unencrypted_logs(data: &mut PublicAccumulatedDataBuilder, public_ca } } -fn propagate_public_data_writes(data: &mut PublicAccumulatedDataBuilder, public_call: PublicCircuitPublicInputs) { +fn propagate_public_data_writes( + data: &mut PublicAccumulatedDataBuilder, + public_call: PublicCircuitPublicInputs, +) { let contract_address = public_call.call_context.contract_address; let writes = public_call.contract_storage_update_requests; for i in 0..writes.len() { let write = writes[i]; if write.counter != 0 { - data.public_data_update_requests.push(PublicDataUpdateRequest::from_contract_storage_update_request(contract_address, write)); + data.public_data_update_requests.push( + PublicDataUpdateRequest::from_contract_storage_update_request( + contract_address, + write, + ), + ); } } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr index 228fac8f1fc..82790088d16 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_inner.nr @@ -1,9 +1,7 @@ -use crate::components::{vm_circuit_output_composer::VMCircuitOutputComposer}; -use dep::types::{ - abis::{ +use crate::components::vm_circuit_output_composer::VMCircuitOutputComposer; +use dep::types::abis::{ kernel_circuit_public_inputs::VMCircuitPublicInputs, - public_kernel_inner_data::PublicKernelInnerData, public_call_data::PublicCallData -} + public_kernel_inner_data::PublicKernelInnerData, public_call_data::PublicCallData, }; // TODO(#7124): To be deprecated. @@ -14,6 +12,8 @@ pub struct PublicKernelInnerCircuitPrivateInputs { impl PublicKernelInnerCircuitPrivateInputs { fn execute(self) -> VMCircuitPublicInputs { - VMCircuitOutputComposer::new_from_previous_kernel(self.previous_kernel.public_inputs).propagate_from_public_call(self.public_call.public_inputs).finish() + VMCircuitOutputComposer::new_from_previous_kernel(self.previous_kernel.public_inputs) + .propagate_from_public_call(self.public_call.public_inputs) + .finish() } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr index 8e8d6344835..6fa7f50fd1c 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_merge.nr @@ -1,24 +1,20 @@ use crate::{ components::{ - enqueued_call_data_validator::EnqueuedCallDataValidator, - previous_kernel_validator::PreviousKernelValidator, - public_kernel_output_composer::PublicKernelOutputComposer, - public_kernel_output_validator::PublicKernelOutputValidator -}, - public_kernel_phase::PublicKernelPhase + enqueued_call_data_validator::EnqueuedCallDataValidator, + previous_kernel_validator::PreviousKernelValidator, + public_kernel_output_composer::PublicKernelOutputComposer, + public_kernel_output_validator::PublicKernelOutputValidator, + }, public_kernel_phase::PublicKernelPhase, }; use dep::types::{ abis::{ - enqueued_call_data::EnqueuedCallData, kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, - public_kernel_data::PublicKernelData -}, - constants::{TUBE_INDEX, PUBLIC_KERNEL_MERGE_INDEX} + enqueued_call_data::EnqueuedCallData, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + public_kernel_data::PublicKernelData, + }, constants::{TUBE_INDEX, PUBLIC_KERNEL_MERGE_INDEX}, }; -global ALLOWED_PREVIOUS_CIRCUITS = [ - TUBE_INDEX, - PUBLIC_KERNEL_MERGE_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = [TUBE_INDEX, PUBLIC_KERNEL_MERGE_INDEX]; pub struct PublicKernelMergeCircuitPrivateInputs { previous_kernel: PublicKernelData, @@ -36,8 +32,12 @@ impl PublicKernelMergeCircuitPrivateInputs { fn get_phase(self) -> u8 { let public_inputs = self.previous_kernel.public_inputs; - let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0].call_context.contract_address.is_zero(); - let needs_app_logic = !public_inputs.end.public_call_stack[0].call_context.contract_address.is_zero(); + let needs_setup = !public_inputs.end_non_revertible.public_call_stack[0] + .call_context + .contract_address + .is_zero(); + let needs_app_logic = + !public_inputs.end.public_call_stack[0].call_context.contract_address.is_zero(); if needs_setup { PublicKernelPhase.SETUP } else if needs_app_logic { @@ -50,27 +50,26 @@ impl PublicKernelMergeCircuitPrivateInputs { fn execute(self) -> PublicKernelCircuitPublicInputs { let phase = self.get_phase(); - let output = unsafe { - self.generate_output(phase) - }; + let output = unsafe { self.generate_output(phase) }; let output_validator = PublicKernelOutputValidator::new( output, self.previous_kernel.public_inputs, self.enqueued_call.data, - phase + phase, ); let previous_kernel_validator = PreviousKernelValidator::new(self.previous_kernel); previous_kernel_validator.validate_proof(ALLOWED_PREVIOUS_CIRCUITS); - let enqueued_call_data_validator = EnqueuedCallDataValidator::new(self.enqueued_call, phase); + let enqueued_call_data_validator = + EnqueuedCallDataValidator::new(self.enqueued_call, phase); enqueued_call_data_validator.validate_proof(); enqueued_call_data_validator.validate_against_previous_kernel( self.previous_kernel.public_inputs, output_validator.previous_validation_request_array_lengths, output_validator.previous_non_revertible_data_array_lengths, - output_validator.previous_revertible_data_array_lengths + output_validator.previous_revertible_data_array_lengths, ); output_validator.validate(); @@ -82,28 +81,30 @@ impl PublicKernelMergeCircuitPrivateInputs { mod tests { use crate::{ public_kernel_phase::PublicKernelPhase, - public_kernel_merge::{ALLOWED_PREVIOUS_CIRCUITS, PublicKernelMergeCircuitPrivateInputs} + public_kernel_merge::{ALLOWED_PREVIOUS_CIRCUITS, PublicKernelMergeCircuitPrivateInputs}, }; use dep::types::{ abis::{ - accumulated_data::PublicAccumulatedDataArrayLengths, gas::Gas, - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, max_block_number::MaxBlockNumber, - validation_requests::PublicValidationRequestArrayLengths - }, - constants::{PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX, BASE_ROLLUP_INDEX}, - tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq} + accumulated_data::PublicAccumulatedDataArrayLengths, gas::Gas, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + max_block_number::MaxBlockNumber, + validation_requests::PublicValidationRequestArrayLengths, + }, constants::{PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX, BASE_ROLLUP_INDEX}, + tests::{fixture_builder::FixtureBuilder, utils::assert_array_eq}, }; struct PublicKernelMergeCircuitPrivateInputsBuilder { previous_kernel: FixtureBuilder, previous_revertible: FixtureBuilder, enqueued_call: FixtureBuilder, - phase: u8 + phase: u8, } impl PublicKernelMergeCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = FixtureBuilder::new().as_parent_contract().in_vk_tree(PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX); + let previous_kernel = FixtureBuilder::new().as_parent_contract().in_vk_tree( + PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX, + ); let mut previous_revertible = FixtureBuilder::new(); let mut enqueued_call = FixtureBuilder::new().is_public_function(); // Add an offset so that the mock data won't be the same as the values in previous_kernel. @@ -113,7 +114,12 @@ mod tests { let phase = PublicKernelPhase.SETUP; - PublicKernelMergeCircuitPrivateInputsBuilder { previous_kernel, previous_revertible, enqueued_call, phase } + PublicKernelMergeCircuitPrivateInputsBuilder { + previous_kernel, + previous_revertible, + enqueued_call, + phase, + } } pub fn execute(&mut self) -> PublicKernelCircuitPublicInputs { @@ -125,17 +131,24 @@ mod tests { } let mut previous_kernel = self.previous_kernel.to_public_kernel_data(false); - previous_kernel.public_inputs.end = self.previous_revertible.to_public_accumulated_data(); + previous_kernel.public_inputs.end = + self.previous_revertible.to_public_accumulated_data(); let mut enqueued_call = self.enqueued_call.to_enqueued_call_data(); - enqueued_call.data.previous_validation_request_array_lengths = PublicValidationRequestArrayLengths::new(previous_kernel.public_inputs.validation_requests); - enqueued_call.data.previous_accumulated_data_array_lengths = if self.phase == PublicKernelPhase.SETUP { - PublicAccumulatedDataArrayLengths::new(previous_kernel.public_inputs.end_non_revertible) + enqueued_call.data.previous_validation_request_array_lengths = PublicValidationRequestArrayLengths::new( + previous_kernel.public_inputs.validation_requests, + ); + enqueued_call.data.previous_accumulated_data_array_lengths = if self.phase + == PublicKernelPhase.SETUP { + PublicAccumulatedDataArrayLengths::new( + previous_kernel.public_inputs.end_non_revertible, + ) } else { PublicAccumulatedDataArrayLengths::new(previous_kernel.public_inputs.end) }; - previous_kernel.public_inputs.end_side_effect_counter = enqueued_call.data.start_side_effect_counter - 1; + previous_kernel.public_inputs.end_side_effect_counter = + enqueued_call.data.start_side_effect_counter - 1; let kernel = PublicKernelMergeCircuitPrivateInputs { previous_kernel, enqueued_call }; kernel.execute() @@ -194,17 +207,17 @@ mod tests { assert_array_eq( public_inputs.validation_requests.public_data_reads, - [prev_reads[0], prev_reads[1], curr_reads[0]] + [prev_reads[0], prev_reads[1], curr_reads[0]], ); assert_array_eq( public_inputs.end_non_revertible.note_hashes, - [prev_note_hashes[0], curr_note_hashes[0], curr_note_hashes[1]] + [prev_note_hashes[0], curr_note_hashes[0], curr_note_hashes[1]], ); assert_array_eq( public_inputs.end_non_revertible.public_call_stack, - [prev_calls[0]] // Public call requests can only be propagated from previous kernel. + [prev_calls[0]], // Public call requests can only be propagated from previous kernel. ); } @@ -242,7 +255,8 @@ mod tests { fn valid_previous_kernel() { for i in 0..ALLOWED_PREVIOUS_CIRCUITS.len() { let mut builder = PublicKernelMergeCircuitPrivateInputsBuilder::new(); - builder.previous_kernel = builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); + builder.previous_kernel = + builder.previous_kernel.in_vk_tree(ALLOWED_PREVIOUS_CIRCUITS[i]); builder.succeeded(); } } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_phase.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_phase.nr index af0421c8d3e..e3de4877531 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_phase.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_phase.nr @@ -5,9 +5,4 @@ struct PublicKernelPhaseEnum { TAIL: u8, } -global PublicKernelPhase = PublicKernelPhaseEnum { - SETUP: 0, - APP_LOGIC: 1, - TEARDOWN: 2, - TAIL: 3, -}; +global PublicKernelPhase = PublicKernelPhaseEnum { SETUP: 0, APP_LOGIC: 1, TEARDOWN: 2, TAIL: 3 }; diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr index 1cadbea00b6..fc4ec877a16 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr @@ -1,29 +1,31 @@ use crate::{ components::{ - previous_kernel_validator::PreviousKernelValidator, - public_tail_output_composer::{OutputHints, PublicTailOutputComposer}, - public_tail_output_validator::PublicTailOutputValidator -}, - public_kernel_phase::PublicKernelPhase + previous_kernel_validator::PreviousKernelValidator, + public_tail_output_composer::{OutputHints, PublicTailOutputComposer}, + public_tail_output_validator::PublicTailOutputValidator, + }, public_kernel_phase::PublicKernelPhase, }; use dep::reset_kernel_lib::{ - NullifierReadRequestHints, NullifierNonExistentReadRequestHints, PublicValidationRequestProcessor, - public_data_read_request_hints::{build_public_data_read_request_hints, PublicDataReadRequestHints}, - TreeLeafReadRequestHint + NullifierReadRequestHints, NullifierNonExistentReadRequestHints, + PublicValidationRequestProcessor, + public_data_read_request_hints::{ + build_public_data_read_request_hints, PublicDataReadRequestHints, + }, TreeLeafReadRequestHint, }; use dep::types::{ - abis::{kernel_circuit_public_inputs::KernelCircuitPublicInputs, public_kernel_data::PublicKernelData}, + abis::{ + kernel_circuit_public_inputs::KernelCircuitPublicInputs, + public_kernel_data::PublicKernelData, + }, constants::{ - L1_TO_L2_MSG_TREE_HEIGHT, MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_PUBLIC_DATA_HINTS, MAX_PUBLIC_DATA_READS_PER_TX, - NOTE_HASH_TREE_HEIGHT, PUBLIC_KERNEL_MERGE_INDEX -}, - data::PublicDataLeafHint, partial_state_reference::PartialStateReference + L1_TO_L2_MSG_TREE_HEIGHT, MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_HINTS, MAX_PUBLIC_DATA_READS_PER_TX, NOTE_HASH_TREE_HEIGHT, + PUBLIC_KERNEL_MERGE_INDEX, + }, data::PublicDataLeafHint, partial_state_reference::PartialStateReference, }; -global ALLOWED_PREVIOUS_CIRCUITS = [ - PUBLIC_KERNEL_MERGE_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = [PUBLIC_KERNEL_MERGE_INDEX]; pub struct PublicKernelTailCircuitPrivateInputs { previous_kernel: PublicKernelData, @@ -36,17 +38,20 @@ pub struct PublicKernelTailCircuitPrivateInputs { } impl PublicKernelTailCircuitPrivateInputs { - unconstrained fn generate_output_and_hints(self) -> (KernelCircuitPublicInputs, OutputHints, PublicDataReadRequestHints) { + unconstrained fn generate_output_and_hints( + self, + ) -> (KernelCircuitPublicInputs, OutputHints, PublicDataReadRequestHints) { let (output, output_hints) = PublicTailOutputComposer::new( self.previous_kernel.public_inputs, self.start_state, - self.public_data_hints - ).finish(); + self.public_data_hints, + ) + .finish(); let public_data_read_request_hints = build_public_data_read_request_hints( self.previous_kernel.public_inputs.validation_requests.public_data_reads, output_hints.public_data_writes, - output_hints.public_data_leaves + output_hints.public_data_leaves, ); (output, output_hints, public_data_read_request_hints) @@ -57,9 +62,8 @@ impl PublicKernelTailCircuitPrivateInputs { previous_kernel_validator.validate_phase(PublicKernelPhase.TAIL); previous_kernel_validator.validate_proof(ALLOWED_PREVIOUS_CIRCUITS); - let (output, output_hints, public_data_read_request_hints) = unsafe { - self.generate_output_and_hints() - }; + let (output, output_hints, public_data_read_request_hints) = + unsafe { self.generate_output_and_hints() }; PublicValidationRequestProcessor::new( self.previous_kernel.public_inputs, @@ -70,87 +74,92 @@ impl PublicKernelTailCircuitPrivateInputs { self.l1_to_l2_msg_read_request_hints, output_hints.public_data_writes, output_hints.public_data_leaves, - public_data_read_request_hints - ).validate(); + public_data_read_request_hints, + ) + .validate(); PublicTailOutputValidator::new( output, self.previous_kernel.public_inputs, self.start_state, output_hints, - self.public_data_hints - ).validate(); + self.public_data_hints, + ) + .validate(); output } } mod tests { - use crate::{public_kernel_tail::PublicKernelTailCircuitPrivateInputs}; + use crate::public_kernel_tail::PublicKernelTailCircuitPrivateInputs; use dep::reset_kernel_lib::{ tests::{ - nullifier_non_existent_read_request_hints_builder::NullifierNonExistentReadRequestHintsBuilder, - nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder - }, - reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus}, - TreeLeafReadRequestHint + nullifier_non_existent_read_request_hints_builder::NullifierNonExistentReadRequestHintsBuilder, + nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder, + }, reset::read_request::{PendingReadHint, ReadRequestState, ReadRequestStatus}, + TreeLeafReadRequestHint, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::KernelCircuitPublicInputs, nullifier::ScopedNullifier, - nullifier_leaf_preimage::NullifierLeafPreimage, - public_data_update_request::PublicDataUpdateRequest - }, - address::AztecAddress, + kernel_circuit_public_inputs::KernelCircuitPublicInputs, nullifier::ScopedNullifier, + nullifier_leaf_preimage::NullifierLeafPreimage, + public_data_update_request::PublicDataUpdateRequest, + }, address::AztecAddress, constants::{ - L1_TO_L2_MSG_TREE_HEIGHT, MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, - MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, - MAX_PUBLIC_DATA_HINTS, NOTE_HASH_SUBTREE_HEIGHT, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, - NULLIFIER_TREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, - PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT, - MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NOTE_HASH_TREE_HEIGHT, PUBLIC_KERNEL_MERGE_INDEX, - BASE_ROLLUP_INDEX - }, - data::{PublicDataLeafHint, PublicDataTreeLeafPreimage}, + L1_TO_L2_MSG_TREE_HEIGHT, MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_PUBLIC_DATA_HINTS, NOTE_HASH_SUBTREE_HEIGHT, + NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, + NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, + PUBLIC_DATA_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, + PUBLIC_DATA_TREE_HEIGHT, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + NOTE_HASH_TREE_HEIGHT, PUBLIC_KERNEL_MERGE_INDEX, BASE_ROLLUP_INDEX, + }, data::{PublicDataLeafHint, PublicDataTreeLeafPreimage}, hash::{compute_siloed_nullifier, silo_note_hash}, tests::{ - fixture_builder::FixtureBuilder, merkle_tree_utils::NonEmptyMerkleTree, - utils::{assert_array_eq, pad_end, swap_items} - }, - traits::is_empty, partial_state_reference::PartialStateReference, - utils::arrays::{array_merge, find_index_hint}, merkle_tree::MembershipWitness + fixture_builder::FixtureBuilder, merkle_tree_utils::NonEmptyMerkleTree, + utils::{assert_array_eq, pad_end, swap_items}, + }, traits::is_empty, partial_state_reference::PartialStateReference, + utils::arrays::{array_merge, find_index_hint}, merkle_tree::MembershipWitness, }; - fn build_note_hash_tree(leaf_preimages: [Field; N]) -> NonEmptyMerkleTree { + fn build_note_hash_tree( + leaf_preimages: [Field; N], + ) -> NonEmptyMerkleTree { NonEmptyMerkleTree::new( pad_end(leaf_preimages, 0), [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT], - [0; NOTE_HASH_SUBTREE_HEIGHT] + [0; NOTE_HASH_SUBTREE_HEIGHT], ) } fn build_nullifier_tree() -> NonEmptyMerkleTree { let mut pre_existing_nullifiers = [NullifierLeafPreimage::empty(); MAX_NULLIFIERS_PER_TX]; - pre_existing_nullifiers[0] = NullifierLeafPreimage { nullifier: 0, next_nullifier: 100, next_index: 1 }; - pre_existing_nullifiers[1] = NullifierLeafPreimage { nullifier: 100, next_nullifier: 0, next_index: 0 }; + pre_existing_nullifiers[0] = + NullifierLeafPreimage { nullifier: 0, next_nullifier: 100, next_index: 1 }; + pre_existing_nullifiers[1] = + NullifierLeafPreimage { nullifier: 100, next_nullifier: 0, next_index: 0 }; NonEmptyMerkleTree::new( pre_existing_nullifiers.map(|preimage: NullifierLeafPreimage| preimage.hash()), [0; NULLIFIER_TREE_HEIGHT], [0; NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT], - [0; NULLIFIER_SUBTREE_HEIGHT] + [0; NULLIFIER_SUBTREE_HEIGHT], ) } - fn build_public_data_tree(leaf_preimages: [PublicDataTreeLeafPreimage; N]) -> NonEmptyMerkleTree { + fn build_public_data_tree( + leaf_preimages: [PublicDataTreeLeafPreimage; N], + ) -> NonEmptyMerkleTree { NonEmptyMerkleTree::new( pad_end( leaf_preimages.map(|preimage: PublicDataTreeLeafPreimage| preimage.hash()), - 0 + 0, ), [0; PUBLIC_DATA_TREE_HEIGHT], [0; PUBLIC_DATA_TREE_HEIGHT - PUBLIC_DATA_SUBTREE_HEIGHT], - [0; PUBLIC_DATA_SUBTREE_HEIGHT] + [0; PUBLIC_DATA_SUBTREE_HEIGHT], ) } @@ -172,7 +181,8 @@ mod tests { pub fn new() -> PublicKernelTailCircuitPrivateInputsBuilder { let previous_kernel = FixtureBuilder::new().in_vk_tree(PUBLIC_KERNEL_MERGE_INDEX); let previous_revertible = FixtureBuilder::new(); - let nullifier_non_existent_read_request_hints_builder = NullifierNonExistentReadRequestHintsBuilder::new(); + let nullifier_non_existent_read_request_hints_builder = + NullifierNonExistentReadRequestHintsBuilder::new(); PublicKernelTailCircuitPrivateInputsBuilder { previous_kernel, @@ -185,7 +195,7 @@ mod tests { note_hash_leaf_preimages: [598589, 714714], public_data_tree: NonEmptyMerkleTree::empty(), public_data_leaf_preimages: pad_end([], PublicDataTreeLeafPreimage::empty()), - start_state: PartialStateReference::empty() + start_state: PartialStateReference::empty(), } } @@ -198,7 +208,9 @@ mod tests { pub fn with_nullifier_tree(&mut self) -> Self { let nullifier_tree = build_nullifier_tree(); - self.nullifier_non_existent_read_request_hints_builder.set_nullifier_tree(nullifier_tree); + self.nullifier_non_existent_read_request_hints_builder.set_nullifier_tree( + nullifier_tree, + ); self.start_state.nullifier_tree.root = nullifier_tree.get_root(); self.previous_kernel.historical_header.state.partial.nullifier_tree.root = 22222; *self @@ -207,12 +219,25 @@ mod tests { pub fn with_public_data_tree(&mut self) -> Self { let public_data_leaf_preimages = [ PublicDataTreeLeafPreimage { slot: 0, value: 0, next_slot: 1111, next_index: 3 }, - PublicDataTreeLeafPreimage { slot: 2222, value: 200, next_slot: 3333, next_index: 2 }, + PublicDataTreeLeafPreimage { + slot: 2222, + value: 200, + next_slot: 3333, + next_index: 2, + }, PublicDataTreeLeafPreimage { slot: 3333, value: 300, next_slot: 0, next_index: 0 }, - PublicDataTreeLeafPreimage { slot: 1111, value: 100, next_slot: 2222, next_index: 1 } + PublicDataTreeLeafPreimage { + slot: 1111, + value: 100, + next_slot: 2222, + next_index: 1, + }, ]; let public_data_tree = build_public_data_tree(public_data_leaf_preimages); - self.public_data_leaf_preimages = pad_end(public_data_leaf_preimages, PublicDataTreeLeafPreimage::empty()); + self.public_data_leaf_preimages = pad_end( + public_data_leaf_preimages, + PublicDataTreeLeafPreimage::empty(), + ); self.public_data_tree = public_data_tree; self.start_state.public_data_tree.root = public_data_tree.get_root(); *self @@ -221,7 +246,7 @@ mod tests { pub fn add_note_hash_read_request(&mut self, leaf_index: u32) { self.previous_kernel.add_note_hash_tree_leaf_read_requests( self.note_hash_leaf_preimages[leaf_index], - leaf_index as Field + leaf_index as Field, ); let sibling_path = self.note_hash_tree.get_sibling_path(leaf_index); self.note_hash_read_request_hints.push(TreeLeafReadRequestHint { sibling_path }); @@ -248,34 +273,40 @@ mod tests { fn set_nullifiers_for_non_existent_read_request_hints(&mut self) { let nullifiers = array_merge( self.previous_kernel.nullifiers.storage, - self.previous_revertible.nullifiers.storage - ).map(|n: ScopedNullifier| n.nullifier); + self.previous_revertible.nullifiers.storage, + ) + .map(|n: ScopedNullifier| n.nullifier); self.nullifier_non_existent_read_request_hints_builder.set_nullifiers(nullifiers); } pub fn add_pending_revertible_nullifier_read_request(&mut self, nullifier_index: u32) { - let read_request_index = self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); + let read_request_index = + self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); self.sync_counters(); let hint_index = self.nullifier_read_request_hints_builder.pending_read_hints.len(); let pending_value_index = nullifier_index + self.previous_kernel.nullifiers.len(); let hint = PendingReadHint { read_request_index, pending_value_index }; self.nullifier_read_request_hints_builder.pending_read_hints.push(hint); - self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; + self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; } pub fn add_pending_non_revertible_nullifier_read_request(&mut self, nullifier_index: u32) { - let read_request_index = self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); + let read_request_index = + self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); self.sync_counters(); let hint_index = self.nullifier_read_request_hints_builder.pending_read_hints.len(); let hint = PendingReadHint { read_request_index, pending_value_index: nullifier_index }; self.nullifier_read_request_hints_builder.pending_read_hints.push(hint); - self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; + self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; } pub fn read_non_existent_nullifier(&mut self, unsiloed_nullifier: Field) { self.previous_kernel.add_non_existent_read_request_for_nullifier(unsiloed_nullifier); self.sync_counters(); - let siloed_nullifier = compute_siloed_nullifier(self.previous_kernel.contract_address, unsiloed_nullifier); + let siloed_nullifier = + compute_siloed_nullifier(self.previous_kernel.contract_address, unsiloed_nullifier); self.nullifier_non_existent_read_request_hints_builder.add_value_read(siloed_nullifier); } @@ -283,20 +314,24 @@ mod tests { let low_leaf_index = unsafe { find_index_hint( self.public_data_leaf_preimages, - |p: PublicDataTreeLeafPreimage| !leaf_slot.lt(p.slot) & (p.next_slot.eq(0) | leaf_slot.lt(p.next_slot)) + |p: PublicDataTreeLeafPreimage| { + !leaf_slot.lt(p.slot) & (p.next_slot.eq(0) | leaf_slot.lt(p.next_slot)) + }, ) }; let preimage = self.public_data_leaf_preimages[low_leaf_index]; let membership_witness = MembershipWitness { leaf_index: low_leaf_index as Field, - sibling_path: self.public_data_tree.get_sibling_path(low_leaf_index) + sibling_path: self.public_data_tree.get_sibling_path(low_leaf_index), }; PublicDataLeafHint { preimage, membership_witness } } - fn generate_public_data_leaf_hints(&mut self) -> [PublicDataLeafHint; MAX_PUBLIC_DATA_HINTS] { + fn generate_public_data_leaf_hints( + &mut self, + ) -> [PublicDataLeafHint; MAX_PUBLIC_DATA_HINTS] { let mut public_data_hints = BoundedVec::new(); let mut unique_slots: BoundedVec = BoundedVec::new(); @@ -331,18 +366,17 @@ mod tests { pub fn execute(&mut self) -> KernelCircuitPublicInputs { let mut previous_kernel = self.previous_kernel.to_public_kernel_data(false); - previous_kernel.public_inputs.end = self.previous_revertible.to_public_accumulated_data(); + previous_kernel.public_inputs.end = + self.previous_revertible.to_public_accumulated_data(); self.set_nullifiers_for_non_existent_read_request_hints(); let public_data_hints = self.generate_public_data_leaf_hints(); - let nullifier_read_request_hints = unsafe { - self.nullifier_read_request_hints_builder.to_hints() - }; + let nullifier_read_request_hints = + unsafe { self.nullifier_read_request_hints_builder.to_hints() }; - let nullifier_non_existent_read_request_hints = unsafe { - self.nullifier_non_existent_read_request_hints_builder.to_hints() - }; + let nullifier_non_existent_read_request_hints = + unsafe { self.nullifier_non_existent_read_request_hints_builder.to_hints() }; let kernel = PublicKernelTailCircuitPrivateInputs { previous_kernel, @@ -351,7 +385,7 @@ mod tests { nullifier_non_existent_read_request_hints, l1_to_l2_msg_read_request_hints: self.l1_to_l2_msg_read_request_hints.storage, public_data_hints, - start_state: self.start_state + start_state: self.start_state, }; kernel.execute() @@ -381,25 +415,36 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_revertible.add_encrypted_log_hash(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_revertible.add_encrypted_log_hash( + prev_encrypted_logs_hash, + prev_encrypted_log_preimages_length, + ); builder.previous_revertible.add_unencrypted_log_hash( prev_unencrypted_logs_hash, - prev_unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length, ); // Logs for the current call stack. let unencrypted_logs_hash = 26; let unencrypted_log_preimages_length = 50; - builder.previous_revertible.add_unencrypted_log_hash(unencrypted_logs_hash, unencrypted_log_preimages_length); + builder.previous_revertible.add_unencrypted_log_hash( + unencrypted_logs_hash, + unencrypted_log_preimages_length, + ); let public_inputs = builder.execute(); - assert_eq(public_inputs.end.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); assert_eq( - public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length + public_inputs.end.encrypted_log_preimages_length, + prev_encrypted_log_preimages_length, + ); + assert_eq( + public_inputs.end.unencrypted_log_preimages_length, + unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length, ); assert_eq( - public_inputs.end.unencrypted_logs_hashes, builder.previous_revertible.unencrypted_logs_hashes.storage + public_inputs.end.unencrypted_logs_hashes, + builder.previous_revertible.unencrypted_logs_hashes.storage, ); } @@ -498,7 +543,8 @@ mod tests { #[test] unconstrained fn public_data_reads_and_writes_succeeds() { - let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); + let mut builder = + PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); builder.previous_kernel.add_public_data_read_request(22, 0); @@ -522,8 +568,16 @@ mod tests { let prev_writes = builder.previous_kernel.public_data_update_requests.storage; // Shuffle the items so that they are not sorted by counter. - swap_items(&mut builder.previous_kernel.public_data_update_requests, 0, 3); - swap_items(&mut builder.previous_kernel.public_data_update_requests, 1, 3); + swap_items( + &mut builder.previous_kernel.public_data_update_requests, + 0, + 3, + ); + swap_items( + &mut builder.previous_kernel.public_data_update_requests, + 1, + 3, + ); swap_items(&mut builder.previous_kernel.public_data_reads, 1, 4); swap_items(&mut builder.previous_kernel.public_data_reads, 0, 3); @@ -531,16 +585,29 @@ mod tests { assert_array_eq( public_inputs.end.public_data_update_requests, [ - PublicDataUpdateRequest { leaf_slot: 3333, new_value: 301, counter: prev_writes[4].counter }, - PublicDataUpdateRequest { leaf_slot: 11, new_value: 500, counter: prev_writes[1].counter }, - PublicDataUpdateRequest { leaf_slot: 22, new_value: 701, counter: prev_writes[3].counter } - ] + PublicDataUpdateRequest { + leaf_slot: 3333, + new_value: 301, + counter: prev_writes[4].counter, + }, + PublicDataUpdateRequest { + leaf_slot: 11, + new_value: 500, + counter: prev_writes[1].counter, + }, + PublicDataUpdateRequest { + leaf_slot: 22, + new_value: 701, + counter: prev_writes[3].counter, + }, + ], ); } #[test(should_fail_with = "value in OverridablePublicDataTreeLeaf does not match read request")] unconstrained fn reading_uninitialized_public_data_non_zero_value_fails() { - let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); + let mut builder = + PublicKernelTailCircuitPrivateInputsBuilder::new().with_public_data_tree(); builder.previous_kernel.add_public_data_read_request(1234, 1); @@ -594,7 +661,7 @@ mod tests { silo_note_hash(non_rev[2], tx_hash, 4), silo_note_hash(rev[2], tx_hash, 5), silo_note_hash(rev[3], tx_hash, 6), - silo_note_hash(rev[4], tx_hash, 7) + silo_note_hash(rev[4], tx_hash, 7), ]; assert_array_eq(public_inputs.end.note_hashes, expected); } @@ -620,7 +687,8 @@ mod tests { let public_inputs = builder.execute(); - let expected = [non_rev[0], rev[0], rev[1], non_rev[1], non_rev[2], rev[2], rev[3], rev[4]].map(|n: ScopedNullifier| n.nullifier.value); + let expected = [non_rev[0], rev[0], rev[1], non_rev[1], non_rev[2], rev[2], rev[3], rev[4]] + .map(|n: ScopedNullifier| n.nullifier.value); assert_array_eq(public_inputs.end.nullifiers, expected); } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-merge-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-merge-simulated/src/main.nr index 8f37b525057..c131d7dda9e 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-merge-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-merge-simulated/src/main.nr @@ -1,6 +1,8 @@ use dep::public_kernel_lib::PublicKernelMergeCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -unconstrained fn main(input: PublicKernelMergeCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { +unconstrained fn main( + input: PublicKernelMergeCircuitPrivateInputs, +) -> pub PublicKernelCircuitPublicInputs { input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr index d387581d4aa..d30846be377 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr @@ -1,6 +1,8 @@ use dep::public_kernel_lib::PublicKernelTailCircuitPrivateInputs; use dep::types::KernelCircuitPublicInputs; -unconstrained fn main(input: PublicKernelTailCircuitPrivateInputs) -> pub KernelCircuitPublicInputs { +unconstrained fn main( + input: PublicKernelTailCircuitPrivateInputs, +) -> pub KernelCircuitPublicInputs { input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr index 7e2624a7fae..ef1eacbc177 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr @@ -15,5 +15,5 @@ pub use public_validation_request_processor::PublicValidationRequestProcessor; pub use reset::{ key_validation_hint::KeyValidationHint, transient_data::{TransientDataIndexHint, verify_squashed_transient_data}, - tree_leaf_read_request::TreeLeafReadRequestHint + tree_leaf_read_request::TreeLeafReadRequestHint, }; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr index 0dba5d72b02..41e52c15b7d 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/note_hash_read_request_reset.nr @@ -1,9 +1,11 @@ // This will be moved to a separate Read Request Reset Circuit. -use crate::reset::read_request::{PendingReadHint, ReadRequestStatus, ReadValueHint, SettledReadHint}; +use crate::reset::read_request::{ + PendingReadHint, ReadRequestStatus, ReadValueHint, SettledReadHint, +}; use dep::types::{ - abis::{note_hash_leaf_preimage::NoteHashLeafPreimage}, + abis::note_hash_leaf_preimage::NoteHashLeafPreimage, constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_TX, NOTE_HASH_TREE_HEIGHT}, - merkle_tree::MembershipWitness + merkle_tree::MembershipWitness, }; pub struct NoteHashSettledReadHint { @@ -31,7 +33,7 @@ impl SettledReadHint for NoteHashSe NoteHashSettledReadHint { read_request_index: read_request_len, membership_witness: MembershipWitness::empty(), - leaf_preimage: NoteHashLeafPreimage::empty() + leaf_preimage: NoteHashLeafPreimage::empty(), } } } @@ -46,16 +48,16 @@ mod tests { use crate::note_hash_read_request_reset::NoteHashSettledReadHint; use crate::reset::read_request::{ get_unverified_read_requests, PendingReadHint, ReadRequestState, ReadRequestStatus, - verify_reset_read_requests + verify_reset_read_requests, }; use dep::types::{ address::AztecAddress, merkle_tree::MembershipWitness, abis::{ - note_hash::{NoteHash, ScopedNoteHash}, note_hash_leaf_preimage::NoteHashLeafPreimage, - read_request::{ReadRequest, ScopedReadRequest} - }, - constants::NOTE_HASH_TREE_HEIGHT, hash::compute_siloed_note_hash, - tests::{merkle_tree_utils::NonEmptyMerkleTree, utils::assert_array_eq}, traits::is_empty_array + note_hash::{NoteHash, ScopedNoteHash}, note_hash_leaf_preimage::NoteHashLeafPreimage, + read_request::{ReadRequest, ScopedReadRequest}, + }, constants::NOTE_HASH_TREE_HEIGHT, hash::compute_siloed_note_hash, + tests::{merkle_tree_utils::NonEmptyMerkleTree, utils::assert_array_eq}, + traits::is_empty_array, }; struct TestBuilder { @@ -73,15 +75,16 @@ mod tests { // Create 4 note hashes. 10 and 11 are settled. 12 and 13 are pending. let note_hashes = [10, 11, 12, 13]; - let siloed_note_hashes = note_hashes.map(|n| compute_siloed_note_hash(contract_address, n)); + let siloed_note_hashes = + note_hashes.map(|n| compute_siloed_note_hash(contract_address, n)); // Create 5 read requests. 0 and 3 are reading settled note hashes. 1, 2 and 4 are reading pending note hashes. let read_requests = [ - ReadRequest { value: note_hashes[1], counter: 11 }.scope(contract_address),// settled - ReadRequest { value: note_hashes[3], counter: 13 }.scope(contract_address),// pending - ReadRequest { value: note_hashes[2], counter: 39 }.scope(contract_address),// pending - ReadRequest { value: note_hashes[0], counter: 46 }.scope(contract_address),// settled - ReadRequest { value: note_hashes[3], counter: 78 }.scope(contract_address)// pending + ReadRequest { value: note_hashes[1], counter: 11 }.scope(contract_address), // settled + ReadRequest { value: note_hashes[3], counter: 13 }.scope(contract_address), // pending + ReadRequest { value: note_hashes[2], counter: 39 }.scope(contract_address), // pending + ReadRequest { value: note_hashes[0], counter: 46 }.scope(contract_address), // settled + ReadRequest { value: note_hashes[3], counter: 78 }.scope(contract_address), // pending ]; let read_request_statuses = [ @@ -89,25 +92,25 @@ mod tests { ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 0 }, ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 1 }, ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 1 }, - ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 2 } + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 2 }, ]; let pending_values = [ NoteHash { value: note_hashes[2], counter: 2 }.scope(contract_address), NoteHash { value: note_hashes[3], counter: 8 }.scope(contract_address), ScopedNoteHash::empty(), - ScopedNoteHash::empty() + ScopedNoteHash::empty(), ]; let pending_read_hints = [ PendingReadHint { read_request_index: 1, pending_value_index: 1 }, PendingReadHint { read_request_index: 2, pending_value_index: 0 }, - PendingReadHint { read_request_index: 4, pending_value_index: 1 } + PendingReadHint { read_request_index: 4, pending_value_index: 1 }, ]; let leaf_preimages = [ NoteHashLeafPreimage { value: siloed_note_hashes[0] }, - NoteHashLeafPreimage { value: siloed_note_hashes[1] } + NoteHashLeafPreimage { value: siloed_note_hashes[1] }, ]; TestBuilder { @@ -116,19 +119,21 @@ mod tests { read_request_statuses, pending_values, pending_read_hints, - leaf_preimages + leaf_preimages, } } } impl TestBuilder { - fn build_tree(self) -> NonEmptyMerkleTree<2, NOTE_HASH_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT - 1, 1> { + fn build_tree( + self, + ) -> NonEmptyMerkleTree<2, NOTE_HASH_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT - 1, 1> { NonEmptyMerkleTree::new( [self.leaf_preimages[0].as_leaf(), self.leaf_preimages[1].as_leaf()], [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - 1], - [0; 1] + [0; 1], ) } @@ -137,28 +142,34 @@ mod tests { let hints = [ NoteHashSettledReadHint { read_request_index: 0, - membership_witness: MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) }, - leaf_preimage: self.leaf_preimages[1] + membership_witness: MembershipWitness { + leaf_index: 1, + sibling_path: tree.get_sibling_path(1), + }, + leaf_preimage: self.leaf_preimages[1], }, NoteHashSettledReadHint { read_request_index: 3, - membership_witness: MembershipWitness { leaf_index: 0, sibling_path: tree.get_sibling_path(0) }, - leaf_preimage: self.leaf_preimages[0] - } + membership_witness: MembershipWitness { + leaf_index: 0, + sibling_path: tree.get_sibling_path(0), + }, + leaf_preimage: self.leaf_preimages[0], + }, ]; let tree_root = tree.get_root(); (hints, tree_root) } - pub unconstrained fn get_unverified_read_requests(self) -> [ScopedReadRequest; READ_REQUEST_LEN] { + pub unconstrained fn get_unverified_read_requests( + self, + ) -> [ScopedReadRequest; READ_REQUEST_LEN] { get_unverified_read_requests(self.read_requests, self.read_request_statuses) } pub fn verify(self) { let (settled_hints, tree_root) = self.get_settled_read_hints(); - let unverified_read_requests = unsafe { - self.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { self.get_unverified_read_requests() }; verify_reset_read_requests( self.read_requests, self.pending_values, @@ -166,7 +177,7 @@ mod tests { self.pending_read_hints, settled_hints, tree_root, - unverified_read_requests + unverified_read_requests, ); } } @@ -175,9 +186,7 @@ mod tests { fn verify_reset_note_hash_read_requests_clears_all_succeeds() { let builder = TestBuilder::new(); - let unverified_read_requests = unsafe { - builder.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { builder.get_unverified_read_requests() }; assert(is_empty_array(unverified_read_requests)); builder.verify(); @@ -191,12 +200,10 @@ mod tests { builder.read_request_statuses[4] = ReadRequestStatus::empty(); let read_requests = builder.read_requests; - let unverified_read_requests = unsafe { - builder.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { builder.get_unverified_read_requests() }; assert_array_eq( unverified_read_requests, - [read_requests[2], read_requests[4]] + [read_requests[2], read_requests[4]], ); builder.verify(); @@ -228,7 +235,8 @@ mod tests { let hint = builder.pending_read_hints[0]; let pending_read = builder.read_requests[hint.read_request_index]; // Tweak the counter of the value to be greater than the read request. - builder.pending_values[hint.pending_value_index].note_hash.counter = pending_read.counter() + 1; + builder.pending_values[hint.pending_value_index].note_hash.counter = + pending_read.counter() + 1; builder.verify(); } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr index 82fe8c04b55..3c6bf8c74f3 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_non_existent_read_request_reset.nr @@ -2,7 +2,10 @@ use crate::reset::non_existent_read_request::NonMembershipHint; use dep::types::{ abis::{nullifier::Nullifier, nullifier_leaf_preimage::NullifierLeafPreimage}, merkle_tree::MembershipWitness, - constants::{MAX_NULLIFIERS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT} + constants::{ + MAX_NULLIFIERS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, + NULLIFIER_TREE_HEIGHT, + }, }; pub struct NullifierNonMembershipHint { diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr index 7c93d97b742..04c6d5a5d36 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/nullifier_read_request_reset.nr @@ -1,9 +1,11 @@ // This will be moved to a separate Read Request Reset Circuit. -use crate::reset::read_request::{PendingReadHint, ReadRequestStatus, ReadValueHint, SettledReadHint}; +use crate::reset::read_request::{ + PendingReadHint, ReadRequestStatus, ReadValueHint, SettledReadHint, +}; use dep::types::{ - abis::{nullifier_leaf_preimage::NullifierLeafPreimage}, + abis::nullifier_leaf_preimage::NullifierLeafPreimage, constants::{MAX_NULLIFIER_READ_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT}, - merkle_tree::MembershipWitness + merkle_tree::MembershipWitness, }; pub struct NullifierSettledReadHint { @@ -31,7 +33,7 @@ impl SettledReadHint for Nullifier NullifierSettledReadHint { read_request_index: read_request_len, membership_witness: MembershipWitness::empty(), - leaf_preimage: NullifierLeafPreimage::empty() + leaf_preimage: NullifierLeafPreimage::empty(), } } } @@ -46,17 +48,17 @@ mod tests { use crate::nullifier_read_request_reset::NullifierSettledReadHint; use crate::reset::read_request::{ get_unverified_read_requests, PendingReadHint, ReadRequestState, ReadRequestStatus, - verify_reset_read_requests + verify_reset_read_requests, }; use dep::types::{ address::AztecAddress, abis::{ - nullifier::{Nullifier, ScopedNullifier}, nullifier_leaf_preimage::NullifierLeafPreimage, - read_request::{ReadRequest, ScopedReadRequest} - }, - constants::NULLIFIER_TREE_HEIGHT, hash::compute_siloed_nullifier, + nullifier::{Nullifier, ScopedNullifier}, nullifier_leaf_preimage::NullifierLeafPreimage, + read_request::{ReadRequest, ScopedReadRequest}, + }, constants::NULLIFIER_TREE_HEIGHT, hash::compute_siloed_nullifier, merkle_tree::MembershipWitness, - tests::{merkle_tree_utils::NonEmptyMerkleTree, utils::assert_array_eq}, traits::is_empty_array + tests::{merkle_tree_utils::NonEmptyMerkleTree, utils::assert_array_eq}, + traits::is_empty_array, }; struct TestBuilder { @@ -73,33 +75,46 @@ mod tests { // Create 4 nullifiers. 10 and 11 are settled. 12 and 13 are pending. let inner_nullifiers = [10, 11, 12, 13]; - let nullifiers = inner_nullifiers.map(|n| compute_siloed_nullifier(contract_address, n)); + let nullifiers = + inner_nullifiers.map(|n| compute_siloed_nullifier(contract_address, n)); // Create 5 read requests. 0 and 3 are reading settled nullifiers. 1, 2 and 4 are reading pending nullifiers. let read_requests = [ - ReadRequest { value: inner_nullifiers[1], counter: 11 }.scope(contract_address),// settled - ReadRequest { value: inner_nullifiers[3], counter: 13 }.scope(contract_address),// pending - ReadRequest { value: inner_nullifiers[2], counter: 39 }.scope(contract_address),// pending - ReadRequest { value: inner_nullifiers[0], counter: 46 }.scope(contract_address),// settled - ReadRequest { value: inner_nullifiers[3], counter: 78 }.scope(contract_address)// pending + ReadRequest { value: inner_nullifiers[1], counter: 11 }.scope(contract_address), // settled + ReadRequest { value: inner_nullifiers[3], counter: 13 }.scope(contract_address), // pending + ReadRequest { value: inner_nullifiers[2], counter: 39 }.scope(contract_address), // pending + ReadRequest { value: inner_nullifiers[0], counter: 46 }.scope(contract_address), // settled + ReadRequest { value: inner_nullifiers[3], counter: 78 }.scope(contract_address), // pending ]; let pending_values = [ - Nullifier { value: inner_nullifiers[2], counter: 2, note_hash: 0 }.scope(contract_address), - Nullifier { value: inner_nullifiers[3], counter: 8, note_hash: 0 }.scope(contract_address), + Nullifier { value: inner_nullifiers[2], counter: 2, note_hash: 0 }.scope( + contract_address, + ), + Nullifier { value: inner_nullifiers[3], counter: 8, note_hash: 0 }.scope( + contract_address, + ), + ScopedNullifier::empty(), ScopedNullifier::empty(), - ScopedNullifier::empty() ]; let pending_read_hints = [ PendingReadHint { read_request_index: 1, pending_value_index: 1 }, PendingReadHint { read_request_index: 2, pending_value_index: 0 }, - PendingReadHint { read_request_index: 4, pending_value_index: 1 } + PendingReadHint { read_request_index: 4, pending_value_index: 1 }, ]; let leaf_preimages = [ - NullifierLeafPreimage { nullifier: nullifiers[0], next_nullifier: nullifiers[1], next_index: 1 }, - NullifierLeafPreimage { nullifier: nullifiers[1], next_nullifier: 0, next_index: 0 } + NullifierLeafPreimage { + nullifier: nullifiers[0], + next_nullifier: nullifiers[1], + next_index: 1, + }, + NullifierLeafPreimage { + nullifier: nullifiers[1], + next_nullifier: 0, + next_index: 0, + }, ]; let read_request_statuses = [ @@ -107,20 +122,28 @@ mod tests { ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 0 }, ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 1 }, ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 1 }, - ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 2 } + ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 2 }, ]; - TestBuilder { read_requests, read_request_statuses, pending_values, pending_read_hints, leaf_preimages } + TestBuilder { + read_requests, + read_request_statuses, + pending_values, + pending_read_hints, + leaf_preimages, + } } } impl TestBuilder { - fn build_tree(self) -> NonEmptyMerkleTree<2, NULLIFIER_TREE_HEIGHT, NULLIFIER_TREE_HEIGHT - 1, 1> { + fn build_tree( + self, + ) -> NonEmptyMerkleTree<2, NULLIFIER_TREE_HEIGHT, NULLIFIER_TREE_HEIGHT - 1, 1> { NonEmptyMerkleTree::new( [self.leaf_preimages[0].hash(), self.leaf_preimages[1].hash()], [0; NULLIFIER_TREE_HEIGHT], [0; NULLIFIER_TREE_HEIGHT - 1], - [0; 1] + [0; 1], ) } @@ -129,28 +152,34 @@ mod tests { let hints = [ NullifierSettledReadHint { read_request_index: 0, - membership_witness: MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) }, - leaf_preimage: self.leaf_preimages[1] + membership_witness: MembershipWitness { + leaf_index: 1, + sibling_path: tree.get_sibling_path(1), + }, + leaf_preimage: self.leaf_preimages[1], }, NullifierSettledReadHint { read_request_index: 3, - membership_witness: MembershipWitness { leaf_index: 0, sibling_path: tree.get_sibling_path(0) }, - leaf_preimage: self.leaf_preimages[0] - } + membership_witness: MembershipWitness { + leaf_index: 0, + sibling_path: tree.get_sibling_path(0), + }, + leaf_preimage: self.leaf_preimages[0], + }, ]; let tree_root = tree.get_root(); (hints, tree_root) } - pub unconstrained fn get_unverified_read_requests(self) -> [ScopedReadRequest; READ_REQUEST_LEN] { + pub unconstrained fn get_unverified_read_requests( + self, + ) -> [ScopedReadRequest; READ_REQUEST_LEN] { get_unverified_read_requests(self.read_requests, self.read_request_statuses) } pub fn verify(self) { let (settled_hints, tree_root) = self.get_settled_read_hints(); - let unverified_read_requests = unsafe { - self.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { self.get_unverified_read_requests() }; verify_reset_read_requests( self.read_requests, self.pending_values, @@ -158,7 +187,7 @@ mod tests { self.pending_read_hints, settled_hints, tree_root, - unverified_read_requests + unverified_read_requests, ); } } @@ -167,9 +196,7 @@ mod tests { fn verify_reset_nullifier_read_requests_clears_all_succeeds() { let builder = TestBuilder::new(); - let unverified_read_requests = unsafe { - builder.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { builder.get_unverified_read_requests() }; assert(is_empty_array(unverified_read_requests)); builder.verify(); @@ -183,12 +210,10 @@ mod tests { builder.read_request_statuses[4] = ReadRequestStatus::empty(); let read_requests = builder.read_requests; - let unverified_read_requests = unsafe { - builder.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { builder.get_unverified_read_requests() }; assert_array_eq( unverified_read_requests, - [read_requests[2], read_requests[4]] + [read_requests[2], read_requests[4]], ); builder.verify(); @@ -220,7 +245,8 @@ mod tests { let hint = builder.pending_read_hints[0]; let pending_read = builder.read_requests[hint.read_request_index]; // Tweak the counter of the value to be greater than the read request. - builder.pending_values[hint.pending_value_index].nullifier.counter = pending_read.counter() + 1; + builder.pending_values[hint.pending_value_index].nullifier.counter = + pending_read.counter() + 1; builder.verify(); } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr index 7674cb15a83..c2a429d7382 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr @@ -2,11 +2,16 @@ use crate::{ note_hash_read_request_reset::NoteHashReadRequestHints, nullifier_read_request_reset::NullifierReadRequestHints, reset::read_request::{get_unverified_read_requests, verify_reset_read_requests}, - reset::key_validation_hint::{get_unverified_key_validation_requests, KeyValidationHint, verify_reset_key_validation_requests} + reset::key_validation_hint::{ + get_unverified_key_validation_requests, KeyValidationHint, + verify_reset_key_validation_requests, + }, }; use dep::types::{ - abis::{note_hash::ScopedNoteHash, nullifier::ScopedNullifier, validation_requests::PrivateValidationRequests}, - constants::{MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX} + abis::{ + note_hash::ScopedNoteHash, nullifier::ScopedNullifier, + validation_requests::PrivateValidationRequests, + }, constants::{MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX}, }; pub struct PrivateValidationRequestProcessor { @@ -21,27 +26,21 @@ pub struct PrivateValidationRequestProcessor PrivateValidationRequestProcessor { +impl PrivateValidationRequestProcessor { pub unconstrained fn compose(self) -> PrivateValidationRequests { let note_hash_read_requests = get_unverified_read_requests( self.validation_requests.note_hash_read_requests, - self.note_hash_read_request_hints.read_request_statuses + self.note_hash_read_request_hints.read_request_statuses, ); let nullifier_read_requests = get_unverified_read_requests( self.validation_requests.nullifier_read_requests, - self.nullifier_read_request_hints.read_request_statuses + self.nullifier_read_request_hints.read_request_statuses, ); let scoped_key_validation_requests_and_generators = get_unverified_key_validation_requests( self.validation_requests.scoped_key_validation_requests_and_generators, - self.key_validation_hints + self.key_validation_hints, ); PrivateValidationRequests { @@ -49,13 +48,15 @@ impl< note_hash_read_requests, nullifier_read_requests, scoped_key_validation_requests_and_generators, - split_counter: Option::some(self.validation_requests_split_counter) + split_counter: Option::some(self.validation_requests_split_counter), } } pub fn validate(self, output: PrivateValidationRequests) { assert_eq( - output.for_rollup, self.validation_requests.for_rollup, "mismatch validation request for rollup" + output.for_rollup, + self.validation_requests.for_rollup, + "mismatch validation request for rollup", ); // note_hash_read_requests @@ -66,7 +67,7 @@ impl< self.note_hash_read_request_hints.pending_read_hints, self.note_hash_read_request_hints.settled_read_hints, self.note_hash_tree_root, - output.note_hash_read_requests + output.note_hash_read_requests, ); // nullifier_read_requests @@ -77,29 +78,35 @@ impl< self.nullifier_read_request_hints.pending_read_hints, self.nullifier_read_request_hints.settled_read_hints, self.nullifier_tree_root, - output.nullifier_read_requests + output.nullifier_read_requests, ); // key_validation_requests if KEY_VALIDATION_REQUESTS == 0 { assert_eq( - output.scoped_key_validation_requests_and_generators, self.validation_requests.scoped_key_validation_requests_and_generators, "mismatch scoped_key_validation_requests_and_generators" + output.scoped_key_validation_requests_and_generators, + self.validation_requests.scoped_key_validation_requests_and_generators, + "mismatch scoped_key_validation_requests_and_generators", ); } else { verify_reset_key_validation_requests( self.validation_requests.scoped_key_validation_requests_and_generators, self.key_validation_hints, - output.scoped_key_validation_requests_and_generators + output.scoped_key_validation_requests_and_generators, ); } // split_counter assert_eq( - output.split_counter.unwrap(), self.validation_requests_split_counter, "mismatch split counter" + output.split_counter.unwrap(), + self.validation_requests_split_counter, + "mismatch split counter", ); if self.validation_requests.split_counter.is_some() { assert_eq( - self.validation_requests.split_counter.unwrap_unchecked(), self.validation_requests_split_counter, "mismatch hinted split counter" + self.validation_requests.split_counter.unwrap_unchecked(), + self.validation_requests_split_counter, + "mismatch hinted split counter", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_data_read_request_hints.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_data_read_request_hints.nr index 817a577127a..e54d5e0cc31 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_data_read_request_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_data_read_request_hints.nr @@ -1,7 +1,7 @@ use crate::reset::{mutable_data_read_request::ReadIndexHint, read_request::ReadRequestStatus}; use dep::types::{ abis::{public_data_read::PublicDataRead, public_data_write::OverridablePublicDataWrite}, - data::OverridablePublicDataTreeLeaf, utils::arrays::find_index_hint + data::OverridablePublicDataTreeLeaf, utils::arrays::find_index_hint, }; pub struct PublicDataReadRequestHints { @@ -13,7 +13,7 @@ pub struct PublicDataReadRequestHints { pub unconstrained fn build_public_data_read_request_hints( reads: [PublicDataRead; NUM_READS], writes: [OverridablePublicDataWrite; NUM_WRITES], - leaf_data: [OverridablePublicDataTreeLeaf; NUM_LEAVES] + leaf_data: [OverridablePublicDataTreeLeaf; NUM_LEAVES], ) -> PublicDataReadRequestHints { let mut read_request_statuses = [ReadRequestStatus::empty(); NUM_READS]; let mut pending_read_hints = [ReadIndexHint::nada(NUM_READS); NUM_READS]; @@ -25,21 +25,28 @@ pub unconstrained fn build_public_data_read_request_hints w.counter()) & ((read.counter < w.override_counter) | (w.override_counter == 0)) + |w: OverridablePublicDataWrite| { + (w.inner().leaf_slot == read.leaf_slot) + & (read.counter > w.counter()) + & ((read.counter < w.override_counter) | (w.override_counter == 0)) + }, ); if write_index != writes.len() { - pending_read_hints[num_pending_reads] = ReadIndexHint { read_request_index: i, value_index: write_index }; + pending_read_hints[num_pending_reads] = + ReadIndexHint { read_request_index: i, value_index: write_index }; read_request_statuses[i] = ReadRequestStatus::pending(num_pending_reads); num_pending_reads += 1; } else { let leaf_data_index = find_index_hint( leaf_data, - |d: OverridablePublicDataTreeLeaf| d.leaf.slot == read.leaf_slot + |d: OverridablePublicDataTreeLeaf| d.leaf.slot == read.leaf_slot, ); assert( - leaf_data_index != leaf_data.len(), "cannot find a public data leaf or a pending write for the read request" + leaf_data_index != leaf_data.len(), + "cannot find a public data leaf or a pending write for the read request", ); - leaf_data_read_hints[num_leaf_data_reads] = ReadIndexHint { read_request_index: i, value_index: leaf_data_index }; + leaf_data_read_hints[num_leaf_data_reads] = + ReadIndexHint { read_request_index: i, value_index: leaf_data_index }; read_request_statuses[i] = ReadRequestStatus::settled(num_leaf_data_reads); num_leaf_data_reads += 1; } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_validation_request_processor.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_validation_request_processor.nr index 6c843db2760..cb0a6534026 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_validation_request_processor.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/public_validation_request_processor.nr @@ -1,28 +1,28 @@ use crate::{ reset::{ - non_existent_read_request::reset_non_existent_read_requests, - mutable_data_read_request::reset_mutable_data_read_requests, - read_request::verify_reset_read_requests, - tree_leaf_read_request::{TreeLeafReadRequestHint, validate_tree_leaf_read_requests} -}, - nullifier_read_request_reset::NullifierReadRequestHints, + non_existent_read_request::reset_non_existent_read_requests, + mutable_data_read_request::reset_mutable_data_read_requests, + read_request::verify_reset_read_requests, + tree_leaf_read_request::{TreeLeafReadRequestHint, validate_tree_leaf_read_requests}, + }, nullifier_read_request_reset::NullifierReadRequestHints, nullifier_non_existent_read_request_reset::NullifierNonExistentReadRequestHints, - public_data_read_request_hints::PublicDataReadRequestHints + public_data_read_request_hints::PublicDataReadRequestHints, }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, nullifier::Nullifier, - public_data_write::OverridablePublicDataWrite, read_request::ScopedReadRequest, - validation_requests::PublicValidationRequests -}, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, nullifier::Nullifier, + public_data_write::OverridablePublicDataWrite, read_request::ScopedReadRequest, + validation_requests::PublicValidationRequests, + }, constants::{ - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, L1_TO_L2_MSG_TREE_HEIGHT, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIERS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, - NOTE_HASH_TREE_HEIGHT -}, - data::OverridablePublicDataTreeLeaf, hash::compute_siloed_nullifier, + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, L1_TO_L2_MSG_TREE_HEIGHT, + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIERS_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NOTE_HASH_TREE_HEIGHT, + }, data::OverridablePublicDataTreeLeaf, hash::compute_siloed_nullifier, partial_state_reference::PartialStateReference, traits::is_empty, - utils::arrays::{array_to_bounded_vec, assert_combined_array, assert_sorted_array, combine_arrays} + utils::arrays::{ + array_to_bounded_vec, assert_combined_array, assert_sorted_array, combine_arrays, + }, }; pub struct PublicValidationRequestProcessor { @@ -50,17 +50,16 @@ impl PublicVal l1_to_l2_msg_read_request_hints: [TreeLeafReadRequestHint; MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX], pending_public_data_writes: [OverridablePublicDataWrite; NUN_PUBLIC_DATA_WRITES], public_data_leaves: [OverridablePublicDataTreeLeaf; NUM_PUBLIC_DATA_LEAVES], - public_data_read_request_hints: PublicDataReadRequestHints + public_data_read_request_hints: PublicDataReadRequestHints, ) -> Self { let non_revertible_nullifiers = public_inputs.end_non_revertible.nullifiers; let revertible_nullifiers = public_inputs.end.nullifiers; - let pending_nullifiers = unsafe { - combine_arrays(non_revertible_nullifiers, revertible_nullifiers) - }; + let pending_nullifiers = + unsafe { combine_arrays(non_revertible_nullifiers, revertible_nullifiers) }; assert_combined_array( non_revertible_nullifiers, revertible_nullifiers, - pending_nullifiers + pending_nullifiers, ); PublicValidationRequestProcessor { @@ -72,10 +71,15 @@ impl PublicVal nullifier_non_existent_read_request_hints, nullifier_tree_root: start_state.nullifier_tree.root, l1_to_l2_msg_read_request_hints, - l1_to_l2_msg_tree_root: public_inputs.constants.historical_header.state.l1_to_l2_message_tree.root, + l1_to_l2_msg_tree_root: public_inputs + .constants + .historical_header + .state + .l1_to_l2_message_tree + .root, pending_public_data_writes, public_data_leaves, - public_data_read_request_hints + public_data_read_request_hints, } } @@ -91,14 +95,15 @@ impl PublicVal validate_tree_leaf_read_requests( self.validation_requests.note_hash_read_requests, self.note_hash_read_request_hints, - self.note_hash_tree_root + self.note_hash_tree_root, ); } fn validate_nullifier_read_requests(self) { let requests = self.validation_requests.nullifier_read_requests; let hints = self.nullifier_read_request_hints; - let unverified_nullifier_read_requests = [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX]; // All nullifier read requests must be verified. + let unverified_nullifier_read_requests = + [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX]; // All nullifier read requests must be verified. verify_reset_read_requests( requests, self.pending_nullifiers, @@ -106,7 +111,7 @@ impl PublicVal hints.pending_read_hints, hints.settled_read_hints, self.nullifier_tree_root, - unverified_nullifier_read_requests + unverified_nullifier_read_requests, ); } @@ -117,7 +122,8 @@ impl PublicVal for i in 0..read_requests.len() { let read_request = read_requests[i]; if !is_empty(read_request) { - read_requests[i].read_request.value = compute_siloed_nullifier(read_request.contract_address, read_request.value()); + read_requests[i].read_request.value = + compute_siloed_nullifier(read_request.contract_address, read_request.value()); } } @@ -127,7 +133,7 @@ impl PublicVal self.pending_nullifiers, hints.sorted_pending_values, hints.sorted_pending_value_index_hints, - |a: Nullifier, b: Nullifier| a.value.lt(b.value) + |a: Nullifier, b: Nullifier| a.value.lt(b.value), ); let sorted_pending_nullifiers = array_to_bounded_vec(hints.sorted_pending_values); @@ -136,7 +142,7 @@ impl PublicVal hints.non_membership_hints, self.nullifier_tree_root, sorted_pending_nullifiers, - hints.next_pending_value_indices + hints.next_pending_value_indices, ); } @@ -144,7 +150,7 @@ impl PublicVal validate_tree_leaf_read_requests( self.validation_requests.l1_to_l2_msg_read_requests, self.l1_to_l2_msg_read_request_hints, - self.l1_to_l2_msg_tree_root + self.l1_to_l2_msg_tree_root, ); } @@ -157,7 +163,7 @@ impl PublicVal self.pending_public_data_writes, self.public_data_leaves, hints.pending_read_hints, - hints.leaf_data_read_hints + hints.leaf_data_read_hints, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/key_validation_hint.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/key_validation_hint.nr index 0ead614801d..167c6b97803 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/key_validation_hint.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/key_validation_hint.nr @@ -1,12 +1,12 @@ use dep::types::{ - traits::Empty, abis::{validation_requests::ScopedKeyValidationRequestAndGenerator}, scalar::Scalar, - hash::poseidon2_hash_with_separator + traits::Empty, abis::validation_requests::ScopedKeyValidationRequestAndGenerator, + scalar::Scalar, hash::poseidon2_hash_with_separator, }; use std::embedded_curve_ops::fixed_base_scalar_mul as derive_public_key; pub struct KeyValidationHint { - sk_m: Scalar, - request_index: u32, + sk_m: Scalar, + request_index: u32, } impl Empty for KeyValidationHint { @@ -27,7 +27,10 @@ impl KeyValidationHint { } } -fn verify_key_validation_request(scoped_request: ScopedKeyValidationRequestAndGenerator, sk_m: Scalar) { +fn verify_key_validation_request( + scoped_request: ScopedKeyValidationRequestAndGenerator, + sk_m: Scalar, +) { let contract_address = scoped_request.contract_address; let request_and_generator = scoped_request.request; let request = request_and_generator.request; @@ -35,17 +38,27 @@ fn verify_key_validation_request(scoped_request: ScopedKeyValidationRequestAndGe // First we check that derived public key matches master public key from request. let pk_m = derive_public_key(sk_m); - assert_eq(pk_m, request.pk_m, "Failed to derive matching master public key from the secret key."); + assert_eq( + pk_m, + request.pk_m, + "Failed to derive matching master public key from the secret key.", + ); // Then we check that siloing the master secret key with the contract address gives the app secret key. let sk_app = poseidon2_hash_with_separator( [sk_m.hi, sk_m.lo, contract_address.to_field()], - sk_app_generator + sk_app_generator, + ); + assert_eq( + sk_app, + request.sk_app, + "Failed to derive matching app secret key from the secret key.", ); - assert_eq(sk_app, request.sk_app, "Failed to derive matching app secret key from the secret key."); } -unconstrained fn get_hint_indexes(hints: [KeyValidationHint; NUM_HINTS]) -> [u32; REQUEST_LEN] { +unconstrained fn get_hint_indexes( + hints: [KeyValidationHint; NUM_HINTS], +) -> [u32; REQUEST_LEN] { let mut hint_indexes = [NUM_HINTS; REQUEST_LEN]; for i in 0..NUM_HINTS { let hint = hints[i]; @@ -59,7 +72,7 @@ unconstrained fn get_hint_indexes(hint pub fn verify_reset_key_validation_requests( key_validation_requests: [ScopedKeyValidationRequestAndGenerator; REQUEST_LEN], hints: [KeyValidationHint; NUM_HINTS], - unverified_requests: [ScopedKeyValidationRequestAndGenerator; REQUEST_LEN] + unverified_requests: [ScopedKeyValidationRequestAndGenerator; REQUEST_LEN], ) { for i in 0..NUM_HINTS { let hint = hints[i]; @@ -71,9 +84,7 @@ pub fn verify_reset_key_validation_requests( key_validation_requests: [ScopedKeyValidationRequestAndGenerator; REQUEST_LEN], - hints: [KeyValidationHint; NUM_HINTS] + hints: [KeyValidationHint; NUM_HINTS], ) -> [ScopedKeyValidationRequestAndGenerator; REQUEST_LEN] { let mut should_propagate = [true; REQUEST_LEN]; for i in 0..NUM_HINTS { diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/mutable_data_read_request.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/mutable_data_read_request.nr index a88f33b5de3..2b7b3bcdef6 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/mutable_data_read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/mutable_data_read_request.nr @@ -1,5 +1,5 @@ -use crate::reset::{read_request::{ReadRequestState, ReadRequestStatus}}; -use dep::types::{abis::side_effect::{Ordered, Overridable, Readable}}; +use crate::reset::read_request::{ReadRequestState, ReadRequestStatus}; +use dep::types::abis::side_effect::{Ordered, Overridable, Readable}; pub struct ReadIndexHint { read_request_index: u32, @@ -15,8 +15,12 @@ impl ReadIndexHint { fn validate_pending_read_requests( read_requests: [R; READ_REQUEST_LEN], pending_values: [V; PENDING_VALUE_LEN], - index_hints: [ReadIndexHint; NUM_HINTS] -) where R: Ordered, V: Readable + Ordered + Overridable { + index_hints: [ReadIndexHint; NUM_HINTS], +) +where + R: Ordered, + V: Readable + Ordered + Overridable, +{ for i in 0..index_hints.len() { let index_hint = index_hints[i]; let read_request_index = index_hint.read_request_index; @@ -25,11 +29,13 @@ fn validate_pending_read_requests pending_value.counter(), "Read request counter must be greater than the counter of the data write" + read_request.counter() > pending_value.counter(), + "Read request counter must be greater than the counter of the data write", ); assert( (read_request.counter() < pending_value.override_counter()) - | (pending_value.override_counter() == 0), "Read request counter must be less than the counter of the next data write" + | (pending_value.override_counter() == 0), + "Read request counter must be less than the counter of the next data write", ); } } @@ -38,8 +44,12 @@ fn validate_pending_read_requests( read_requests: [R; READ_REQUEST_LEN], leaf_data: [L; LEAF_DATA_LEN], - index_hints: [ReadIndexHint; NUM_HINTS] -) where R: Ordered, L: Readable + Overridable { + index_hints: [ReadIndexHint; NUM_HINTS], +) +where + R: Ordered, + L: Readable + Overridable, +{ for i in 0..index_hints.len() { let index_hint = index_hints[i]; let read_request_index = index_hint.read_request_index; @@ -48,7 +58,8 @@ fn validate_leaf_data_read_requests( +pub fn reset_mutable_data_read_requests( read_requests: [R; READ_REQUEST_LEN], read_request_statuses: [ReadRequestStatus; READ_REQUEST_LEN], pending_values: [V; PENDING_VALUE_LEN], leaf_data: [L; NUM_LEAF_DATA_HINTS], pending_read_hints: [ReadIndexHint; NUM_PENDING_READS], - leaf_data_read_hints: [ReadIndexHint; NUM_LEAF_DATA_READS] -) where R: Ordered, V: Readable + Ordered + Overridable, L: Readable + Overridable { + leaf_data_read_hints: [ReadIndexHint; NUM_LEAF_DATA_READS], +) +where + R: Ordered, + V: Readable + Ordered + Overridable, + L: Readable + Overridable, +{ validate_pending_read_requests(read_requests, pending_values, pending_read_hints); validate_leaf_data_read_requests(read_requests, leaf_data, leaf_data_read_hints); @@ -102,24 +114,22 @@ pub fn reset_mutable_data_read_requests< read_requests, read_request_statuses, pending_read_hints, - leaf_data_read_hints + leaf_data_read_hints, ); } mod tests { use crate::reset::{ mutable_data_read_request::{ - ensure_all_read_requests_are_verified, ReadIndexHint, reset_mutable_data_read_requests, - validate_pending_read_requests, validate_leaf_data_read_requests - }, - read_request::{ReadRequestState, ReadRequestStatus} + ensure_all_read_requests_are_verified, ReadIndexHint, reset_mutable_data_read_requests, + validate_pending_read_requests, validate_leaf_data_read_requests, + }, read_request::{ReadRequestState, ReadRequestStatus}, }; use dep::types::{ abis::{ - public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, - public_data_write::OverridablePublicDataWrite, side_effect::{Overridable, Readable} - }, - tests::utils::pad_end, traits::Empty + public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, + public_data_write::OverridablePublicDataWrite, side_effect::{Overridable, Readable}, + }, tests::utils::pad_end, traits::Empty, }; struct TestLeafData { @@ -142,7 +152,11 @@ mod tests { impl Readable for TestLeafData { fn assert_match_read_request(self, read_request: PublicDataRead) { - assert_eq(self.leaf_index, read_request.leaf_slot, "leaf_index in TestLeafData does not match"); + assert_eq( + self.leaf_index, + read_request.leaf_slot, + "leaf_index in TestLeafData does not match", + ); assert_eq(self.value, read_request.value, "value in TestLeafData does not match"); } } @@ -168,25 +182,53 @@ mod tests { let leaf_data = pad_end( [ - TestLeafData { leaf_index: 44, value: 0, override_counter: 40 }, - TestLeafData { leaf_index: 77, value: 700, override_counter: 0 }, - TestLeafData { leaf_index: 11, value: 0, override_counter: 20 }, - TestLeafData { leaf_index: 33, value: 300, override_counter: 30 }, - TestLeafData { leaf_index: 66, value: 600, override_counter: 0 }, - TestLeafData { leaf_index: 22, value: 200, override_counter: 10 }, - TestLeafData { leaf_index: 55, value: 500, override_counter: 0 } - ], - TestLeafData::empty() + TestLeafData { leaf_index: 44, value: 0, override_counter: 40 }, + TestLeafData { leaf_index: 77, value: 700, override_counter: 0 }, + TestLeafData { leaf_index: 11, value: 0, override_counter: 20 }, + TestLeafData { leaf_index: 33, value: 300, override_counter: 30 }, + TestLeafData { leaf_index: 66, value: 600, override_counter: 0 }, + TestLeafData { leaf_index: 22, value: 200, override_counter: 10 }, + TestLeafData { leaf_index: 55, value: 500, override_counter: 0 }, + ], + TestLeafData::empty(), ); let data_writes = pad_end( [ - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 22, new_value: 201, counter: 10 }, override_counter: 40 }, - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 11, new_value: 100, counter: 20 }, override_counter: 0 }, - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 33, new_value: 301, counter: 30 }, override_counter: 0 }, - OverridablePublicDataWrite { write: PublicDataUpdateRequest { leaf_slot: 22, new_value: 202, counter: 40 }, override_counter: 0 } - ], - OverridablePublicDataWrite::empty() + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 22, + new_value: 201, + counter: 10, + }, + override_counter: 40, + }, + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 11, + new_value: 100, + counter: 20, + }, + override_counter: 0, + }, + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 33, + new_value: 301, + counter: 30, + }, + override_counter: 0, + }, + OverridablePublicDataWrite { + write: PublicDataUpdateRequest { + leaf_slot: 22, + new_value: 202, + counter: 40, + }, + override_counter: 0, + }, + ], + OverridablePublicDataWrite::empty(), ); let pending_read_hints = pad_end([], ReadIndexHint::nada(READ_REQUEST_LEN)); @@ -202,7 +244,7 @@ mod tests { leaf_data_read_hints, num_pending_reads: 0, num_leaf_data_reads: 0, - counter: 50 + counter: 50, } } @@ -212,10 +254,12 @@ mod tests { self.read_requests[read_request_index] = PublicDataRead { leaf_slot: write.leaf_slot, value: write.new_value, - counter: self.counter + counter: self.counter, }; - self.pending_read_hints[self.num_pending_reads] = ReadIndexHint { read_request_index, value_index: data_write_index }; - self.read_request_statuses[read_request_index] = ReadRequestStatus::pending(self.num_pending_reads); + self.pending_read_hints[self.num_pending_reads] = + ReadIndexHint { read_request_index, value_index: data_write_index }; + self.read_request_statuses[read_request_index] = + ReadRequestStatus::pending(self.num_pending_reads); self.num_pending_reads += 1; self.counter += 1; } @@ -226,20 +270,30 @@ mod tests { self.read_requests[read_request_index] = PublicDataRead { leaf_slot: data_hint.leaf_index, value: data_hint.value, - counter: self.counter + counter: self.counter, }; - self.leaf_data_read_hints[self.num_leaf_data_reads] = ReadIndexHint { read_request_index, value_index: data_hint_index }; - self.read_request_statuses[read_request_index] = ReadRequestStatus::settled(self.num_leaf_data_reads); + self.leaf_data_read_hints[self.num_leaf_data_reads] = + ReadIndexHint { read_request_index, value_index: data_hint_index }; + self.read_request_statuses[read_request_index] = + ReadRequestStatus::settled(self.num_leaf_data_reads); self.num_leaf_data_reads += 1; self.counter += 1; } pub fn validate_pending_read_requests(self) { - validate_pending_read_requests(self.read_requests, self.data_writes, self.pending_read_hints); + validate_pending_read_requests( + self.read_requests, + self.data_writes, + self.pending_read_hints, + ); } pub fn validate_leaf_data_read_requests(self) { - validate_leaf_data_read_requests(self.read_requests, self.leaf_data, self.leaf_data_read_hints) + validate_leaf_data_read_requests( + self.read_requests, + self.leaf_data, + self.leaf_data_read_hints, + ) } pub fn ensure_all_read_requests_are_verified(self) { @@ -247,7 +301,7 @@ mod tests { self.read_requests, self.read_request_statuses, self.pending_read_hints, - self.leaf_data_read_hints + self.leaf_data_read_hints, ) } @@ -258,7 +312,7 @@ mod tests { self.data_writes, self.leaf_data, self.pending_read_hints, - self.leaf_data_read_hints + self.leaf_data_read_hints, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr index c080f8d910a..55aab06e6fb 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/non_existent_read_request.nr @@ -1,10 +1,13 @@ use dep::types::{ abis::{side_effect::OrderedValue, read_request::ScopedReadRequest}, merkle_tree::{assert_check_non_membership, IndexedTreeLeafPreimage, MembershipWitness}, - traits::is_empty + traits::is_empty, }; -trait NonMembershipHint where LEAF_PREIMAGE: IndexedTreeLeafPreimage { +trait NonMembershipHint +where + LEAF_PREIMAGE: IndexedTreeLeafPreimage, +{ fn low_leaf_preimage(self) -> LEAF_PREIMAGE; fn membership_witness(self) -> MembershipWitness; } @@ -12,10 +15,14 @@ trait NonMembershipHint where LEAF_PREIMAGE fn check_no_matching_pending_value( read_request: ScopedReadRequest, sorted_pending_values: BoundedVec, - next_value_index: u32 -) -> bool where T: OrderedValue { + next_value_index: u32, +) -> bool +where + T: OrderedValue, +{ if next_value_index == sorted_pending_values.len() { - let highest_value = sorted_pending_values.get_unchecked(sorted_pending_values.len() - 1).value(); + let highest_value = + sorted_pending_values.get_unchecked(sorted_pending_values.len() - 1).value(); highest_value.lt(read_request.value()) } else { let next_value = sorted_pending_values.get_unchecked(next_value_index).value(); @@ -33,8 +40,11 @@ fn check_no_matching_pending_value( fn check_is_read_before_pending_value( read_request: ScopedReadRequest, sorted_pending_values: BoundedVec, - next_value_index: u32 -) -> bool where T: OrderedValue { + next_value_index: u32, +) -> bool +where + T: OrderedValue, +{ if next_value_index == sorted_pending_values.len() { false } else { @@ -56,11 +66,13 @@ pub fn reset_non_existent_read_requests, - next_pending_value_indices: [u32; N] -) where + next_pending_value_indices: [u32; N], +) +where T: OrderedValue, NON_MEMBERSHIP_HINT: NonMembershipHint, - LEAF_PREIMAGE: IndexedTreeLeafPreimage { + LEAF_PREIMAGE: IndexedTreeLeafPreimage, +{ for i in 0..siloed_read_requests.len() { let read_request = siloed_read_requests[i]; if !is_empty(read_request) { @@ -70,28 +82,39 @@ pub fn reset_non_existent_read_requests(leaf_indices: [Field; N]) -> ([TestNonMembershipHint; N], Field) { + fn get_non_membership_hints( + leaf_indices: [Field; N], + ) -> ([TestNonMembershipHint; N], Field) { let tree = build_tree(); - let hints = leaf_indices.map( - |leaf_index| TestNonMembershipHint { + let hints = leaf_indices.map(|leaf_index| { + TestNonMembershipHint { low_leaf_preimage: leaf_preimages[leaf_index], - membership_witness: MembershipWitness { leaf_index, sibling_path: tree.get_sibling_path(leaf_index as u32) } + membership_witness: MembershipWitness { + leaf_index, + sibling_path: tree.get_sibling_path(leaf_index as u32), + }, } - ); + }); let tree_root = tree.get_root(); (hints, tree_root) } @@ -192,7 +220,7 @@ mod tests { let read_requests = [ ReadRequest { value: 11, counter: 50 }.scope(AztecAddress::zero()), ReadRequest { value: 22, counter: 51 }.scope(AztecAddress::zero()), - ReadRequest { value: 6, counter: 52 }.scope(AztecAddress::zero()) + ReadRequest { value: 6, counter: 52 }.scope(AztecAddress::zero()), ]; let (non_membership_hints, root) = get_non_membership_hints([3, 1, 0]); let next_pending_value_indices = [1, 2, 1]; @@ -201,7 +229,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -209,7 +237,7 @@ mod tests { fn test_reset_non_existent_read_requests_less_than_min() { let read_requests = [ ReadRequest { value: 3, counter: 50 }.scope(AztecAddress::zero()), - ReadRequest { value: 2, counter: 51 }.scope(AztecAddress::zero()) + ReadRequest { value: 2, counter: 51 }.scope(AztecAddress::zero()), ]; let (non_membership_hints, root) = get_non_membership_hints([0, 0]); let next_pending_value_indices = [0, 0]; @@ -218,7 +246,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -226,7 +254,7 @@ mod tests { fn test_reset_non_existent_read_requests_greater_than_max() { let read_requests = [ ReadRequest { value: 35, counter: 50 }.scope(AztecAddress::zero()), - ReadRequest { value: 31, counter: 51 }.scope(AztecAddress::zero()) + ReadRequest { value: 31, counter: 51 }.scope(AztecAddress::zero()), ]; let (non_membership_hints, root) = get_non_membership_hints([2, 2]); let next_pending_value_indices = [3, 3]; @@ -235,7 +263,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -243,7 +271,7 @@ mod tests { fn test_reset_non_existent_read_requests_read_before_pending_emitted() { let read_requests = [ ReadRequest { value: 25, counter: 10 }.scope(AztecAddress::zero()), - ReadRequest { value: 5, counter: 11 }.scope(AztecAddress::zero()) + ReadRequest { value: 5, counter: 11 }.scope(AztecAddress::zero()), ]; let (non_membership_hints, root) = get_non_membership_hints([1, 0]); let next_pending_value_indices = [2, 0]; @@ -252,7 +280,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -268,7 +296,7 @@ mod tests { [hint], root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -282,7 +310,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -296,7 +324,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -310,7 +338,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -324,7 +352,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -338,7 +366,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } @@ -352,7 +380,7 @@ mod tests { non_membership_hints, root, sorted_pending_values, - next_pending_value_indices + next_pending_value_indices, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/read_request.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/read_request.nr index 157615b076f..4b2d07b93f7 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/read_request.nr @@ -1,7 +1,7 @@ // This will be moved to a separate Read Request Reset Circuit. use dep::types::{ abis::{read_request::ScopedReadRequest, side_effect::Readable}, - merkle_tree::{assert_check_membership, LeafPreimage, MembershipWitness}, traits::Empty + merkle_tree::{assert_check_membership, LeafPreimage, MembershipWitness}, traits::Empty, }; pub struct ReadRequestStateEnum { @@ -10,11 +10,7 @@ pub struct ReadRequestStateEnum { SETTLED: u8, } -global ReadRequestState = ReadRequestStateEnum { - NADA: 0, - PENDING: 1, - SETTLED: 2, -}; +global ReadRequestState = ReadRequestStateEnum { NADA: 0, PENDING: 1, SETTLED: 2 }; pub struct ReadRequestStatus { state: u8, @@ -58,7 +54,10 @@ impl PendingReadHint { } } -trait SettledReadHint where LEAF_PREIMAGE: LeafPreimage { +trait SettledReadHint +where + LEAF_PREIMAGE: LeafPreimage, +{ fn membership_witness(self) -> MembershipWitness; fn leaf_preimage(self) -> LEAF_PREIMAGE; fn nada(read_request_len: u32) -> Self; @@ -71,8 +70,11 @@ trait SettledReadHint where LEAF_PREIMAGE: fn validate_pending_read_requests( read_requests: [ScopedReadRequest; READ_REQUEST_LEN], pending_values: [T; PENDING_VALUE_LEN], - hints: [PendingReadHint; NUM_PENDING_READS] -) where T: Readable { + hints: [PendingReadHint; NUM_PENDING_READS], +) +where + T: Readable, +{ for i in 0..NUM_PENDING_READS { let hint = hints[i]; let read_request_index = hint.read_request_index; @@ -86,19 +88,15 @@ fn validate_pending_read_requests( +fn validate_settled_read_requests( read_requests: [ScopedReadRequest; READ_REQUEST_LEN], hints: [H; NUM_SETTLED_READS], - tree_root: Field -) where + tree_root: Field, +) +where H: SettledReadHint + ReadValueHint, - LEAF_PREIMAGE: LeafPreimage + Readable { + LEAF_PREIMAGE: LeafPreimage + Readable, +{ for i in 0..NUM_SETTLED_READS { let hint = hints[i]; let read_request_index = hint.read_request_index(); @@ -119,50 +117,53 @@ fn verify_propagated_read_requests( +pub fn verify_reset_read_requests( read_requests: [ScopedReadRequest; READ_REQUEST_LEN], pending_values: [P; PENDING_VALUE_LEN], read_request_statuses: [ReadRequestStatus; READ_REQUEST_LEN], pending_read_hints: [PendingReadHint; NUM_PENDING_READS], settled_read_hints: [H; NUM_SETTLED_READS], tree_root: Field, - propagated_read_requests: [ScopedReadRequest; READ_REQUEST_LEN] -) where + propagated_read_requests: [ScopedReadRequest; READ_REQUEST_LEN], +) +where P: Readable, H: SettledReadHint + ReadValueHint, - LEAF_PREIMAGE: LeafPreimage + Readable { + LEAF_PREIMAGE: LeafPreimage + Readable, +{ validate_pending_read_requests(read_requests, pending_values, pending_read_hints); validate_settled_read_requests(read_requests, settled_read_hints, tree_root); @@ -172,13 +173,13 @@ pub fn verify_reset_read_requests< read_request_statuses, pending_read_hints, settled_read_hints, - propagated_read_requests + propagated_read_requests, ); } pub unconstrained fn get_unverified_read_requests( read_requests: [ScopedReadRequest; READ_REQUEST_LEN], - read_request_statuses: [ReadRequestStatus; READ_REQUEST_LEN] + read_request_statuses: [ReadRequestStatus; READ_REQUEST_LEN], ) -> [ScopedReadRequest; READ_REQUEST_LEN] { let mut propagated_read_requests = BoundedVec::new(); for i in 0..READ_REQUEST_LEN { @@ -193,15 +194,15 @@ pub unconstrained fn get_unverified_read_requests( mod tests { use crate::reset::read_request::{ PendingReadHint, ReadRequestState, ReadRequestStatus, ReadValueHint, SettledReadHint, - get_unverified_read_requests, validate_pending_read_requests, validate_settled_read_requests, - verify_reset_read_requests + get_unverified_read_requests, validate_pending_read_requests, + validate_settled_read_requests, verify_reset_read_requests, }; use dep::types::{ address::AztecAddress, abis::{read_request::{ReadRequest, ScopedReadRequest}, side_effect::Readable}, merkle_tree::{LeafPreimage, MembershipWitness}, tests::{merkle_tree_utils::NonEmptyMerkleTree, utils::assert_array_eq}, - traits::{Empty, is_empty_array} + traits::{Empty, is_empty_array}, }; fn silo_test_value(value: Field) -> Field { @@ -272,7 +273,7 @@ mod tests { TestSettledReadHint { read_request_index: read_request_len, membership_witness: MembershipWitness::empty(), - leaf_preimage: TestLeafPreimage::empty() + leaf_preimage: TestLeafPreimage::empty(), } } } @@ -295,34 +296,40 @@ mod tests { // Create 4 read requests. 0 and 3 are reading settled values. 1 and 2 are reading pending values. let read_requests = [ - ReadRequest { value: values[1], counter: 11 }.scope(contract_address),// settled - ReadRequest { value: values[3], counter: 13 }.scope(contract_address),// pending - ReadRequest { value: values[2], counter: 39 }.scope(contract_address),// pending - ReadRequest { value: values[0], counter: 46 }.scope(contract_address)// settled + ReadRequest { value: values[1], counter: 11 }.scope(contract_address), // settled + ReadRequest { value: values[3], counter: 13 }.scope(contract_address), // pending + ReadRequest { value: values[2], counter: 39 }.scope(contract_address), // pending + ReadRequest { value: values[0], counter: 46 }.scope(contract_address), // settled ]; let pending_values = [ TestValue { value: siloed_values[2], counter: 2 }, - TestValue { value: siloed_values[3], counter: 8 } + TestValue { value: siloed_values[3], counter: 8 }, ]; let pending_read_hints = [ PendingReadHint { read_request_index: 1, pending_value_index: 1 }, - PendingReadHint { read_request_index: 2, pending_value_index: 0 } + PendingReadHint { read_request_index: 2, pending_value_index: 0 }, ]; let leaf_preimages = [ TestLeafPreimage { value: siloed_values[0] }, - TestLeafPreimage { value: siloed_values[1] } + TestLeafPreimage { value: siloed_values[1] }, ]; let read_request_statuses = [ ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 0 }, ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 0 }, ReadRequestStatus { state: ReadRequestState.PENDING, hint_index: 1 }, - ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 1 } + ReadRequestStatus { state: ReadRequestState.SETTLED, hint_index: 1 }, ]; - TestBuilder { read_requests, read_request_statuses, pending_values, pending_read_hints, leaf_preimages } + TestBuilder { + read_requests, + read_request_statuses, + pending_values, + pending_read_hints, + leaf_preimages, + } } } @@ -332,7 +339,7 @@ mod tests { [self.leaf_preimages[0].as_leaf(), self.leaf_preimages[1].as_leaf()], [0; 3], [0; 2], - [0; 1] + [0; 1], ) } @@ -341,14 +348,20 @@ mod tests { let hints = [ TestSettledReadHint { read_request_index: 0, - membership_witness: MembershipWitness { leaf_index: 1, sibling_path: tree.get_sibling_path(1) }, - leaf_preimage: self.leaf_preimages[1] + membership_witness: MembershipWitness { + leaf_index: 1, + sibling_path: tree.get_sibling_path(1), + }, + leaf_preimage: self.leaf_preimages[1], }, TestSettledReadHint { read_request_index: 3, - membership_witness: MembershipWitness { leaf_index: 0, sibling_path: tree.get_sibling_path(0) }, - leaf_preimage: self.leaf_preimages[0] - } + membership_witness: MembershipWitness { + leaf_index: 0, + sibling_path: tree.get_sibling_path(0), + }, + leaf_preimage: self.leaf_preimages[0], + }, ]; let tree_root = tree.get_root(); (hints, tree_root) @@ -362,7 +375,9 @@ mod tests { TestSettledReadHint::nada(self.read_requests.len()) } - pub unconstrained fn get_unverified_read_requests(self) -> [ScopedReadRequest; READ_REQUEST_LEN] { + pub unconstrained fn get_unverified_read_requests( + self, + ) -> [ScopedReadRequest; READ_REQUEST_LEN] { get_unverified_read_requests(self.read_requests, self.read_request_statuses) } @@ -370,7 +385,7 @@ mod tests { validate_pending_read_requests( self.read_requests, self.pending_values, - self.pending_read_hints + self.pending_read_hints, ); } @@ -382,16 +397,14 @@ mod tests { pub fn validate_settled_read_requests_with_hints( self, settled_hints: [TestSettledReadHint; 2], - tree_root: Field + tree_root: Field, ) { validate_settled_read_requests(self.read_requests, settled_hints, tree_root); } pub fn verify_with_settled_hints(self, settled_hints: [TestSettledReadHint; 2]) { let tree = self.build_tree(); - let unverified = unsafe { - self.get_unverified_read_requests() - }; + let unverified = unsafe { self.get_unverified_read_requests() }; verify_reset_read_requests( self.read_requests, self.pending_values, @@ -399,15 +412,13 @@ mod tests { self.pending_read_hints, settled_hints, tree.get_root(), - unverified + unverified, ); } pub fn verify(self) { let (settled_hints, tree_root) = self.get_settled_read_hints(); - let unverified = unsafe { - self.get_unverified_read_requests() - }; + let unverified = unsafe { self.get_unverified_read_requests() }; verify_reset_read_requests( self.read_requests, self.pending_values, @@ -415,7 +426,7 @@ mod tests { self.pending_read_hints, settled_hints, tree_root, - unverified + unverified, ); } } @@ -514,9 +525,7 @@ mod tests { fn verify_read_requests_clears_all_succeeds() { let builder = TestBuilder::new(); - let unverified_read_requests = unsafe { - builder.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { builder.get_unverified_read_requests() }; assert(is_empty_array(unverified_read_requests)); builder.verify(); @@ -534,12 +543,10 @@ mod tests { settled_hints[0] = builder.get_nada_settled_read_hint(); let read_requests = builder.read_requests; - let unverified_read_requests = unsafe { - builder.get_unverified_read_requests() - }; + let unverified_read_requests = unsafe { builder.get_unverified_read_requests() }; assert_array_eq( unverified_read_requests, - [read_requests[0], read_requests[2]] + [read_requests[0], read_requests[2]], ); builder.verify_with_settled_hints(settled_hints); diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr index fad2acf2962..7d970eaf2fb 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/transient_data.nr @@ -1,6 +1,6 @@ use dep::types::{ abis::{note_hash::ScopedNoteHash, nullifier::ScopedNullifier, log_hash::NoteLogHash}, - traits::is_empty + traits::is_empty, }; pub struct TransientDataIndexHint { @@ -14,12 +14,7 @@ impl TransientDataIndexHint { } } -pub fn verify_squashed_transient_data_with_hint_indexes< - let NUM_NOTE_HASHES: u32, - let NUM_NULLIFIERS: u32, - let NUM_LOGS: u32, - let NUM_INDEX_HINTS: u32 ->( +pub fn verify_squashed_transient_data_with_hint_indexes( note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES], nullifiers: [ScopedNullifier; NUM_NULLIFIERS], note_logs: [NoteLogHash; NUM_LOGS], @@ -30,7 +25,7 @@ pub fn verify_squashed_transient_data_with_hint_indexes< transient_or_propagated_note_hash_indexes_for_logs: [u32; NUM_LOGS], split_counter: u32, squashed_note_hash_hints: [bool; NUM_NOTE_HASHES], - squashed_nullifier_hints: [bool; NUM_NULLIFIERS] + squashed_nullifier_hints: [bool; NUM_NULLIFIERS], ) { let mut num_squashed = 0; for i in 0..NUM_INDEX_HINTS { @@ -41,17 +36,23 @@ pub fn verify_squashed_transient_data_with_hint_indexes< let nullifier = nullifiers[hint.nullifier_index]; let note_hash = note_hashes[hint.note_hash_index]; assert_eq( - note_hash.value(), nullifier.nullified_note_hash(), "Value of the hinted transient note hash does not match" + note_hash.value(), + nullifier.nullified_note_hash(), + "Value of the hinted transient note hash does not match", ); assert_eq( - note_hash.contract_address, nullifier.contract_address, "Contract address of the hinted transient note hash does not match" + note_hash.contract_address, + nullifier.contract_address, + "Contract address of the hinted transient note hash does not match", ); assert( - nullifier.counter() > note_hash.counter(), "Cannot nullify a note hash created afterwards" + nullifier.counter() > note_hash.counter(), + "Cannot nullify a note hash created afterwards", ); if nullifier.counter() >= split_counter { assert( - note_hash.counter() >= split_counter, "Cannot squash a non-revertible note hash with a revertible nullifier" + note_hash.counter() >= split_counter, + "Cannot squash a non-revertible note hash with a revertible nullifier", ); // Since the nullifier counter must be larger than the note hash counter, it's not possible to squash a revertible note hash with a non-revertible nullifier. } @@ -73,18 +74,26 @@ pub fn verify_squashed_transient_data_with_hint_indexes< for i in 0..NUM_NOTE_HASHES { if !squashed_note_hash_hints[i] { assert_eq( - expected_note_hashes[note_hashes_kept], note_hashes[i], "Propagated note hash does not match" + expected_note_hashes[note_hashes_kept], + note_hashes[i], + "Propagated note hash does not match", ); note_hashes_kept += 1; } } - assert_eq(note_hashes_kept + num_squashed, NUM_NOTE_HASHES, "Wrong number of note hashes removed"); + assert_eq( + note_hashes_kept + num_squashed, + NUM_NOTE_HASHES, + "Wrong number of note hashes removed", + ); let mut nullifiers_kept = 0; for i in 0..NUM_NULLIFIERS { if !squashed_nullifier_hints[i] { assert_eq( - expected_nullifiers[nullifiers_kept], nullifiers[i], "Propagated nullifier does not match" + expected_nullifiers[nullifiers_kept], + nullifiers[i], + "Propagated nullifier does not match", ); nullifiers_kept += 1; } @@ -115,7 +124,9 @@ pub fn verify_squashed_transient_data_with_hint_indexes< let hint = transient_data_index_hints[hint_index]; let transient_note_hash = note_hashes[hint.note_hash_index]; assert_eq( - log.note_hash_counter, transient_note_hash.counter(), "Value of the hinted transient note hash does not match log" + log.note_hash_counter, + transient_note_hash.counter(), + "Value of the hinted transient note hash does not match log", ); // For each log removed, an empty item is padded to the right. assert(is_empty(expected_log), "Empty log must be padded to the right"); @@ -124,7 +135,9 @@ pub fn verify_squashed_transient_data_with_hint_indexes< } } -pub unconstrained fn get_squashed_note_hash_hints(transient_data_index_hints: [TransientDataIndexHint; NUM_INDEX_HINTS]) -> [bool; NUM_NOTE_HASHES] { +pub unconstrained fn get_squashed_note_hash_hints( + transient_data_index_hints: [TransientDataIndexHint; NUM_INDEX_HINTS], +) -> [bool; NUM_NOTE_HASHES] { let mut hints = [false; NUM_NOTE_HASHES]; for i in 0..transient_data_index_hints.len() { let note_hash_index = transient_data_index_hints[i].note_hash_index; @@ -135,7 +148,9 @@ pub unconstrained fn get_squashed_note_hash_hints(transient_data_index_hints: [TransientDataIndexHint; NUM_INDEX_HINTS]) -> [bool; NUM_NULLIFIERS] { +pub unconstrained fn get_squashed_nullifier_hints( + transient_data_index_hints: [TransientDataIndexHint; NUM_INDEX_HINTS], +) -> [bool; NUM_NULLIFIERS] { let mut hints = [false; NUM_NULLIFIERS]; for i in 0..transient_data_index_hints.len() { let nullifier_index = transient_data_index_hints[i].nullifier_index; @@ -146,12 +161,7 @@ pub unconstrained fn get_squashed_nullifier_hints( +pub fn verify_squashed_transient_data( note_hashes: [ScopedNoteHash; NUM_NOTE_HASHES], nullifiers: [ScopedNullifier; NUM_NULLIFIERS], note_logs: [NoteLogHash; NUM_LOGS], @@ -160,14 +170,12 @@ pub fn verify_squashed_transient_data< expected_note_logs: [NoteLogHash; NUM_LOGS], transient_data_index_hints: [TransientDataIndexHint; NUM_INDEX_HINTS], transient_or_propagated_note_hash_indexes_for_logs: [u32; NUM_LOGS], - split_counter: u32 + split_counter: u32, ) { - let squashed_note_hash_hints = unsafe { - get_squashed_note_hash_hints(transient_data_index_hints) - }; - let squashed_nullifier_hints = unsafe { - get_squashed_nullifier_hints(transient_data_index_hints) - }; + let squashed_note_hash_hints = + unsafe { get_squashed_note_hash_hints(transient_data_index_hints) }; + let squashed_nullifier_hints = + unsafe { get_squashed_nullifier_hints(transient_data_index_hints) }; verify_squashed_transient_data_with_hint_indexes( note_hashes, nullifiers, @@ -179,18 +187,20 @@ pub fn verify_squashed_transient_data< transient_or_propagated_note_hash_indexes_for_logs, split_counter, squashed_note_hash_hints, - squashed_nullifier_hints + squashed_nullifier_hints, ); } mod tests { use crate::reset::transient_data::{ get_squashed_note_hash_hints, get_squashed_nullifier_hints, TransientDataIndexHint, - verify_squashed_transient_data, verify_squashed_transient_data_with_hint_indexes + verify_squashed_transient_data, verify_squashed_transient_data_with_hint_indexes, }; use dep::types::{ - abis::{note_hash::{NoteHash, ScopedNoteHash}, nullifier::{Nullifier, ScopedNullifier}, log_hash::NoteLogHash}, - address::AztecAddress + abis::{ + note_hash::{NoteHash, ScopedNoteHash}, nullifier::{Nullifier, ScopedNullifier}, + log_hash::NoteLogHash, + }, address::AztecAddress, }; global contract_address = AztecAddress::from_field(987654); @@ -214,20 +224,20 @@ mod tests { NoteHash { value: 22, counter: 200 }.scope(contract_address), NoteHash { value: 33, counter: 300 }.scope(contract_address), ScopedNoteHash::empty(), - ScopedNoteHash::empty() + ScopedNoteHash::empty(), ]; let nullifiers = [ Nullifier { value: 44, counter: 400, note_hash: 33 }.scope(contract_address), Nullifier { value: 55, counter: 500, note_hash: 11 }.scope(contract_address), Nullifier { value: 66, counter: 600, note_hash: 0 }.scope(contract_address), - ScopedNullifier::empty() + ScopedNullifier::empty(), ]; let note_logs = [ NoteLogHash { value: 77, counter: 700, length: 70, note_hash_counter: 100 }, NoteLogHash { value: 88, counter: 800, length: 80, note_hash_counter: 200 }, - NoteLogHash::empty() + NoteLogHash::empty(), ]; let mut expected_note_hashes = [ScopedNoteHash::empty(); 5]; @@ -239,7 +249,7 @@ mod tests { let transient_data_index_hints = [ TransientDataIndexHint { nullifier_index: 0, note_hash_index: 2 }, - TransientDataIndexHint { nullifier_index: 1, note_hash_index: 0 } + TransientDataIndexHint { nullifier_index: 1, note_hash_index: 0 }, ]; let transient_or_propagated_note_hash_indexes_for_logs = [1, 0, 1]; @@ -252,7 +262,7 @@ mod tests { expected_note_logs, transient_data_index_hints, transient_or_propagated_note_hash_indexes_for_logs, - split_counter: 0 + split_counter: 0, } } } @@ -262,13 +272,13 @@ mod tests { let note_hashes = [ NoteHash { value: 11, counter: 100 }.scope(contract_address), NoteHash { value: 22, counter: 200 }.scope(contract_address), - NoteHash { value: 33, counter: 300 }.scope(contract_address) + NoteHash { value: 33, counter: 300 }.scope(contract_address), ]; let nullifiers = [ Nullifier { value: 44, counter: 400, note_hash: 33 }.scope(contract_address), Nullifier { value: 55, counter: 500, note_hash: 11 }.scope(contract_address), - Nullifier { value: 66, counter: 600, note_hash: 22 }.scope(contract_address) + Nullifier { value: 66, counter: 600, note_hash: 22 }.scope(contract_address), ]; // tests removing two logs for one note hash @@ -276,7 +286,7 @@ mod tests { NoteLogHash { value: 77, counter: 700, length: 70, note_hash_counter: 100 }, NoteLogHash { value: 88, counter: 800, length: 80, note_hash_counter: 300 }, NoteLogHash { value: 99, counter: 900, length: 90, note_hash_counter: 200 }, - NoteLogHash { value: 111, counter: 1000, length: 100, note_hash_counter: 300 } + NoteLogHash { value: 111, counter: 1000, length: 100, note_hash_counter: 300 }, ]; let expected_note_hashes = [ScopedNoteHash::empty(); 3]; @@ -286,7 +296,7 @@ mod tests { let transient_data_index_hints = [ TransientDataIndexHint { nullifier_index: 0, note_hash_index: 2 }, TransientDataIndexHint { nullifier_index: 1, note_hash_index: 0 }, - TransientDataIndexHint { nullifier_index: 2, note_hash_index: 1 } + TransientDataIndexHint { nullifier_index: 2, note_hash_index: 1 }, ]; let transient_or_propagated_note_hash_indexes_for_logs = [1, 0, 2, 0]; @@ -299,7 +309,7 @@ mod tests { expected_note_logs, transient_data_index_hints, transient_or_propagated_note_hash_indexes_for_logs, - split_counter: 0 + split_counter: 0, } } } @@ -309,30 +319,33 @@ mod tests { let note_hashes = [ NoteHash { value: 11, counter: 100 }.scope(contract_address), NoteHash { value: 11, counter: 200 }.scope(contract_address), - NoteHash { value: 11, counter: 600 }.scope(contract_address) + NoteHash { value: 11, counter: 600 }.scope(contract_address), ]; let nullifiers = [ Nullifier { value: 33, counter: 300, note_hash: 11 }.scope(contract_address), Nullifier { value: 44, counter: 400, note_hash: 0 }.scope(contract_address), - Nullifier { value: 55, counter: 500, note_hash: 11 }.scope(contract_address) + Nullifier { value: 55, counter: 500, note_hash: 11 }.scope(contract_address), ]; let note_logs = [ NoteLogHash { value: 77, counter: 701, length: 70, note_hash_counter: 200 }, NoteLogHash { value: 77, counter: 702, length: 70, note_hash_counter: 200 }, NoteLogHash { value: 77, counter: 703, length: 70, note_hash_counter: 200 }, - NoteLogHash { value: 88, counter: 800, length: 80, note_hash_counter: 600 } + NoteLogHash { value: 88, counter: 800, length: 80, note_hash_counter: 600 }, ]; - let expected_note_hashes = [note_hashes[2], ScopedNoteHash::empty(), ScopedNoteHash::empty()]; - let expected_nullifiers = [nullifiers[1], ScopedNullifier::empty(), ScopedNullifier::empty()]; - let expected_note_logs = [note_logs[3], NoteLogHash::empty(), NoteLogHash::empty(), NoteLogHash::empty()]; + let expected_note_hashes = + [note_hashes[2], ScopedNoteHash::empty(), ScopedNoteHash::empty()]; + let expected_nullifiers = + [nullifiers[1], ScopedNullifier::empty(), ScopedNullifier::empty()]; + let expected_note_logs = + [note_logs[3], NoteLogHash::empty(), NoteLogHash::empty(), NoteLogHash::empty()]; let transient_data_index_hints = [ TransientDataIndexHint { nullifier_index: 0, note_hash_index: 0 }, TransientDataIndexHint { nullifier_index: 2, note_hash_index: 1 }, - TransientDataIndexHint { nullifier_index: 3, note_hash_index: 3 } + TransientDataIndexHint { nullifier_index: 3, note_hash_index: 3 }, ]; let transient_or_propagated_note_hash_indexes_for_logs = [1, 1, 1, 0]; @@ -345,7 +358,7 @@ mod tests { expected_note_logs, transient_data_index_hints, transient_or_propagated_note_hash_indexes_for_logs, - split_counter: 0 + split_counter: 0, } } } @@ -353,16 +366,17 @@ mod tests { impl TestDataBuilder { pub fn get_nada_index_hint(_self: Self) -> TransientDataIndexHint { - TransientDataIndexHint { nullifier_index: NUM_NULLIFIERS, note_hash_index: NUM_NOTE_HASHES } + TransientDataIndexHint { + nullifier_index: NUM_NULLIFIERS, + note_hash_index: NUM_NOTE_HASHES, + } } pub fn get_hint_indexes(self) -> ([bool; NUM_NOTE_HASHES], [bool; NUM_NULLIFIERS]) { - let squashed_note_hash_hints = unsafe { - get_squashed_note_hash_hints(self.transient_data_index_hints) - }; - let squashed_nullifier_hints = unsafe { - get_squashed_nullifier_hints(self.transient_data_index_hints) - }; + let squashed_note_hash_hints = + unsafe { get_squashed_note_hash_hints(self.transient_data_index_hints) }; + let squashed_nullifier_hints = + unsafe { get_squashed_nullifier_hints(self.transient_data_index_hints) }; (squashed_note_hash_hints, squashed_nullifier_hints) } @@ -376,14 +390,14 @@ mod tests { self.expected_note_logs, self.transient_data_index_hints, self.transient_or_propagated_note_hash_indexes_for_logs, - self.split_counter + self.split_counter, ); } pub fn verify_with_hint_indexes( self, squashed_note_hash_hints: [bool; NUM_NOTE_HASHES], - squashed_nullifier_hints: [bool; NUM_NULLIFIERS] + squashed_nullifier_hints: [bool; NUM_NULLIFIERS], ) { verify_squashed_transient_data_with_hint_indexes( self.note_hashes, @@ -396,7 +410,7 @@ mod tests { self.transient_or_propagated_note_hash_indexes_for_logs, self.split_counter, squashed_note_hash_hints, - squashed_nullifier_hints + squashed_nullifier_hints, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/tree_leaf_read_request.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/tree_leaf_read_request.nr index 75ac5ab045a..a5dd79f6c4f 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/tree_leaf_read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/reset/tree_leaf_read_request.nr @@ -1,16 +1,16 @@ use dep::types::{ abis::tree_leaf_read_request::TreeLeafReadRequest, traits::is_empty, - merkle_tree::assert_check_membership + merkle_tree::assert_check_membership, }; pub struct TreeLeafReadRequestHint { - sibling_path: [Field; N] + sibling_path: [Field; N], } pub fn validate_tree_leaf_read_requests( read_requests: [TreeLeafReadRequest; READ_REQUEST_LEN], hints: [TreeLeafReadRequestHint; READ_REQUEST_LEN], - tree_root: Field + tree_root: Field, ) { for i in 0..READ_REQUEST_LEN { let read_request = read_requests[i]; @@ -19,7 +19,7 @@ pub fn validate_tree_leaf_read_requests NoteHashReadRequest pub fn new() -> Self { NoteHashReadRequestHintsBuilder { read_request_statuses: [ReadRequestStatus::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX], - pending_read_hints: BoundedVec { storage: [PendingReadHint::nada(MAX_NOTE_HASH_READ_REQUESTS_PER_TX); NUM_PENDING_HINTS], len: 0 }, + pending_read_hints: BoundedVec { + storage: [ + PendingReadHint::nada(MAX_NOTE_HASH_READ_REQUESTS_PER_TX); NUM_PENDING_HINTS + ], + len: 0, + }, settled_read_hints: BoundedVec { - storage: [NoteHashSettledReadHint::nada(MAX_NOTE_HASH_READ_REQUESTS_PER_TX); NUM_SETTLED_HINTS], - len: 0 + storage: [ + NoteHashSettledReadHint::nada(MAX_NOTE_HASH_READ_REQUESTS_PER_TX); + NUM_SETTLED_HINTS + ], + len: 0, + }, } } - } - pub unconstrained fn to_hints(self) -> NoteHashReadRequestHints { + pub unconstrained fn to_hints( + self, + ) -> NoteHashReadRequestHints { NoteHashReadRequestHints { read_request_statuses: self.read_request_statuses, pending_read_hints: self.pending_read_hints.storage, - settled_read_hints: self.settled_read_hints.storage + settled_read_hints: self.settled_read_hints.storage, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_non_existent_read_request_hints_builder.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_non_existent_read_request_hints_builder.nr index 22f7330f903..3fd0579ca1d 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_non_existent_read_request_hints_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_non_existent_read_request_hints_builder.nr @@ -1,12 +1,13 @@ -use crate::nullifier_non_existent_read_request_reset::{NullifierNonMembershipHint, NullifierNonExistentReadRequestHints}; +use crate::nullifier_non_existent_read_request_reset::{ + NullifierNonMembershipHint, NullifierNonExistentReadRequestHints, +}; use dep::types::{ abis::{nullifier::Nullifier, nullifier_leaf_preimage::NullifierLeafPreimage}, constants::{ - MAX_NULLIFIERS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT, - NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT -}, - merkle_tree::MembershipWitness, tests::{merkle_tree_utils::NonEmptyMerkleTree}, - utils::{arrays::{find_index_hint, get_sorted_result}} + MAX_NULLIFIERS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, + NULLIFIER_TREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, + }, merkle_tree::MembershipWitness, tests::merkle_tree_utils::NonEmptyMerkleTree, + utils::arrays::{find_index_hint, get_sorted_result}, }; pub struct NullifierNonExistentReadRequestHintsBuilder { @@ -22,13 +23,13 @@ impl NullifierNonExistentReadRequestHintsBuilder { nullifier_tree: NonEmptyMerkleTree::empty(), non_membership_hints: BoundedVec::new(), read_values: BoundedVec::new(), - pending_nullifiers: [Nullifier::empty(); MAX_NULLIFIERS_PER_TX] + pending_nullifiers: [Nullifier::empty(); MAX_NULLIFIERS_PER_TX], } } pub fn set_nullifier_tree( &mut self, - tree: NonEmptyMerkleTree + tree: NonEmptyMerkleTree, ) { self.nullifier_tree = tree; } @@ -43,8 +44,15 @@ impl NullifierNonExistentReadRequestHintsBuilder { // There are only two pre-existing nullifiers in the tree: [0, 100], generated in public_kernel_tail::tests. // Assuming the siloed_value is always greater than 100. let hint = NullifierNonMembershipHint { - low_leaf_preimage: NullifierLeafPreimage { nullifier: 100, next_nullifier: 0, next_index: 0 }, - membership_witness: MembershipWitness { leaf_index: 1, sibling_path: self.nullifier_tree.get_sibling_path(1) } + low_leaf_preimage: NullifierLeafPreimage { + nullifier: 100, + next_nullifier: 0, + next_index: 0, + }, + membership_witness: MembershipWitness { + leaf_index: 1, + sibling_path: self.nullifier_tree.get_sibling_path(1), + }, }; self.non_membership_hints.push(hint); } @@ -52,7 +60,7 @@ impl NullifierNonExistentReadRequestHintsBuilder { pub unconstrained fn to_hints(self) -> NullifierNonExistentReadRequestHints { let sorted_result = get_sorted_result( self.pending_nullifiers, - |a: Nullifier, b: Nullifier| (b.value == 0) | ((a.value != 0) & a.value.lt(b.value)) + |a: Nullifier, b: Nullifier| (b.value == 0) | ((a.value != 0) & a.value.lt(b.value)), ); let sorted_pending_values = sorted_result.sorted_array; let sorted_pending_value_index_hints = sorted_result.sorted_index_hints; @@ -61,7 +69,8 @@ impl NullifierNonExistentReadRequestHintsBuilder { for i in 0..MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX { if i < self.read_values.len() { let value = self.read_values.get_unchecked(i); - next_pending_value_indices[i] = find_index_hint(sorted_pending_values, |v: Nullifier| !v.value.lt(value)); + next_pending_value_indices[i] = + find_index_hint(sorted_pending_values, |v: Nullifier| !v.value.lt(value)); } } @@ -69,7 +78,7 @@ impl NullifierNonExistentReadRequestHintsBuilder { non_membership_hints: self.non_membership_hints.storage, sorted_pending_values, sorted_pending_value_index_hints, - next_pending_value_indices + next_pending_value_indices, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_read_request_hints_builder.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_read_request_hints_builder.nr index 0a24622d9eb..b3a4717bcf3 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_read_request_hints_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/tests/nullifier_read_request_hints_builder.nr @@ -1,6 +1,6 @@ use crate::{ nullifier_read_request_reset::{NullifierSettledReadHint, NullifierReadRequestHints}, - reset::read_request::{PendingReadHint, ReadRequestStatus} + reset::read_request::{PendingReadHint, ReadRequestStatus}, }; use dep::types::constants::MAX_NULLIFIER_READ_REQUESTS_PER_TX; @@ -14,19 +14,29 @@ impl NullifierReadReques pub fn new() -> Self { NullifierReadRequestHintsBuilder { read_request_statuses: [ReadRequestStatus::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX], - pending_read_hints: BoundedVec { storage: [PendingReadHint::nada(MAX_NULLIFIER_READ_REQUESTS_PER_TX); NUM_PENDING_HINTS], len: 0 }, + pending_read_hints: BoundedVec { + storage: [ + PendingReadHint::nada(MAX_NULLIFIER_READ_REQUESTS_PER_TX); NUM_PENDING_HINTS + ], + len: 0, + }, settled_read_hints: BoundedVec { - storage: [NullifierSettledReadHint::nada(MAX_NULLIFIER_READ_REQUESTS_PER_TX); NUM_SETTLED_HINTS], - len: 0 + storage: [ + NullifierSettledReadHint::nada(MAX_NULLIFIER_READ_REQUESTS_PER_TX); + NUM_SETTLED_HINTS + ], + len: 0, + }, } } - } - pub unconstrained fn to_hints(self) -> NullifierReadRequestHints { + pub unconstrained fn to_hints( + self, + ) -> NullifierReadRequestHints { NullifierReadRequestHints { read_request_statuses: self.read_request_statuses, pending_read_hints: self.pending_read_hints.storage, - settled_read_hints: self.settled_read_hints.storage + settled_read_hints: self.settled_read_hints.storage, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr index 109ea39bf4e..cf844edcfe4 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/base_or_merge_rollup_public_inputs.nr @@ -1,6 +1,6 @@ use dep::types::{ constants::BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH, partial_state_reference::PartialStateReference, - traits::{Empty, Serialize, Deserialize}, utils::reader::Reader + traits::{Empty, Serialize, Deserialize}, utils::reader::Reader, }; use crate::abis::constant_rollup_data::ConstantRollupData; @@ -10,9 +10,9 @@ global MERGE_ROLLUP_TYPE = 1; pub struct BaseOrMergeRollupPublicInputs { // rollup_type is either 0 (base) or 1 (merge) // TODO(Kev): Why is this a u32 instead of a u8/u16? - rollup_type : u32, - num_txs : u32, - constants : ConstantRollupData, + rollup_type: u32, + num_txs: u32, + constants: ConstantRollupData, start: PartialStateReference, end: PartialStateReference, @@ -22,10 +22,10 @@ pub struct BaseOrMergeRollupPublicInputs { // So we want to constrain it when casting these fields to U128 // We hash public inputs to make them constant-sized (to then be unpacked on-chain) - txs_effects_hash : Field, - out_hash : Field, + txs_effects_hash: Field, + out_hash: Field, - accumulated_fees: Field + accumulated_fees: Field, } impl Empty for BaseOrMergeRollupPublicInputs { @@ -38,7 +38,7 @@ impl Empty for BaseOrMergeRollupPublicInputs { end: PartialStateReference::empty(), txs_effects_hash: 0, out_hash: 0, - accumulated_fees: 0 + accumulated_fees: 0, } } } @@ -76,7 +76,9 @@ impl Serialize for BaseOrMergeRollupPublicIn } impl Deserialize for BaseOrMergeRollupPublicInputs { - fn deserialize(fields: [Field; BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH]) -> BaseOrMergeRollupPublicInputs { + fn deserialize( + fields: [Field; BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH], + ) -> BaseOrMergeRollupPublicInputs { let mut reader = Reader::new(fields); let item = Self { rollup_type: reader.read() as u32, @@ -86,7 +88,7 @@ impl Deserialize for BaseOrMergeRollupPublic end: reader.read_struct(PartialStateReference::deserialize), txs_effects_hash: reader.read(), out_hash: reader.read(), - accumulated_fees: reader.read() + accumulated_fees: reader.read(), }; reader.finish(); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr index ab4808e4e28..a8fea926e2c 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/block_root_or_block_merge_public_inputs.nr @@ -1,12 +1,13 @@ use dep::types::{ abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot, global_variables::GlobalVariables}, - constants::{AZTEC_EPOCH_DURATION, BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH, FEE_RECIPIENT_LENGTH}, - traits::{Empty, Serialize, Deserialize}, utils::reader::Reader, address::EthAddress + constants::{ + AZTEC_EPOCH_DURATION, BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH, FEE_RECIPIENT_LENGTH, + }, traits::{Empty, Serialize, Deserialize}, utils::reader::Reader, address::EthAddress, }; pub struct FeeRecipient { - recipient: EthAddress, - value: Field, + recipient: EthAddress, + value: Field, } // TODO(#7346): Should the default empty value be MAX_FIELD? The zero addr may be a valid recipient @@ -37,17 +38,17 @@ impl Eq for FeeRecipient { // TODO: instead of archives + global vars, use ConstantRollupData x2? It also includes vk root // may be confusing as new_constant.last_archive would actually be the new_archive pub struct BlockRootOrBlockMergePublicInputs { - previous_archive: AppendOnlyTreeSnapshot, // Archive tree root immediately before this block range - new_archive: AppendOnlyTreeSnapshot, // Archive tree root after adding this block range - previous_block_hash: Field, // Identifier of the previous block before the range - end_block_hash: Field, // Identifier of the last block in the range - start_global_variables: GlobalVariables, // Global variables for the first block in the range - end_global_variables: GlobalVariables, // Global variables for the last block in the range - out_hash: Field, // Merkle node of the L2-to-L1 messages merkle roots in the block range - fees: [FeeRecipient; AZTEC_EPOCH_DURATION], // Concatenation of all coinbase and fees for the block range - vk_tree_root: Field, // Root of allowed vk tree - protocol_contract_tree_root: Field, // Root of protocol contract tree - prover_id: Field, // TODO(#7346): Temporarily added prover_id while we verify block-root proofs on L1 + previous_archive: AppendOnlyTreeSnapshot, // Archive tree root immediately before this block range + new_archive: AppendOnlyTreeSnapshot, // Archive tree root after adding this block range + previous_block_hash: Field, // Identifier of the previous block before the range + end_block_hash: Field, // Identifier of the last block in the range + start_global_variables: GlobalVariables, // Global variables for the first block in the range + end_global_variables: GlobalVariables, // Global variables for the last block in the range + out_hash: Field, // Merkle node of the L2-to-L1 messages merkle roots in the block range + fees: [FeeRecipient; AZTEC_EPOCH_DURATION], // Concatenation of all coinbase and fees for the block range + vk_tree_root: Field, // Root of allowed vk tree + protocol_contract_tree_root: Field, // Root of protocol contract tree + prover_id: Field, // TODO(#7346): Temporarily added prover_id while we verify block-root proofs on L1 } impl BlockRootOrBlockMergePublicInputs { @@ -69,7 +70,7 @@ impl Empty for BlockRootOrBlockMergePublicInputs { fees: [FeeRecipient::empty(); AZTEC_EPOCH_DURATION], vk_tree_root: 0, protocol_contract_tree_root: 0, - prover_id: 0 + prover_id: 0, } } } @@ -85,15 +86,15 @@ impl Eq for BlockRootOrBlockMergePublicInputs { & (self.out_hash == other.out_hash) & (self.fees.eq(other.fees)) & (self.vk_tree_root == other.vk_tree_root) - & (self.protocol_contract_tree_root - == other.protocol_contract_tree_root) + & (self.protocol_contract_tree_root == other.protocol_contract_tree_root) & (self.prover_id == other.prover_id) } } impl Serialize for BlockRootOrBlockMergePublicInputs { fn serialize(self) -> [Field; BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH] { - let mut fields: BoundedVec = BoundedVec::new(); + let mut fields: BoundedVec = + BoundedVec::new(); fields.extend_from_array(self.previous_archive.serialize()); fields.extend_from_array(self.new_archive.serialize()); @@ -115,7 +116,9 @@ impl Serialize for BlockRootOrBl } impl Deserialize for BlockRootOrBlockMergePublicInputs { - fn deserialize(fields: [Field; BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH]) -> BlockRootOrBlockMergePublicInputs { + fn deserialize( + fields: [Field; BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH], + ) -> BlockRootOrBlockMergePublicInputs { let mut reader = Reader::new(fields); let item = Self { previous_archive: reader.read_struct(AppendOnlyTreeSnapshot::deserialize), @@ -127,11 +130,11 @@ impl Deserialize for BlockRootOr out_hash: reader.read(), fees: reader.read_struct_array( FeeRecipient::deserialize, - [FeeRecipient::empty(); AZTEC_EPOCH_DURATION] + [FeeRecipient::empty(); AZTEC_EPOCH_DURATION], ), vk_tree_root: reader.read(), protocol_contract_tree_root: reader.read(), - prover_id: reader.read() + prover_id: reader.read(), }; reader.finish(); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/constant_rollup_data.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/constant_rollup_data.nr index ba4bbae335e..6c5380cc42e 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/constant_rollup_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/constant_rollup_data.nr @@ -1,7 +1,7 @@ use dep::types::{ abis::{global_variables::GlobalVariables, append_only_tree_snapshot::AppendOnlyTreeSnapshot}, traits::{Empty, Serialize, Deserialize}, constants::CONSTANT_ROLLUP_DATA_LENGTH, - utils::reader::Reader + utils::reader::Reader, }; pub struct ConstantRollupData { @@ -27,7 +27,7 @@ impl Empty for ConstantRollupData { last_archive: AppendOnlyTreeSnapshot::zero(), vk_tree_root: 0, protocol_contract_tree_root: 0, - global_variables: GlobalVariables::empty() + global_variables: GlobalVariables::empty(), } } } @@ -54,7 +54,7 @@ impl Deserialize for ConstantRollupData { last_archive: reader.read_struct(AppendOnlyTreeSnapshot::deserialize), vk_tree_root: reader.read(), protocol_contract_tree_root: reader.read(), - global_variables: reader.read_struct(GlobalVariables::deserialize) + global_variables: reader.read_struct(GlobalVariables::deserialize), }; reader.finish(); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_block_data.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_block_data.nr index 94f4ef54add..100233dcb6b 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_block_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_block_data.nr @@ -2,11 +2,10 @@ use crate::abis::block_root_or_block_merge_public_inputs::BlockRootOrBlockMergeP use dep::types::{ constants::VK_TREE_HEIGHT, recursion::{ - proof::NestedRecursiveProof, verification_key::{HonkVerificationKey, VerificationKey}, - traits::Verifiable -}, - traits::Empty, merkle_tree::MembershipWitness, merkle_tree::membership::assert_check_membership, - utils::arrays::find_index_hint + proof::NestedRecursiveProof, verification_key::{HonkVerificationKey, VerificationKey}, + traits::Verifiable, + }, traits::Empty, merkle_tree::MembershipWitness, + merkle_tree::membership::assert_check_membership, utils::arrays::find_index_hint, }; pub struct PreviousRollupBlockData { @@ -18,7 +17,9 @@ pub struct PreviousRollupBlockData { impl Verifiable for PreviousRollupBlockData { fn verify(self) { - let inputs = BlockRootOrBlockMergePublicInputs::serialize(self.block_root_or_block_merge_public_inputs); + let inputs = BlockRootOrBlockMergePublicInputs::serialize( + self.block_root_or_block_merge_public_inputs, + ); std::verify_proof(self.vk.key, self.proof.fields, inputs, self.vk.hash); } } @@ -29,7 +30,7 @@ impl Empty for PreviousRollupBlockData { block_root_or_block_merge_public_inputs: BlockRootOrBlockMergePublicInputs::empty(), proof: NestedRecursiveProof::empty(), vk: VerificationKey::empty(), - vk_witness: MembershipWitness::empty() + vk_witness: MembershipWitness::empty(), } } } @@ -39,9 +40,8 @@ impl PreviousRollupBlockData { self.vk.check_hash(); let leaf_index = self.vk_witness.leaf_index as u32; - let index_hint = unsafe { - find_index_hint(allowed_indices, |index: u32| index == leaf_index) - }; + let index_hint = + unsafe { find_index_hint(allowed_indices, |index: u32| index == leaf_index) }; assert(index_hint < N, "Invalid vk index"); assert_eq(allowed_indices[index_hint], leaf_index, "Invalid vk index"); @@ -49,7 +49,7 @@ impl PreviousRollupBlockData { self.vk.hash, self.vk_witness.leaf_index, self.vk_witness.sibling_path, - self.block_root_or_block_merge_public_inputs.vk_tree_root + self.block_root_or_block_merge_public_inputs.vk_tree_root, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr index 9682bbe1824..1b7e4867811 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/abis/previous_rollup_data.nr @@ -2,23 +2,23 @@ use crate::abis::base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInpu use dep::types::{ constants::VK_TREE_HEIGHT, recursion::{ - proof::NestedRecursiveProof, verification_key::{VerificationKey, HonkVerificationKey}, - traits::Verifiable -}, - traits::Empty, merkle_tree::MembershipWitness, merkle_tree::membership::assert_check_membership, - utils::arrays::find_index_hint + proof::NestedRecursiveProof, verification_key::{VerificationKey, HonkVerificationKey}, + traits::Verifiable, + }, traits::Empty, merkle_tree::MembershipWitness, + merkle_tree::membership::assert_check_membership, utils::arrays::find_index_hint, }; -pub struct PreviousRollupData{ - base_or_merge_rollup_public_inputs : BaseOrMergeRollupPublicInputs, - proof : NestedRecursiveProof, - vk : HonkVerificationKey, - vk_witness : MembershipWitness, +pub struct PreviousRollupData { + base_or_merge_rollup_public_inputs: BaseOrMergeRollupPublicInputs, + proof: NestedRecursiveProof, + vk: HonkVerificationKey, + vk_witness: MembershipWitness, } impl Verifiable for PreviousRollupData { fn verify(self) { - let inputs = BaseOrMergeRollupPublicInputs::serialize(self.base_or_merge_rollup_public_inputs); + let inputs = + BaseOrMergeRollupPublicInputs::serialize(self.base_or_merge_rollup_public_inputs); std::verify_proof(self.vk.key, self.proof.fields, inputs, self.vk.hash); } } @@ -29,7 +29,7 @@ impl Empty for PreviousRollupData { base_or_merge_rollup_public_inputs: BaseOrMergeRollupPublicInputs::empty(), proof: NestedRecursiveProof::empty(), vk: VerificationKey::empty(), - vk_witness: MembershipWitness::empty() + vk_witness: MembershipWitness::empty(), } } } @@ -39,9 +39,8 @@ impl PreviousRollupData { self.vk.check_hash(); let leaf_index = self.vk_witness.leaf_index as u32; - let index_hint = unsafe { - find_index_hint(allowed_indices, |index: u32| index == leaf_index) - }; + let index_hint = + unsafe { find_index_hint(allowed_indices, |index: u32| index == leaf_index) }; assert(index_hint < N, "Invalid vk index"); assert_eq(allowed_indices[index_hint], leaf_index, "Invalid vk index"); @@ -49,7 +48,7 @@ impl PreviousRollupData { self.vk.hash, self.vk_witness.leaf_index, self.vk_witness.sibling_path, - self.base_or_merge_rollup_public_inputs.constants.vk_tree_root + self.base_or_merge_rollup_public_inputs.constants.vk_tree_root, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr index 680dd98310c..dd9d49aaec1 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -1,44 +1,38 @@ use crate::{ abis::{ - constant_rollup_data::ConstantRollupData, - base_or_merge_rollup_public_inputs::{BaseOrMergeRollupPublicInputs, BASE_ROLLUP_TYPE} -}, - base::state_diff_hints::StateDiffHints, - components::{compute_tx_effects_hash, compute_kernel_out_hash} + constant_rollup_data::ConstantRollupData, + base_or_merge_rollup_public_inputs::{BaseOrMergeRollupPublicInputs, BASE_ROLLUP_TYPE}, + }, base::state_diff_hints::StateDiffHints, + components::{compute_tx_effects_hash, compute_kernel_out_hash}, }; use dep::types::{ hash::silo_l2_to_l1_message, data::{ - public_data_hint::PublicDataHint, - hash::{compute_public_data_tree_index, compute_public_data_tree_value} -}, - storage::map::derive_storage_slot_in_map, address::AztecAddress, + public_data_hint::PublicDataHint, + hash::{compute_public_data_tree_index, compute_public_data_tree_value}, + }, storage::map::derive_storage_slot_in_map, address::AztecAddress, abis::{ - append_only_tree_snapshot::AppendOnlyTreeSnapshot, nullifier_leaf_preimage::NullifierLeafPreimage, - public_data_update_request::PublicDataUpdateRequest, kernel_data::KernelData -}, - messaging::l2_to_l1_message::ScopedL2ToL1Message, + append_only_tree_snapshot::AppendOnlyTreeSnapshot, + nullifier_leaf_preimage::NullifierLeafPreimage, + public_data_update_request::PublicDataUpdateRequest, kernel_data::KernelData, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, constants::{ - PUBLIC_DATA_TREE_HEIGHT, NOTE_HASH_SUBTREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, - MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, - PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_HEIGHT, ARCHIVE_HEIGHT, - FEE_JUICE_ADDRESS, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PUBLIC_KERNEL_TAIL_INDEX, - PRIVATE_KERNEL_EMPTY_INDEX, TUBE_INDEX -}, + PUBLIC_DATA_TREE_HEIGHT, NOTE_HASH_SUBTREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, + MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, + NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_HEIGHT, + ARCHIVE_HEIGHT, FEE_JUICE_ADDRESS, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + PUBLIC_KERNEL_TAIL_INDEX, PRIVATE_KERNEL_EMPTY_INDEX, TUBE_INDEX, + }, merkle_tree::{ - append_only_tree, assert_check_membership, calculate_empty_tree_root, calculate_subtree_root, - indexed_tree, MembershipWitness -}, - partial_state_reference::PartialStateReference, + append_only_tree, assert_check_membership, calculate_empty_tree_root, + calculate_subtree_root, indexed_tree, MembershipWitness, + }, partial_state_reference::PartialStateReference, data::{PublicDataTreeLeaf, PublicDataTreeLeafPreimage}, traits::is_empty, - utils::{field::{full_field_less_than, full_field_greater_than}} + utils::field::{full_field_less_than, full_field_greater_than}, }; -global ALLOWED_PREVIOUS_CIRCUITS = [ - PRIVATE_KERNEL_EMPTY_INDEX, - TUBE_INDEX, - PUBLIC_KERNEL_TAIL_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = + [PRIVATE_KERNEL_EMPTY_INDEX, TUBE_INDEX, PUBLIC_KERNEL_TAIL_INDEX]; pub struct BaseRollupInputs { kernel_data: KernelData, @@ -69,26 +63,33 @@ impl BaseRollupInputs { // Verify the kernel chain_id and versions assert( self.kernel_data.public_inputs.constants.tx_context.chain_id - == self.constants.global_variables.chain_id, "kernel chain_id does not match the rollup chain_id" + == self.constants.global_variables.chain_id, + "kernel chain_id does not match the rollup chain_id", ); assert( self.kernel_data.public_inputs.constants.tx_context.version - == self.constants.global_variables.version, "kernel version does not match the rollup version" + == self.constants.global_variables.version, + "kernel version does not match the rollup version", ); assert( - self.kernel_data.public_inputs.constants.vk_tree_root == self.constants.vk_tree_root, "kernel vk_tree_root does not match the rollup vk_tree_root" + self.kernel_data.public_inputs.constants.vk_tree_root == self.constants.vk_tree_root, + "kernel vk_tree_root does not match the rollup vk_tree_root", ); assert( self.kernel_data.public_inputs.constants.protocol_contract_tree_root - == self.constants.protocol_contract_tree_root, "kernel protocol_contract_tree_root does not match the rollup protocol_contract_tree_root" + == self.constants.protocol_contract_tree_root, + "kernel protocol_contract_tree_root does not match the rollup protocol_contract_tree_root", ); // Verify the kernel global variables if set, note these can be empty if this is a request coming directly from the private kernel tail. // TODO(@spalladino) How can we check that this is a request coming from the private kernel tail? assert( self.kernel_data.public_inputs.constants.global_variables.is_empty() - | (self.kernel_data.public_inputs.constants.global_variables - == self.constants.global_variables), "kernel global variables do not match the rollup global variables" + | ( + self.kernel_data.public_inputs.constants.global_variables + == self.constants.global_variables + ), + "kernel global variables do not match the rollup global variables", ); self.validate_kernel_start_state(); @@ -100,7 +101,8 @@ impl BaseRollupInputs { if rollup_validation_requests.max_block_number.is_some() { assert( self.constants.global_variables.block_number as u32 - <= rollup_validation_requests.max_block_number.unwrap_unchecked(), "kernel max_block_number is smaller than block number" + <= rollup_validation_requests.max_block_number.unwrap_unchecked(), + "kernel max_block_number is smaller than block number", ); } @@ -113,23 +115,30 @@ impl BaseRollupInputs { self.state_diff_hints.note_hash_subtree_sibling_path, empty_commitments_subtree_root, commitments_tree_subroot, - NOTE_HASH_SUBTREE_HEIGHT as u8 + NOTE_HASH_SUBTREE_HEIGHT as u8, ); // Insert nullifiers: - let end_nullifier_tree_snapshot = self.check_nullifier_tree_non_membership_and_insert_to_tree(); + let end_nullifier_tree_snapshot = + self.check_nullifier_tree_non_membership_and_insert_to_tree(); // Inject protocol update requests for deducting tx_fee from fee_payer's balance let gas_fees = self.constants.global_variables.gas_fees; let transaction_fee = self.kernel_data.public_inputs.compute_transaction_fee(gas_fees); - let all_public_data_update_requests = self.calculate_all_public_data_update_requests(transaction_fee); + let all_public_data_update_requests = + self.calculate_all_public_data_update_requests(transaction_fee); // Validate public data update requests and update public data tree - let end_public_data_tree_snapshot = self.validate_and_process_public_state(all_public_data_update_requests); + let end_public_data_tree_snapshot = + self.validate_and_process_public_state(all_public_data_update_requests); // Calculate the tx effects hash of the transaction let siloed_l2_to_l1_msgs = self.kernel_data.public_inputs.end.l2_to_l1_msgs.map( - |message: ScopedL2ToL1Message| silo_l2_to_l1_message(message, self.kernel_data.public_inputs.constants.tx_context.version, self.kernel_data.public_inputs.constants.tx_context.chain_id) + |message: ScopedL2ToL1Message| silo_l2_to_l1_message( + message, + self.kernel_data.public_inputs.constants.tx_context.version, + self.kernel_data.public_inputs.constants.tx_context.chain_id, + ), ); let out_hash = compute_kernel_out_hash(siloed_l2_to_l1_msgs); let tx_effects_hash = compute_tx_effects_hash( @@ -137,7 +146,7 @@ impl BaseRollupInputs { self.kernel_data.public_inputs.revert_code, transaction_fee, all_public_data_update_requests, - out_hash + out_hash, ); // Perform membership checks that the notes provided exist within the historical trees data @@ -151,11 +160,11 @@ impl BaseRollupInputs { end: PartialStateReference { note_hash_tree: end_note_hash_tree_snapshot, nullifier_tree: end_nullifier_tree_snapshot, - public_data_tree: end_public_data_tree_snapshot + public_data_tree: end_public_data_tree_snapshot, }, txs_effects_hash: tx_effects_hash, out_hash, - accumulated_fees: transaction_fee + accumulated_fees: transaction_fee, } } @@ -175,62 +184,70 @@ impl BaseRollupInputs { self.state_diff_hints.nullifier_predecessor_preimages, self.state_diff_hints.nullifier_predecessor_membership_witnesses.map( |witness: MembershipWitness| { - MembershipWitness { - leaf_index: witness.leaf_index, - sibling_path: witness.sibling_path, - } - } + MembershipWitness { + leaf_index: witness.leaf_index, + sibling_path: witness.sibling_path, + } + }, ), - |low_leaf: NullifierLeafPreimage, nullifier: Field| { // Is valid low leaf + |low_leaf: NullifierLeafPreimage, nullifier: Field| { + // Is valid low leaf let is_less_than_nullifier = full_field_less_than(low_leaf.nullifier, nullifier); let is_next_greater_than = full_field_less_than(nullifier, low_leaf.next_nullifier); - (!low_leaf.is_empty()) & is_less_than_nullifier & ( - is_next_greater_than | - ((low_leaf.next_index == 0) & (low_leaf.next_nullifier == 0)) - ) + (!low_leaf.is_empty()) + & is_less_than_nullifier + & ( + is_next_greater_than + | ((low_leaf.next_index == 0) & (low_leaf.next_nullifier == 0)) + ) }, - |low_leaf: NullifierLeafPreimage, nullifier: Field, nullifier_index: u32| { // Update low leaf - NullifierLeafPreimage{ - nullifier : low_leaf.nullifier, - next_nullifier : nullifier, - next_index : nullifier_index, + |low_leaf: NullifierLeafPreimage, nullifier: Field, nullifier_index: u32| { + // Update low leaf + NullifierLeafPreimage { + nullifier: low_leaf.nullifier, + next_nullifier: nullifier, + next_index: nullifier_index, } }, - |nullifier: Field, low_leaf: NullifierLeafPreimage| { // Build insertion leaf + |nullifier: Field, low_leaf: NullifierLeafPreimage| { + // Build insertion leaf NullifierLeafPreimage { - nullifier : nullifier, - next_nullifier : low_leaf.next_nullifier, - next_index : low_leaf.next_index, + nullifier: nullifier, + next_nullifier: low_leaf.next_nullifier, + next_index: low_leaf.next_index, } }, [0; NULLIFIER_SUBTREE_HEIGHT], - [0; NULLIFIER_TREE_HEIGHT] + [0; NULLIFIER_TREE_HEIGHT], ) } fn create_nullifier_subtree(leaves: [NullifierLeafPreimage; N]) -> Field { - calculate_subtree_root(leaves.map(|leaf:NullifierLeafPreimage| leaf.hash())) + calculate_subtree_root(leaves.map(|leaf: NullifierLeafPreimage| leaf.hash())) } fn validate_kernel_start_state(self) { let kernel_state = self.kernel_data.public_inputs.start_state; if !is_empty(kernel_state) { assert( - kernel_state.note_hash_tree.eq(self.start.note_hash_tree), "Mismatch start state for note hash tree" + kernel_state.note_hash_tree.eq(self.start.note_hash_tree), + "Mismatch start state for note hash tree", ); assert( - kernel_state.nullifier_tree.eq(self.start.nullifier_tree), "Mismatch start state for nullifier tree" + kernel_state.nullifier_tree.eq(self.start.nullifier_tree), + "Mismatch start state for nullifier tree", ); assert( - kernel_state.public_data_tree.eq(self.start.public_data_tree), "Mismatch start state for public data tree" + kernel_state.public_data_tree.eq(self.start.public_data_tree), + "Mismatch start state for public data tree", ); } } fn validate_and_process_public_state( self, - all_update_requests: [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] + all_update_requests: [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], ) -> AppendOnlyTreeSnapshot { let end_public_data_tree_snapshot = insert_public_data_update_requests( self.start.public_data_tree, @@ -239,7 +256,7 @@ impl BaseRollupInputs { self.sorted_public_data_writes_indexes, self.low_public_data_writes_preimages, self.low_public_data_writes_witnesses, - self.state_diff_hints.public_data_sibling_path + self.state_diff_hints.public_data_sibling_path, ); end_public_data_tree_snapshot @@ -250,14 +267,17 @@ impl BaseRollupInputs { // update request we have at the time of this writing is deducting the tx_fee from the fee_payer balance. fn calculate_all_public_data_update_requests( self, - tx_fee: Field + tx_fee: Field, ) -> [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] { - let mut all_update_requests: [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = [PublicDataUpdateRequest::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + let mut all_update_requests: [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = + [PublicDataUpdateRequest::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { - all_update_requests[i] = self.kernel_data.public_inputs.end.public_data_update_requests[i]; + all_update_requests[i] = + self.kernel_data.public_inputs.end.public_data_update_requests[i]; } - let (payment_update_request, payment_update_index) = self.build_or_patch_payment_update_request(tx_fee); + let (payment_update_request, payment_update_index) = + self.build_or_patch_payment_update_request(tx_fee); all_update_requests[payment_update_index] = payment_update_request; all_update_requests @@ -269,7 +289,10 @@ impl BaseRollupInputs { // from the balance of the fee_payer, using the fee_payer_fee_juice_balance_read_hint to read the current balance. // Returns the data update request that subtracts the tx_fee from the fee_payer's balance, and the index where it // should be inserted in the public data update requests array. - fn build_or_patch_payment_update_request(self, tx_fee: Field) -> (PublicDataUpdateRequest, u32) { + fn build_or_patch_payment_update_request( + self, + tx_fee: Field, + ) -> (PublicDataUpdateRequest, u32) { let fee_payer = self.kernel_data.public_inputs.fee_payer; // TODO(@spalladino) Eventually remove the is_zero condition as we should always charge fees to every tx @@ -279,37 +302,48 @@ impl BaseRollupInputs { if read_hint.leaf_slot == 0 { // Is there a balance update already in this tx? If so, update it and return its index. - let existing_update_index = unsafe { - self.find_fee_payer_fee_juice_update_index(leaf_slot) - }; - let existing_update = self.kernel_data.public_inputs.end.public_data_update_requests[existing_update_index]; - assert( - existing_update.leaf_slot == leaf_slot, "Wrong leaf slot for Fee Juice balance update request" - ); - assert( - !existing_update.new_value.lt(tx_fee), "Not enough balance for fee payer after claim to pay for transaction" - ); + let existing_update_index = + unsafe { self.find_fee_payer_fee_juice_update_index(leaf_slot) }; + let existing_update = self.kernel_data.public_inputs.end.public_data_update_requests + [existing_update_index]; + assert( + existing_update.leaf_slot == leaf_slot, + "Wrong leaf slot for Fee Juice balance update request", + ); + assert( + !existing_update.new_value.lt(tx_fee), + "Not enough balance for fee payer after claim to pay for transaction", + ); - let new_value = compute_public_data_tree_value(existing_update.new_value - tx_fee); - let protocol_update_request = PublicDataUpdateRequest { leaf_slot, new_value, counter: 0 }; - (protocol_update_request, existing_update_index as u32) - } else { - // Otherwise, build a new one to be inserted into the protocol update requests at the end of the array. - read_hint.validate(self.start.public_data_tree.root); + let new_value = + compute_public_data_tree_value(existing_update.new_value - tx_fee); + let protocol_update_request = + PublicDataUpdateRequest { leaf_slot, new_value, counter: 0 }; + (protocol_update_request, existing_update_index as u32) + } else { + // Otherwise, build a new one to be inserted into the protocol update requests at the end of the array. + read_hint.validate(self.start.public_data_tree.root); - let balance = read_hint.value; - assert(read_hint.leaf_slot == leaf_slot, "Wrong leaf slot for Fee Juice balance read hint"); - assert(!balance.lt(tx_fee), "Not enough balance for fee payer to pay for transaction"); + let balance = read_hint.value; + assert( + read_hint.leaf_slot == leaf_slot, + "Wrong leaf slot for Fee Juice balance read hint", + ); + assert( + !balance.lt(tx_fee), + "Not enough balance for fee payer to pay for transaction", + ); - let new_value = compute_public_data_tree_value(balance - tx_fee); - let protocol_update_request = PublicDataUpdateRequest { leaf_slot, new_value, counter: 0 }; - (protocol_update_request, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) + let new_value = compute_public_data_tree_value(balance - tx_fee); + let protocol_update_request = + PublicDataUpdateRequest { leaf_slot, new_value, counter: 0 }; + (protocol_update_request, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) + } + } else { + // Nothing to do, just place an empty update request at the end of the array + (PublicDataUpdateRequest::empty(), MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) } - } else { - // Nothing to do, just place an empty update request at the end of the array - (PublicDataUpdateRequest::empty(), MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX) } - } // Check that the block header used by each kernel is a member of the blocks tree --> since the block header // contains roots of all the trees this is sufficient to verify that the tree roots used by kernels are correct @@ -329,19 +363,21 @@ impl BaseRollupInputs { previous_block_hash, previous_block_hash_witness.leaf_index, previous_block_hash_witness.sibling_path, - archive_root + archive_root, ); } unconstrained fn find_fee_payer_fee_juice_update_index(self, leaf_slot: Field) -> u32 { let mut update_index = MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + 1; for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { - if self.kernel_data.public_inputs.end.public_data_update_requests[i].leaf_slot == leaf_slot { + if self.kernel_data.public_inputs.end.public_data_update_requests[i].leaf_slot + == leaf_slot { update_index = i; } } assert( - update_index < MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, "Could not find fee payer Fee Juice update request" + update_index < MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + "Could not find fee payer Fee Juice update request", ); update_index } @@ -354,7 +390,7 @@ fn insert_public_data_update_requests( sorted_public_data_writes_indexes: [u32; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], low_public_data_writes_preimages: [PublicDataTreeLeafPreimage; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], low_public_data_writes_witnesses: [MembershipWitness; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - public_data_writes_subtree_sibling_path: [Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH] + public_data_writes_subtree_sibling_path: [Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], ) -> AppendOnlyTreeSnapshot { indexed_tree::batch_insert( prev_snapshot, @@ -365,73 +401,81 @@ fn insert_public_data_update_requests( low_public_data_writes_preimages, low_public_data_writes_witnesses.map( |witness: MembershipWitness| { - MembershipWitness { - leaf_index: witness.leaf_index, - sibling_path: witness.sibling_path, - } - } + MembershipWitness { + leaf_index: witness.leaf_index, + sibling_path: witness.sibling_path, + } + }, ), - |low_preimage: PublicDataTreeLeafPreimage, write: PublicDataTreeLeaf| { // Is valid low preimage + |low_preimage: PublicDataTreeLeafPreimage, write: PublicDataTreeLeaf| { + // Is valid low preimage let is_update = low_preimage.slot == write.slot; let is_low_empty = low_preimage.is_empty(); let is_less_than_slot = full_field_less_than(low_preimage.slot, write.slot); let is_next_greater_than = full_field_less_than(write.slot, low_preimage.next_slot); - let is_in_range = is_less_than_slot & ( - is_next_greater_than | - ((low_preimage.next_index == 0) & (low_preimage.next_slot == 0))); + let is_in_range = is_less_than_slot + & ( + is_next_greater_than + | ((low_preimage.next_index == 0) & (low_preimage.next_slot == 0)) + ); (!is_low_empty) & (is_update | is_in_range) }, - |low_preimage: PublicDataTreeLeafPreimage, write: PublicDataTreeLeaf, write_index: u32| { // Update low leaf + |low_preimage: PublicDataTreeLeafPreimage, write: PublicDataTreeLeaf, write_index: u32| { + // Update low leaf let is_update = low_preimage.slot == write.slot; if is_update { - PublicDataTreeLeafPreimage{ - slot : low_preimage.slot, + PublicDataTreeLeafPreimage { + slot: low_preimage.slot, value: write.value, - next_slot : low_preimage.next_slot, - next_index : low_preimage.next_index, + next_slot: low_preimage.next_slot, + next_index: low_preimage.next_index, } } else { - PublicDataTreeLeafPreimage{ - slot : low_preimage.slot, + PublicDataTreeLeafPreimage { + slot: low_preimage.slot, value: low_preimage.value, - next_slot : write.slot, - next_index : write_index, + next_slot: write.slot, + next_index: write_index, } } }, - |write: PublicDataTreeLeaf, low_preimage: PublicDataTreeLeafPreimage| { // Build insertion leaf + |write: PublicDataTreeLeaf, low_preimage: PublicDataTreeLeafPreimage| { + // Build insertion leaf let is_update = low_preimage.slot == write.slot; if is_update { PublicDataTreeLeafPreimage::empty() - }else { + } else { PublicDataTreeLeafPreimage { slot: write.slot, value: write.value, - next_slot : low_preimage.next_slot, - next_index : low_preimage.next_index, + next_slot: low_preimage.next_slot, + next_index: low_preimage.next_index, } } }, [0; PUBLIC_DATA_SUBTREE_HEIGHT], - [0; PUBLIC_DATA_TREE_HEIGHT] + [0; PUBLIC_DATA_TREE_HEIGHT], ) } fn compute_fee_payer_fee_juice_balance_leaf_slot(fee_payer: AztecAddress) -> Field { let balances_slot_in_fee_juice_contract = 1; - let fee_payer_balance_slot_in_fee_juice_contract = derive_storage_slot_in_map(balances_slot_in_fee_juice_contract, fee_payer); + let fee_payer_balance_slot_in_fee_juice_contract = + derive_storage_slot_in_map(balances_slot_in_fee_juice_contract, fee_payer); compute_public_data_tree_index( FEE_JUICE_ADDRESS, - fee_payer_balance_slot_in_fee_juice_contract + fee_payer_balance_slot_in_fee_juice_contract, ) } #[test] fn consistent_not_hash_subtree_width() { assert_eq( - MAX_NOTE_HASHES_PER_TX as Field, 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT as Field), "note hash subtree width is incorrect" + MAX_NOTE_HASHES_PER_TX as Field, + 2.pow_32(NOTE_HASH_SUBTREE_HEIGHT as Field), + "note hash subtree width is incorrect", ); } @@ -456,39 +500,38 @@ fn test_u256_greater_than() { mod tests { use crate::{ abis::{ - constant_rollup_data::ConstantRollupData, - base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs - }, + constant_rollup_data::ConstantRollupData, + base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs, + }, base::{ - state_diff_hints::StateDiffHints, - base_rollup_inputs::{BaseRollupInputs, compute_fee_payer_fee_juice_balance_leaf_slot} - }, - components::TX_EFFECTS_HASH_INPUT_FIELDS + state_diff_hints::StateDiffHints, + base_rollup_inputs::{BaseRollupInputs, compute_fee_payer_fee_juice_balance_leaf_slot}, + }, components::TX_EFFECTS_HASH_INPUT_FIELDS, }; use dep::types::{ abis::{ - append_only_tree_snapshot::AppendOnlyTreeSnapshot, - nullifier_leaf_preimage::NullifierLeafPreimage, - public_data_update_request::PublicDataUpdateRequest, kernel_data::KernelData - }, - messaging::l2_to_l1_message::ScopedL2ToL1Message, merkle_tree::MembershipWitness, + append_only_tree_snapshot::AppendOnlyTreeSnapshot, + nullifier_leaf_preimage::NullifierLeafPreimage, + public_data_update_request::PublicDataUpdateRequest, kernel_data::KernelData, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, merkle_tree::MembershipWitness, hash::silo_l2_to_l1_message, data::public_data_hint::PublicDataHint, address::{AztecAddress, EthAddress}, constants::{ - ARCHIVE_HEIGHT, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, - MAX_NULLIFIERS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NOTE_HASH_TREE_HEIGHT, - NOTE_HASH_SUBTREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, - NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT, - PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, MAX_L2_TO_L1_MSGS_PER_TX, - PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - PRIVATE_KERNEL_EMPTY_INDEX, PRIVATE_KERNEL_TAIL_INDEX, PUBLIC_KERNEL_TAIL_INDEX, - BASE_ROLLUP_INDEX, TUBE_INDEX - }, - partial_state_reference::PartialStateReference, + ARCHIVE_HEIGHT, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NOTE_HASHES_PER_TX, + MAX_NULLIFIERS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NOTE_HASH_TREE_HEIGHT, + NOTE_HASH_SUBTREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT, + NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT, + PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, MAX_L2_TO_L1_MSGS_PER_TX, + PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + PRIVATE_KERNEL_EMPTY_INDEX, PRIVATE_KERNEL_TAIL_INDEX, PUBLIC_KERNEL_TAIL_INDEX, + BASE_ROLLUP_INDEX, TUBE_INDEX, + }, partial_state_reference::PartialStateReference, data::{PublicDataTreeLeaf, PublicDataTreeLeafPreimage}, tests::{fixtures, fixture_builder::FixtureBuilder, merkle_tree_utils::NonEmptyMerkleTree}, - utils::{arrays::get_sorted_tuple::get_sorted_tuple, field::{full_field_less_than, field_from_bytes_32_trunc}}, - traits::Empty + utils::{ + arrays::get_sorted_tuple::get_sorted_tuple, + field::{full_field_less_than, field_from_bytes_32_trunc}, + }, traits::Empty, }; struct NullifierInsertion { @@ -506,23 +549,28 @@ mod tests { user_public_data_writes: BoundedVec<(u32, PublicDataTreeLeaf), MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX>, protocol_public_data_writes: BoundedVec<(u32, PublicDataTreeLeaf), PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX>, mut final_public_data_writes: BoundedVec<(u32, PublicDataTreeLeaf), MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX>, - mut pre_existing_public_data: [PublicDataTreeLeafPreimage; EXISTING_LEAVES] + mut pre_existing_public_data: [PublicDataTreeLeafPreimage; EXISTING_LEAVES], ) -> ([Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], [PublicDataTreeLeaf; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [u32; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [MembershipWitness; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; EXISTING_LEAVES]) { let mut subtree_path = [0; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]; - let mut sorted_public_data_writes = [PublicDataTreeLeaf::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; - let mut sorted_public_data_writes_indexes = [0 as u32; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; - let mut low_public_data_writes_preimages = [PublicDataTreeLeafPreimage::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; - let mut low_public_data_writes_witnesses = [MembershipWitness::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; - let mut new_subtree = [PublicDataTreeLeafPreimage::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + let mut sorted_public_data_writes = + [PublicDataTreeLeaf::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + let mut sorted_public_data_writes_indexes = + [0 as u32; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + let mut low_public_data_writes_preimages = + [PublicDataTreeLeafPreimage::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + let mut low_public_data_writes_witnesses = + [MembershipWitness::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; + let mut new_subtree = + [PublicDataTreeLeafPreimage::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]; for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { if i < (user_public_data_writes.len()) { let leaf = user_public_data_writes.get_unchecked(i).1; kernel_data.public_inputs.end.public_data_update_requests[i] = PublicDataUpdateRequest { - leaf_slot : leaf.slot, - new_value : leaf.value, - counter : 0 + leaf_slot: leaf.slot, + new_value: leaf.value, + counter: 0, }; } } @@ -536,7 +584,9 @@ mod tests { let mut sorted_write_tuples = unsafe { get_sorted_tuple( final_public_data_writes.storage, - |(_, leaf_a): (u32, PublicDataTreeLeaf), (_, leaf_b): (u32, PublicDataTreeLeaf)| full_field_less_than(leaf_b.slot, leaf_a.slot) + |(_, leaf_a): (u32, PublicDataTreeLeaf), (_, leaf_b): (u32, PublicDataTreeLeaf)| { + full_field_less_than(leaf_b.slot, leaf_a.slot) + }, ) }; @@ -562,18 +612,18 @@ mod tests { slot: low_leaf.slot, value: low_leaf.value, next_slot: leaf.slot, - next_index: MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + i + next_index: MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + i, }; } low_public_data_writes_preimages[i] = low_leaf; low_public_data_writes_witnesses[i] = MembershipWitness { leaf_index: low_leaf_index as Field, - sibling_path: public_data_tree.get_sibling_path(low_leaf_index) + sibling_path: public_data_tree.get_sibling_path(low_leaf_index), }; public_data_tree.update_leaf( low_leaf_index, - pre_existing_public_data[low_leaf_index].hash() + pre_existing_public_data[low_leaf_index].hash(), ); } } else { @@ -582,10 +632,15 @@ mod tests { } } - subtree_path = BaseRollupInputsBuilder::extract_subtree_sibling_path(public_data_tree.get_sibling_path(snapshot.next_available_leaf_index as u32), [0; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]); + subtree_path = BaseRollupInputsBuilder::extract_subtree_sibling_path( + public_data_tree.get_sibling_path(snapshot.next_available_leaf_index as u32), + [0; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], + ); ( - subtree_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, pre_existing_public_data + subtree_path, sorted_public_data_writes, sorted_public_data_writes_indexes, + low_public_data_writes_preimages, low_public_data_writes_witnesses, + pre_existing_public_data, ) } @@ -607,7 +662,7 @@ mod tests { constants: ConstantRollupData, // Index of the item in the pre_existing_public_data array that contains the fee payer's Fee Juice balance. // Used for building the public data hint read for the payment update request. If set to none, no hint is built. - fee_payer_fee_juice_balance_pre_existing_public_data_index: Option + fee_payer_fee_juice_balance_pre_existing_public_data_index: Option, } impl BaseRollupInputsBuilder { @@ -631,28 +686,31 @@ mod tests { fn build_fee_payer_fee_juice_balance_read_hint( self, - start_public_data_tree: NonEmptyMerkleTree + start_public_data_tree: NonEmptyMerkleTree, ) -> PublicDataHint { self.fee_payer_fee_juice_balance_pre_existing_public_data_index.map_or( PublicDataHint::empty(), |leaf_index_u32: u32| { let leaf_index = leaf_index_u32 as Field; let leaf_preimage = self.pre_existing_public_data[leaf_index]; - let membership_witness = MembershipWitness { leaf_index, sibling_path: start_public_data_tree.get_sibling_path(leaf_index_u32) }; + let membership_witness = MembershipWitness { + leaf_index, + sibling_path: start_public_data_tree.get_sibling_path(leaf_index_u32), + }; PublicDataHint { leaf_slot: leaf_preimage.slot, value: leaf_preimage.value, override_counter: 0, membership_witness, - leaf_preimage + leaf_preimage, } - } + }, ) } fn extract_subtree_sibling_path( path: [Field; FULL_HEIGHT], - mut sibling_path: [Field; SIBLING_PATH_LENGTH] + mut sibling_path: [Field; SIBLING_PATH_LENGTH], ) -> [Field; SIBLING_PATH_LENGTH] { let subtree_height = FULL_HEIGHT - SIBLING_PATH_LENGTH; for i in subtree_height..FULL_HEIGHT { @@ -665,15 +723,17 @@ mod tests { mut self, nullifier_tree: &mut NonEmptyMerkleTree, kernel_data: &mut KernelData, - start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot + start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot, ) -> ([NullifierLeafPreimage; MAX_NULLIFIERS_PER_TX], [MembershipWitness; MAX_NULLIFIERS_PER_TX], [Field; MAX_NULLIFIERS_PER_TX], [u32; MAX_NULLIFIERS_PER_TX]) { - let mut nullifier_predecessor_preimages = [NullifierLeafPreimage::empty(); MAX_NULLIFIERS_PER_TX]; - let mut low_nullifier_membership_witness = [MembershipWitness::empty(); MAX_NULLIFIERS_PER_TX]; + let mut nullifier_predecessor_preimages = + [NullifierLeafPreimage::empty(); MAX_NULLIFIERS_PER_TX]; + let mut low_nullifier_membership_witness = + [MembershipWitness::empty(); MAX_NULLIFIERS_PER_TX]; let sorted_new_nullifier_tuples = unsafe { get_sorted_tuple( self.nullifiers.storage.map(|insertion: NullifierInsertion| insertion.value), - |a, b| full_field_less_than(b, a) + |a, b| full_field_less_than(b, a), ) }; @@ -706,11 +766,13 @@ mod tests { nullifier_predecessor_preimages[i] = low_preimage; low_nullifier_membership_witness[i] = MembershipWitness { leaf_index: low_index as Field, - sibling_path: nullifier_tree.get_sibling_path(low_index) + sibling_path: nullifier_tree.get_sibling_path(low_index), }; low_preimage.next_nullifier = new_nullifier; - low_preimage.next_index = start_nullifier_tree_snapshot.next_available_leaf_index as u32 + original_index; + low_preimage.next_index = start_nullifier_tree_snapshot + .next_available_leaf_index as u32 + + original_index; pre_existing_nullifiers[low_index] = low_preimage; nullifier_tree.update_leaf(low_index, low_preimage.hash()); @@ -718,7 +780,8 @@ mod tests { } ( - nullifier_predecessor_preimages, low_nullifier_membership_witness, sorted_nullifiers, sorted_nullifiers_indexes + nullifier_predecessor_preimages, low_nullifier_membership_witness, + sorted_nullifiers, sorted_nullifiers_indexes, ) } @@ -729,90 +792,82 @@ mod tests { self.pre_existing_notes, [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT], - [0; NOTE_HASH_SUBTREE_HEIGHT] + [0; NOTE_HASH_SUBTREE_HEIGHT], ); let start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: start_note_hash_tree.get_root(), - next_available_leaf_index: start_note_hash_tree.get_next_available_index() as u32 + next_available_leaf_index: start_note_hash_tree.get_next_available_index() as u32, }; let note_hash_subtree_sibling_path = BaseRollupInputsBuilder::extract_subtree_sibling_path( start_note_hash_tree.get_sibling_path(self.pre_existing_notes.len()), - [0; NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH] + [0; NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH], ); let mut start_nullifier_tree = NonEmptyMerkleTree::new( self.pre_existing_nullifiers.map(|preimage: NullifierLeafPreimage| preimage.hash()), [0; NULLIFIER_TREE_HEIGHT], [0; NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT], - [0; NULLIFIER_SUBTREE_HEIGHT] + [0; NULLIFIER_SUBTREE_HEIGHT], ); let start_nullifier_tree_snapshot = AppendOnlyTreeSnapshot { root: start_nullifier_tree.get_root(), - next_available_leaf_index: start_nullifier_tree.get_next_available_index() as u32 + next_available_leaf_index: start_nullifier_tree.get_next_available_index() as u32, }; let mut start_public_data_tree = NonEmptyMerkleTree::new( - self.pre_existing_public_data.map(|preimage: PublicDataTreeLeafPreimage| preimage.hash()), + self.pre_existing_public_data.map(|preimage: PublicDataTreeLeafPreimage| { + preimage.hash() + }), [0; PUBLIC_DATA_TREE_HEIGHT], [0; PUBLIC_DATA_TREE_HEIGHT - PUBLIC_DATA_SUBTREE_HEIGHT], - [0; PUBLIC_DATA_SUBTREE_HEIGHT] + [0; PUBLIC_DATA_SUBTREE_HEIGHT], ); let start_public_data_tree_snapshot = AppendOnlyTreeSnapshot { root: start_public_data_tree.get_root(), - next_available_leaf_index: start_public_data_tree.get_next_available_index() as u32 + next_available_leaf_index: start_public_data_tree.get_next_available_index() as u32, }; - let fee_payer_fee_juice_balance_read_hint = self.build_fee_payer_fee_juice_balance_read_hint(start_public_data_tree); + let fee_payer_fee_juice_balance_read_hint = + self.build_fee_payer_fee_juice_balance_read_hint(start_public_data_tree); let start_archive = NonEmptyMerkleTree::new( self.pre_existing_blocks, [0; ARCHIVE_HEIGHT], [0; ARCHIVE_HEIGHT - 1], - [0; 1] + [0; 1], ); self.constants.last_archive = AppendOnlyTreeSnapshot { root: start_archive.get_root(), next_available_leaf_index: start_archive.get_next_available_index() as u32, }; - let ( - nullifier_predecessor_preimages, - nullifier_predecessor_membership_witnesses, - sorted_nullifiers, - sorted_nullifier_indexes - ) = self.update_nullifier_tree_with_new_leaves( - &mut start_nullifier_tree, - &mut kernel_data, - start_nullifier_tree_snapshot - ); + let (nullifier_predecessor_preimages, nullifier_predecessor_membership_witnesses, sorted_nullifiers, sorted_nullifier_indexes) = self + .update_nullifier_tree_with_new_leaves( + &mut start_nullifier_tree, + &mut kernel_data, + start_nullifier_tree_snapshot, + ); let nullifier_subtree_sibling_path = BaseRollupInputsBuilder::extract_subtree_sibling_path( start_nullifier_tree.get_sibling_path(self.pre_existing_nullifiers.len()), - [0; NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH] + [0; NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH], ); - let ( - public_data_sibling_path, - sorted_public_data_writes, - sorted_public_data_writes_indexes, - low_public_data_writes_preimages, - low_public_data_writes_witnesses, - _new_subtree - ) = update_public_data_tree( + let (public_data_sibling_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, _new_subtree) = update_public_data_tree( &mut start_public_data_tree, &mut kernel_data, start_public_data_tree_snapshot, self.public_data_writes, self.protocol_public_data_writes, self.final_public_data_writes, - self.pre_existing_public_data + self.pre_existing_public_data, ); let start = PartialStateReference { note_hash_tree: start_note_hash_tree_snapshot, nullifier_tree: start_nullifier_tree_snapshot, - public_data_tree: start_public_data_tree_snapshot + public_data_tree: start_public_data_tree_snapshot, }; let state_diff_hints = StateDiffHints { @@ -822,7 +877,7 @@ mod tests { sorted_nullifier_indexes, note_hash_subtree_sibling_path, nullifier_subtree_sibling_path, - public_data_sibling_path + public_data_sibling_path, }; BaseRollupInputs { @@ -833,16 +888,17 @@ mod tests { sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, - archive_root_membership_witness: MembershipWitness { leaf_index: 0, sibling_path: start_archive.get_sibling_path(0) }, + archive_root_membership_witness: MembershipWitness { + leaf_index: 0, + sibling_path: start_archive.get_sibling_path(0), + }, constants: self.constants, - fee_payer_fee_juice_balance_read_hint + fee_payer_fee_juice_balance_read_hint, } } fn execute(self) -> BaseOrMergeRollupPublicInputs { - let inputs = unsafe { - self.build_inputs() - }; + let inputs = unsafe { self.build_inputs() }; inputs.base_rollup_circuit() } @@ -862,17 +918,20 @@ mod tests { pre_existing_notes: [0; MAX_NOTE_HASHES_PER_TX], pre_existing_nullifiers: [NullifierLeafPreimage::empty(); MAX_NULLIFIERS_PER_TX], pre_existing_contracts: [0; 2], - pre_existing_public_data: [PublicDataTreeLeafPreimage::empty(); MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - pre_existing_blocks: [0; 2], - public_data_reads: BoundedVec::new(), - public_data_writes: BoundedVec::new(), - protocol_public_data_writes: BoundedVec::new(), - final_public_data_writes: BoundedVec::new(), - nullifiers: BoundedVec::new(), - constants: ConstantRollupData::empty(), - fee_payer_fee_juice_balance_pre_existing_public_data_index: Option::none() + pre_existing_public_data: [ + PublicDataTreeLeafPreimage::empty(); + MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + ], + pre_existing_blocks: [0; 2], + public_data_reads: BoundedVec::new(), + public_data_writes: BoundedVec::new(), + protocol_public_data_writes: BoundedVec::new(), + final_public_data_writes: BoundedVec::new(), + nullifiers: BoundedVec::new(), + constants: ConstantRollupData::empty(), + fee_payer_fee_juice_balance_pre_existing_public_data_index: Option::none(), + } } - } } #[test] @@ -887,11 +946,14 @@ mod tests { [0; MAX_NOTE_HASHES_PER_TX * 2], [0; NOTE_HASH_TREE_HEIGHT], [0; NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT - 1], - [0; NOTE_HASH_SUBTREE_HEIGHT + 1] + [0; NOTE_HASH_SUBTREE_HEIGHT + 1], ); let outputs = builder.execute(); - let expected_start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), next_available_leaf_index: MAX_NOTE_HASHES_PER_TX as u32 }; + let expected_start_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { + root: expected_commitments_tree.get_root(), + next_available_leaf_index: MAX_NOTE_HASHES_PER_TX as u32, + }; assert(outputs.start.note_hash_tree.eq(expected_start_note_hash_tree_snapshot)); for i in 0..note_hashes.len() { @@ -899,7 +961,7 @@ mod tests { } let expected_end_note_hash_tree_snapshot = AppendOnlyTreeSnapshot { root: expected_commitments_tree.get_root(), - next_available_leaf_index: (MAX_NOTE_HASHES_PER_TX * 2) as u32 + next_available_leaf_index: (MAX_NOTE_HASHES_PER_TX * 2) as u32, }; assert(outputs.end.note_hash_tree.eq(expected_end_note_hash_tree_snapshot)); } @@ -910,19 +972,12 @@ mod tests { // In this special case we will not need to provide sibling paths to check insertion of the nullifier values // This is because 0 values are not actually inserted into the tree, rather the inserted subtree is left // empty to begin with. - let mut builder = BaseRollupInputsBuilder::new(); - builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { - nullifier : 0, - next_nullifier : 7, - next_index : 1, - }; - builder.pre_existing_nullifiers[1] = NullifierLeafPreimage { - nullifier : 7, - next_nullifier : 0, - next_index : 0, - }; + builder.pre_existing_nullifiers[0] = + NullifierLeafPreimage { nullifier: 0, next_nullifier: 7, next_index: 1 }; + builder.pre_existing_nullifiers[1] = + NullifierLeafPreimage { nullifier: 7, next_nullifier: 0, next_index: 0 }; builder.succeeds(); } @@ -931,65 +986,53 @@ mod tests { unconstrained fn nullifier_insertion_test() { let mut builder = BaseRollupInputsBuilder::new(); - builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { - nullifier : 0, - next_nullifier : 7, - next_index : 1, - }; - builder.pre_existing_nullifiers[1] = NullifierLeafPreimage { - nullifier : 7, - next_nullifier : 0, - next_index : 0, - }; + builder.pre_existing_nullifiers[0] = + NullifierLeafPreimage { nullifier: 0, next_nullifier: 7, next_index: 1 }; + builder.pre_existing_nullifiers[1] = + NullifierLeafPreimage { nullifier: 7, next_nullifier: 0, next_index: 0 }; builder.nullifiers.push(NullifierInsertion { existing_index: 0, value: 1 }); let mut tree_nullifiers = [NullifierLeafPreimage::empty(); MAX_NULLIFIERS_PER_TX * 2]; tree_nullifiers[0] = NullifierLeafPreimage { - nullifier : 0, - next_nullifier : 1, - next_index : MAX_NULLIFIERS_PER_TX, + nullifier: 0, + next_nullifier: 1, + next_index: MAX_NULLIFIERS_PER_TX, }; tree_nullifiers[1] = builder.pre_existing_nullifiers[1]; - tree_nullifiers[MAX_NULLIFIERS_PER_TX] = NullifierLeafPreimage { - nullifier : 1, - next_nullifier : 7, - next_index : 1, - }; + tree_nullifiers[MAX_NULLIFIERS_PER_TX] = + NullifierLeafPreimage { nullifier: 1, next_nullifier: 7, next_index: 1 }; let mut end_nullifier_tree = NonEmptyMerkleTree::new( tree_nullifiers.map(|preimage: NullifierLeafPreimage| preimage.hash()), [0; NULLIFIER_TREE_HEIGHT], [0; NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT - 1], - [0; NULLIFIER_SUBTREE_HEIGHT + 1] + [0; NULLIFIER_SUBTREE_HEIGHT + 1], ); let output = builder.execute(); - assert( - output.end.nullifier_tree.eq( - AppendOnlyTreeSnapshot { root: end_nullifier_tree.get_root(), next_available_leaf_index: 2 * MAX_NULLIFIERS_PER_TX as u32 } - ) - ); + assert(output.end.nullifier_tree.eq( + AppendOnlyTreeSnapshot { + root: end_nullifier_tree.get_root(), + next_available_leaf_index: 2 * MAX_NULLIFIERS_PER_TX as u32, + }, + )); } #[test] unconstrained fn new_nullifier_tree_all_larger() { let mut builder = BaseRollupInputsBuilder::new(); - builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { - nullifier : 0, - next_nullifier : 7, - next_index : 1, - }; - builder.pre_existing_nullifiers[1] = NullifierLeafPreimage { - nullifier : 7, - next_nullifier : 0, - next_index : 0, - }; + builder.pre_existing_nullifiers[0] = + NullifierLeafPreimage { nullifier: 0, next_nullifier: 7, next_index: 1 }; + builder.pre_existing_nullifiers[1] = + NullifierLeafPreimage { nullifier: 7, next_nullifier: 0, next_index: 0 }; builder.nullifiers.push(NullifierInsertion { existing_index: 1, value: 8 }); for i in 1..builder.nullifiers.max_len() { - builder.nullifiers.push(NullifierInsertion { existing_index: 1, value: (8 + i) as Field }); + builder.nullifiers.push( + NullifierInsertion { existing_index: 1, value: (8 + i) as Field }, + ); } let output = builder.execute(); @@ -997,53 +1040,48 @@ mod tests { tree_nullifiers[0] = builder.pre_existing_nullifiers[0]; tree_nullifiers[1] = NullifierLeafPreimage { - nullifier : 7, - next_nullifier : 8, - next_index : MAX_NULLIFIERS_PER_TX, + nullifier: 7, + next_nullifier: 8, + next_index: MAX_NULLIFIERS_PER_TX, }; let last_index = builder.nullifiers.max_len() - 1; for i in 0..last_index { tree_nullifiers[MAX_NULLIFIERS_PER_TX + i] = NullifierLeafPreimage { - nullifier : (8 + i) as Field, - next_nullifier : (8 + i + 1) as Field, - next_index : MAX_NULLIFIERS_PER_TX + i + 1, + nullifier: (8 + i) as Field, + next_nullifier: (8 + i + 1) as Field, + next_index: MAX_NULLIFIERS_PER_TX + i + 1, }; } - tree_nullifiers[MAX_NULLIFIERS_PER_TX+last_index] = NullifierLeafPreimage { - nullifier : (8 + last_index) as Field, - next_nullifier : 0, - next_index : 0, + tree_nullifiers[MAX_NULLIFIERS_PER_TX + last_index] = NullifierLeafPreimage { + nullifier: (8 + last_index) as Field, + next_nullifier: 0, + next_index: 0, }; let mut end_nullifier_tree = NonEmptyMerkleTree::new( tree_nullifiers.map(|preimage: NullifierLeafPreimage| preimage.hash()), [0; NULLIFIER_TREE_HEIGHT], [0; NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT - 1], - [0; NULLIFIER_SUBTREE_HEIGHT + 1] + [0; NULLIFIER_SUBTREE_HEIGHT + 1], ); - assert( - output.end.nullifier_tree.eq( - AppendOnlyTreeSnapshot { root: end_nullifier_tree.get_root(), next_available_leaf_index: 2 * MAX_NULLIFIERS_PER_TX as u32 } - ) - ); + assert(output.end.nullifier_tree.eq( + AppendOnlyTreeSnapshot { + root: end_nullifier_tree.get_root(), + next_available_leaf_index: 2 * MAX_NULLIFIERS_PER_TX as u32, + }, + )); } #[test(should_fail_with = "Invalid low leaf")] unconstrained fn new_nullifier_tree_double_spend() { let mut builder = BaseRollupInputsBuilder::new(); - builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { - nullifier : 0, - next_nullifier : 7, - next_index : 1, - }; - builder.pre_existing_nullifiers[1] = NullifierLeafPreimage { - nullifier : 7, - next_nullifier : 0, - next_index : 0, - }; + builder.pre_existing_nullifiers[0] = + NullifierLeafPreimage { nullifier: 0, next_nullifier: 7, next_index: 1 }; + builder.pre_existing_nullifiers[1] = + NullifierLeafPreimage { nullifier: 7, next_nullifier: 0, next_index: 0 }; builder.nullifiers.push(NullifierInsertion { existing_index: 1, value: 8 }); builder.nullifiers.push(NullifierInsertion { existing_index: 1, value: 8 }); @@ -1055,16 +1093,10 @@ mod tests { unconstrained fn new_nullifier_tree_double_spend_same_batch() { let mut builder = BaseRollupInputsBuilder::new(); - builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { - nullifier : 0, - next_nullifier : 7, - next_index : 1, - }; - builder.pre_existing_nullifiers[1] = NullifierLeafPreimage { - nullifier : 7, - next_nullifier : 0, - next_index : 0, - }; + builder.pre_existing_nullifiers[0] = + NullifierLeafPreimage { nullifier: 0, next_nullifier: 7, next_index: 1 }; + builder.pre_existing_nullifiers[1] = + NullifierLeafPreimage { nullifier: 7, next_nullifier: 0, next_index: 0 }; builder.nullifiers.push(NullifierInsertion { existing_index: 1, value: 8 }); builder.nullifiers.push(NullifierInsertion { existing_index: 1, value: 8 }); @@ -1093,16 +1125,25 @@ mod tests { let mut builder = BaseRollupInputsBuilder::new(); for i in 0..MAX_L2_TO_L1_MSGS_PER_TX { - builder.kernel_data.add_exposed_l2_to_l1_message(i as Field, EthAddress::from_field(1 + i as Field)); + builder.kernel_data.add_exposed_l2_to_l1_message( + i as Field, + EthAddress::from_field(1 + i as Field), + ); } let out_hash = builder.execute().out_hash; let siloed_l2_to_l1_msgs = builder.kernel_data.l2_to_l1_msgs.map( - |l2_to_l1_message: ScopedL2ToL1Message| silo_l2_to_l1_message(l2_to_l1_message, builder.constants.global_variables.version, builder.constants.global_variables.chain_id) + |l2_to_l1_message: ScopedL2ToL1Message| silo_l2_to_l1_message( + l2_to_l1_message, + builder.constants.global_variables.version, + builder.constants.global_variables.chain_id, + ), ); // Since we fill the tree completely, we know to expect a full tree as below - let expected_tree = dep::types::merkle_tree::variable_merkle_tree::tests::generate_full_sha_tree(siloed_l2_to_l1_msgs.storage); + let expected_tree = dep::types::merkle_tree::variable_merkle_tree::tests::generate_full_sha_tree( + siloed_l2_to_l1_msgs.storage, + ); assert_eq(out_hash, expected_tree.get_root()); } @@ -1178,22 +1219,19 @@ mod tests { unconstrained fn single_public_state_write() { let mut builder = BaseRollupInputsBuilder::new(); - builder.pre_existing_public_data[0] = PublicDataTreeLeafPreimage { - slot: 27, - value: 28, - next_slot: 0, - next_index: 0, - }; + builder.pre_existing_public_data[0] = + PublicDataTreeLeafPreimage { slot: 27, value: 28, next_slot: 0, next_index: 0 }; builder.public_data_writes.push((0, PublicDataTreeLeaf { slot: 27, value: 29 })); let outputs = builder.execute(); - let updated_leaf = PublicDataTreeLeafPreimage { slot: 27, value: 29, next_slot: 0, next_index: 0 }; + let updated_leaf = + PublicDataTreeLeafPreimage { slot: 27, value: 29, next_slot: 0, next_index: 0 }; let mut expected_public_data_tree = NonEmptyMerkleTree::new( [updated_leaf.hash(), 0], [0; PUBLIC_DATA_TREE_HEIGHT], [0; PUBLIC_DATA_TREE_HEIGHT - 1], - [0; 1] + [0; 1], ); assert_eq(outputs.end.public_data_tree.root, expected_public_data_tree.get_root()); @@ -1203,30 +1241,14 @@ mod tests { unconstrained fn multiple_public_state_read_writes() { let mut builder = BaseRollupInputsBuilder::new(); - builder.pre_existing_public_data[0] = PublicDataTreeLeafPreimage { - slot: 20, - value: 40, - next_slot: 28, - next_index: 1, - }; - builder.pre_existing_public_data[1] = PublicDataTreeLeafPreimage { - slot: 28, - value: 41, - next_slot: 29, - next_index: 2, - }; - builder.pre_existing_public_data[2] = PublicDataTreeLeafPreimage { - slot: 29, - value: 42, - next_slot: 30, - next_index: 3, - }; - builder.pre_existing_public_data[3] = PublicDataTreeLeafPreimage { - slot: 30, - value: 43, - next_slot: 0, - next_index: 0, - }; + builder.pre_existing_public_data[0] = + PublicDataTreeLeafPreimage { slot: 20, value: 40, next_slot: 28, next_index: 1 }; + builder.pre_existing_public_data[1] = + PublicDataTreeLeafPreimage { slot: 28, value: 41, next_slot: 29, next_index: 2 }; + builder.pre_existing_public_data[2] = + PublicDataTreeLeafPreimage { slot: 29, value: 42, next_slot: 30, next_index: 3 }; + builder.pre_existing_public_data[3] = + PublicDataTreeLeafPreimage { slot: 30, value: 43, next_slot: 0, next_index: 0 }; builder.public_data_reads.push(0); builder.public_data_writes.push((0, PublicDataTreeLeaf { slot: 25, value: 60 })); builder.public_data_reads.push(4); @@ -1240,37 +1262,22 @@ mod tests { value: 90, next_slot: 25, next_index: MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - }.hash(); - public_data_leaves[1] = PublicDataTreeLeafPreimage { - slot: 28, - value: 41, - next_slot: 29, - next_index: 2, - }.hash(); - public_data_leaves[2] = PublicDataTreeLeafPreimage { - slot: 29, - value: 42, - next_slot: 30, - next_index: 3, - }.hash(); - public_data_leaves[3] = PublicDataTreeLeafPreimage { - slot: 30, - value: 43, - next_slot: 0, - next_index: 0, - }.hash(); - public_data_leaves[MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = PublicDataTreeLeafPreimage { - slot: 25, - value: 60, - next_slot: 28, - next_index: 1, - }.hash(); + } + .hash(); + public_data_leaves[1] = + PublicDataTreeLeafPreimage { slot: 28, value: 41, next_slot: 29, next_index: 2 }.hash(); + public_data_leaves[2] = + PublicDataTreeLeafPreimage { slot: 29, value: 42, next_slot: 30, next_index: 3 }.hash(); + public_data_leaves[3] = + PublicDataTreeLeafPreimage { slot: 30, value: 43, next_slot: 0, next_index: 0 }.hash(); + public_data_leaves[MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = + PublicDataTreeLeafPreimage { slot: 25, value: 60, next_slot: 28, next_index: 1 }.hash(); let mut expected_public_data_tree = NonEmptyMerkleTree::new( public_data_leaves, [0; PUBLIC_DATA_TREE_HEIGHT], [0; PUBLIC_DATA_TREE_HEIGHT - PUBLIC_DATA_SUBTREE_HEIGHT - 1], - [0; PUBLIC_DATA_SUBTREE_HEIGHT + 1] + [0; PUBLIC_DATA_SUBTREE_HEIGHT + 1], ); assert_eq(outputs.end.public_data_tree.root, expected_public_data_tree.get_root()); @@ -1302,17 +1309,24 @@ mod tests { builder.kernel_data.tx_context.gas_settings.inclusion_fee = tx_fee; // Set expected protocol data update - builder.protocol_public_data_writes.push((0, PublicDataTreeLeaf { slot: balance_slot, value: expected_balance })); + builder.protocol_public_data_writes.push(( + 0, PublicDataTreeLeaf { slot: balance_slot, value: expected_balance }, + )); let outputs = builder.execute(); // The new public data tree should have updated the balance of the fee payer - let updated_leaf = PublicDataTreeLeafPreimage { slot: balance_slot, value: expected_balance, next_slot: 0, next_index: 0 }; + let updated_leaf = PublicDataTreeLeafPreimage { + slot: balance_slot, + value: expected_balance, + next_slot: 0, + next_index: 0, + }; let mut expected_public_data_tree = NonEmptyMerkleTree::new( [updated_leaf.hash(), 0], [0; PUBLIC_DATA_TREE_HEIGHT], [0; PUBLIC_DATA_TREE_HEIGHT - 1], - [0; 1] + [0; 1], ); assert_eq(outputs.end.public_data_tree.root, expected_public_data_tree.get_root()); @@ -1344,21 +1358,30 @@ mod tests { builder.kernel_data.tx_context.gas_settings.inclusion_fee = tx_fee; // Create an existing data update that corresponds to a claim - builder.public_data_writes.push((0, PublicDataTreeLeaf { slot: balance_slot, value: after_claim_balance })); + builder.public_data_writes.push(( + 0, PublicDataTreeLeaf { slot: balance_slot, value: after_claim_balance }, + )); // Set expected data updates after base rollup runs // Note that we tweak the final_public_data_writes directly, since we need to overwrite the output of the user public_data_writes - builder.final_public_data_writes.push((0, PublicDataTreeLeaf { slot: balance_slot, value: expected_balance })); + builder.final_public_data_writes.push(( + 0, PublicDataTreeLeaf { slot: balance_slot, value: expected_balance }, + )); let outputs = builder.execute(); // The new public data tree should have updated the balance of the fee payer - let updated_leaf = PublicDataTreeLeafPreimage { slot: balance_slot, value: expected_balance, next_slot: 0, next_index: 0 }; + let updated_leaf = PublicDataTreeLeafPreimage { + slot: balance_slot, + value: expected_balance, + next_slot: 0, + next_index: 0, + }; let mut expected_public_data_tree = NonEmptyMerkleTree::new( [updated_leaf.hash(), 0], [0; PUBLIC_DATA_TREE_HEIGHT], [0; PUBLIC_DATA_TREE_HEIGHT - 1], - [0; 1] + [0; 1], ); assert_eq(outputs.end.public_data_tree.root, expected_public_data_tree.get_root()); @@ -1390,7 +1413,9 @@ mod tests { builder.kernel_data.tx_context.gas_settings.inclusion_fee = tx_fee; // Set expected protocol data update - builder.protocol_public_data_writes.push((0, PublicDataTreeLeaf { slot: balance_slot, value: -90_000 })); + builder.protocol_public_data_writes.push(( + 0, PublicDataTreeLeaf { slot: balance_slot, value: -90_000 }, + )); builder.fails(); } @@ -1430,7 +1455,9 @@ mod tests { builder.kernel_data.tx_context.gas_settings.inclusion_fee = tx_fee; // Set expected protocol data update - builder.protocol_public_data_writes.push((0, PublicDataTreeLeaf { slot: balance_slot, value: expected_balance })); + builder.protocol_public_data_writes.push(( + 0, PublicDataTreeLeaf { slot: balance_slot, value: expected_balance }, + )); builder.fails(); } @@ -1446,18 +1473,15 @@ mod tests { #[test] fn valid_previous_kernel_tube() { - let builder = unsafe { - BaseRollupInputsBuilder::new_with_previous_kernel(TUBE_INDEX) - }; + let builder = unsafe { BaseRollupInputsBuilder::new_with_previous_kernel(TUBE_INDEX) }; let _res = builder.execute(); } #[test] fn valid_previous_kernel_public_tail() { - let builder = unsafe { - BaseRollupInputsBuilder::new_with_previous_kernel(PUBLIC_KERNEL_TAIL_INDEX) - }; + let builder = + unsafe { BaseRollupInputsBuilder::new_with_previous_kernel(PUBLIC_KERNEL_TAIL_INDEX) }; let _res = builder.execute(); } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr index a214e0d816c..00bcc9e0986 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/state_diff_hints.nr @@ -1,10 +1,10 @@ use dep::types::{ - abis::{nullifier_leaf_preimage::NullifierLeafPreimage}, + abis::nullifier_leaf_preimage::NullifierLeafPreimage, constants::{ - MAX_NULLIFIERS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, - PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_TREE_HEIGHT -}, - merkle_tree::MembershipWitness + MAX_NULLIFIERS_PER_TX, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, + NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, + NULLIFIER_TREE_HEIGHT, + }, merkle_tree::MembershipWitness, }; pub struct StateDiffHints { diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup_inputs.nr index 5ed1dd7c633..66f52d9e0b1 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_merge/block_merge_rollup_inputs.nr @@ -3,13 +3,10 @@ use crate::abis::previous_rollup_block_data::PreviousRollupBlockData; use crate::abis::block_root_or_block_merge_public_inputs::BlockRootOrBlockMergePublicInputs; use crate::components; // TODO(#7346): Currently unused! Will be used when batch rollup circuits are integrated. -global ALLOWED_PREVIOUS_CIRCUITS = [ - BLOCK_ROOT_ROLLUP_INDEX, - BLOCK_MERGE_ROLLUP_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = [BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX]; pub struct BlockMergeRollupInputs { - previous_rollup_data : [PreviousRollupBlockData; 2] + previous_rollup_data: [PreviousRollupBlockData; 2], } impl Empty for BlockMergeRollupInputs { @@ -22,7 +19,6 @@ impl BlockMergeRollupInputs { pub fn block_merge_rollup_circuit(self) -> BlockRootOrBlockMergePublicInputs { // TODO(Lasse): Check both previous rollup vks (in previous_rollup_block_data) against the permitted set of kernel vks. // we don't have a set of permitted kernel vks yet. - // Verify the previous rollup proofs if !dep::std::runtime::is_unconstrained() { self.previous_rollup_data[0].verify(); @@ -42,7 +38,6 @@ impl BlockMergeRollupInputs { // assert(left.num_blocks == right.num_blocks) // if (num_blocks == 1) { assert(vk_witness.index == BLOCK_ROOT_ROLLUP_INDEX) } else { assert(vk_witness.index == BLOCK_MERGE_ROLLUP_INDEX)} // ^ Where instead of num_txs, use num_blocks = (end_global_variables.block_number - start_global_variables.block_number) + 1 - components::assert_prev_block_rollups_follow_on_from_each_other(left, right); let out_hash = components::compute_blocks_out_hash(self.previous_rollup_data); @@ -60,29 +55,33 @@ impl BlockMergeRollupInputs { fees, vk_tree_root: left.vk_tree_root, protocol_contract_tree_root: left.protocol_contract_tree_root, - prover_id: left.prover_id // TODO(#7346): Temporarily added prover_id while we verify block-root proofs on L1 + prover_id: left.prover_id, // TODO(#7346): Temporarily added prover_id while we verify block-root proofs on L1 } } } mod tests { - use crate::{tests::block_merge_rollup_inputs::default_block_merge_rollup_inputs}; - use dep::types::{hash::accumulate_sha256}; - use dep::types::constants::{BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX, ROOT_PARITY_INDEX}; + use crate::tests::block_merge_rollup_inputs::default_block_merge_rollup_inputs; + use dep::types::hash::accumulate_sha256; + use dep::types::constants::{ + BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX, ROOT_PARITY_INDEX, + }; use types::merkle_tree::merkle_tree::MerkleTree; use dep::types::tests::fixtures; #[test(should_fail_with = "input blocks have different chain id")] fn constants_different_chain_id_fails() { let mut inputs = default_block_merge_rollup_inputs(); - inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_global_variables.chain_id = 1; + inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_global_variables.chain_id = + 1; let _output = inputs.block_merge_rollup_circuit(); } #[test(should_fail_with = "input blocks have different chain version")] fn constants_different_ver_fails() { let mut inputs = default_block_merge_rollup_inputs(); - inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_global_variables.version = 1; + inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_global_variables.version = + 1; let _output = inputs.block_merge_rollup_circuit(); } @@ -90,7 +89,8 @@ mod tests { fn previous_rollups_dont_follow_archive() { let mut inputs = default_block_merge_rollup_inputs(); inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.new_archive.root = 0; - inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.previous_archive.root = 1; + inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.previous_archive.root = + 1; let _output = inputs.block_merge_rollup_circuit(); } @@ -98,15 +98,18 @@ mod tests { fn previous_rollups_dont_follow_block_hash() { let mut inputs = default_block_merge_rollup_inputs(); inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_block_hash = 0; - inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.previous_block_hash = 1; + inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.previous_block_hash = + 1; let _output = inputs.block_merge_rollup_circuit(); } #[test(should_fail_with = "input block numbers do not follow on from each other")] fn previous_rollups_dont_follow_block_number() { let mut inputs = default_block_merge_rollup_inputs(); - inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_global_variables.block_number = 2; - inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.start_global_variables.block_number = 1; + inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_global_variables.block_number = + 2; + inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.start_global_variables.block_number = + 1; let _output = inputs.block_merge_rollup_circuit(); } @@ -124,59 +127,61 @@ mod tests { let mut inputs = default_block_merge_rollup_inputs(); let outputs = inputs.block_merge_rollup_circuit(); // TODO(Miranda): Uncomment below when fees are accumulated: components.nr -> accumulate_blocks_fees() - // // Default previous rollup inputs have the same fee recipient, so they should be accumulated into one // let expected_fee_total = inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.fees[0].value // + inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.fees[0].value; // assert_eq(outputs.fees[0].value, expected_fee_total); // assert(is_empty(outputs.fees[1])); - // inputs = default_block_merge_rollup_inputs(); // // Force each previous rollup to have different fee recipients // inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.fees[0].recipient = EthAddress::from_field(2); // let outputs = inputs.block_merge_rollup_circuit(); - assert_eq( - outputs.fees[0], inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.fees[0] + outputs.fees[0], + inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.fees[0], ); assert_eq( - outputs.fees[1], inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.fees[0] + outputs.fees[1], + inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.fees[0], ); } #[test] fn valid_previous_circuit_block_root() { let mut inputs = default_block_merge_rollup_inputs(); - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; - inputs.previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(BLOCK_ROOT_ROLLUP_INDEX); + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; + inputs.previous_rollup_data[0].vk = + fixtures::vk_tree::generate_fake_honk_vk_for_index(BLOCK_ROOT_ROLLUP_INDEX); inputs.previous_rollup_data[0].vk_witness.leaf_index = BLOCK_ROOT_ROLLUP_INDEX as Field; - inputs.previous_rollup_data[0].vk_witness.sibling_path = vk_tree.get_sibling_path(BLOCK_ROOT_ROLLUP_INDEX); + inputs.previous_rollup_data[0].vk_witness.sibling_path = + vk_tree.get_sibling_path(BLOCK_ROOT_ROLLUP_INDEX); let _outputs = inputs.block_merge_rollup_circuit(); } #[test] fn valid_previous_circuit_block_merge() { let mut inputs = default_block_merge_rollup_inputs(); - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; - inputs.previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(BLOCK_MERGE_ROLLUP_INDEX); + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; + inputs.previous_rollup_data[0].vk = + fixtures::vk_tree::generate_fake_honk_vk_for_index(BLOCK_MERGE_ROLLUP_INDEX); inputs.previous_rollup_data[0].vk_witness.leaf_index = BLOCK_MERGE_ROLLUP_INDEX as Field; - inputs.previous_rollup_data[0].vk_witness.sibling_path = vk_tree.get_sibling_path(BLOCK_MERGE_ROLLUP_INDEX); + inputs.previous_rollup_data[0].vk_witness.sibling_path = + vk_tree.get_sibling_path(BLOCK_MERGE_ROLLUP_INDEX); let _outputs = inputs.block_merge_rollup_circuit(); } #[test(should_fail_with = "Invalid vk index")] fn invalid_previous_circuit() { let mut inputs = default_block_merge_rollup_inputs(); - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; - inputs.previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(ROOT_PARITY_INDEX); + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; + inputs.previous_rollup_data[0].vk = + fixtures::vk_tree::generate_fake_honk_vk_for_index(ROOT_PARITY_INDEX); inputs.previous_rollup_data[0].vk_witness.leaf_index = ROOT_PARITY_INDEX as Field; - inputs.previous_rollup_data[0].vk_witness.sibling_path = vk_tree.get_sibling_path(ROOT_PARITY_INDEX); + inputs.previous_rollup_data[0].vk_witness.sibling_path = + vk_tree.get_sibling_path(ROOT_PARITY_INDEX); let _outputs = inputs.block_merge_rollup_circuit(); } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr index 1342f39f789..0b0ee32a8ee 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/block_root_rollup_inputs.nr @@ -1,27 +1,23 @@ use crate::{ abis::{ - previous_rollup_data::PreviousRollupData, - block_root_or_block_merge_public_inputs::{BlockRootOrBlockMergePublicInputs, FeeRecipient} -}, - components + previous_rollup_data::PreviousRollupData, + block_root_or_block_merge_public_inputs::{BlockRootOrBlockMergePublicInputs, FeeRecipient}, + }, components, }; -use parity_lib::{root::root_rollup_parity_input::RootRollupParityInput}; +use parity_lib::root::root_rollup_parity_input::RootRollupParityInput; use types::{ - abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot}, + abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, constants::{ - AZTEC_EPOCH_DURATION, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, L1_TO_L2_MSG_SUBTREE_HEIGHT, - L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, ARCHIVE_HEIGHT, BASE_ROLLUP_INDEX, MERGE_ROLLUP_INDEX -}, - header::Header, content_commitment::ContentCommitment, + AZTEC_EPOCH_DURATION, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, L1_TO_L2_MSG_SUBTREE_HEIGHT, + L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, ARCHIVE_HEIGHT, BASE_ROLLUP_INDEX, + MERGE_ROLLUP_INDEX, + }, header::Header, content_commitment::ContentCommitment, merkle_tree::{append_only_tree, calculate_empty_tree_root}, state_reference::StateReference, - traits::Empty + traits::Empty, }; use types::debug_log::debug_log_format; -global ALLOWED_PREVIOUS_CIRCUITS = [ - BASE_ROLLUP_INDEX, - MERGE_ROLLUP_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = [BASE_ROLLUP_INDEX, MERGE_ROLLUP_INDEX]; pub struct BlockRootRollupInputs { // All below are shared between the base and merge rollups @@ -78,16 +74,19 @@ impl BlockRootRollupInputs { self.l1_to_l2_roots.public_inputs.converted_root, // TODO(Kev): For now we can add a test that this fits inside of // a u8. - L1_TO_L2_MSG_SUBTREE_HEIGHT as u8 + L1_TO_L2_MSG_SUBTREE_HEIGHT as u8, ); - let state = StateReference { l1_to_l2_message_tree: new_l1_to_l2_message_tree_snapshot, partial: right.end }; + let state = StateReference { + l1_to_l2_message_tree: new_l1_to_l2_message_tree_snapshot, + partial: right.end, + }; let content_commitment = ContentCommitment { num_txs: (left.num_txs + right.num_txs) as Field, txs_effects_hash: components::compute_txs_effects_hash(self.previous_rollup_data), in_hash: self.l1_to_l2_roots.public_inputs.sha_root, - out_hash: components::compute_out_hash(self.previous_rollup_data) + out_hash: components::compute_out_hash(self.previous_rollup_data), }; let total_fees = components::accumulate_fees(left, right); @@ -109,13 +108,12 @@ impl BlockRootRollupInputs { // ); // debug_log_format("header.total_fees={0}", [total_fees]); // } - let header = Header { last_archive: left.constants.last_archive, content_commitment, state, global_variables: left.constants.global_variables, - total_fees + total_fees, }; // Build the block hash for this by hashing the header and then insert the new leaf to archive tree. @@ -127,11 +125,12 @@ impl BlockRootRollupInputs { self.new_archive_sibling_path, 0, block_hash, - 0 + 0, ); let mut fee_arr = [FeeRecipient::empty(); AZTEC_EPOCH_DURATION]; - fee_arr[0] = FeeRecipient { recipient: left.constants.global_variables.coinbase, value: total_fees }; + fee_arr[0] = + FeeRecipient { recipient: left.constants.global_variables.coinbase, value: total_fees }; BlockRootOrBlockMergePublicInputs { previous_archive: left.constants.last_archive, // archive before this block was added @@ -144,7 +143,7 @@ impl BlockRootRollupInputs { fees: fee_arr, vk_tree_root: left.constants.vk_tree_root, protocol_contract_tree_root: left.constants.protocol_contract_tree_root, - prover_id: self.prover_id + prover_id: self.prover_id, } } } @@ -160,7 +159,7 @@ impl Empty for BlockRootRollupInputs { start_archive_snapshot: AppendOnlyTreeSnapshot::zero(), new_archive_sibling_path: [0; ARCHIVE_HEIGHT], previous_block_hash: 0, - prover_id: 0 + prover_id: 0, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr index d41e3f67707..7d431741163 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/empty_block_root_rollup_inputs.nr @@ -1,5 +1,7 @@ use crate::abis::block_root_or_block_merge_public_inputs::BlockRootOrBlockMergePublicInputs; -use types::{abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot, global_variables::GlobalVariables}}; +use types::abis::{ + append_only_tree_snapshot::AppendOnlyTreeSnapshot, global_variables::GlobalVariables, +}; use types::constants::AZTEC_EPOCH_DURATION; use crate::abis::block_root_or_block_merge_public_inputs::FeeRecipient; @@ -26,7 +28,7 @@ impl EmptyBlockRootRollupInputs { fees: [FeeRecipient::empty(); AZTEC_EPOCH_DURATION], vk_tree_root: self.vk_tree_root, protocol_contract_tree_root: self.protocol_contract_tree_root, - prover_id: self.prover_id + prover_id: self.prover_id, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr index 2c66ed17d6a..51065ad968c 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/block_root/mod.nr @@ -26,11 +26,17 @@ mod tests { let inputs = default_block_root_rollup_inputs(); let outputs = inputs.block_root_rollup_circuit(); - assert( - outputs.previous_archive.eq(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.last_archive) - ); - assert( - outputs.start_global_variables.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.global_variables) - ); + assert(outputs.previous_archive.eq( + inputs.previous_rollup_data[0] + .base_or_merge_rollup_public_inputs + .constants + .last_archive, + )); + assert(outputs.start_global_variables.eq( + inputs.previous_rollup_data[1] + .base_or_merge_rollup_public_inputs + .constants + .global_variables, + )); } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr index fbf6743982f..b25f9fef8bc 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr @@ -1,23 +1,24 @@ use crate::abis::{ base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs, - block_root_or_block_merge_public_inputs::{BlockRootOrBlockMergePublicInputs, FeeRecipient} + block_root_or_block_merge_public_inputs::{BlockRootOrBlockMergePublicInputs, FeeRecipient}, +}; +use crate::abis::{ + previous_rollup_data::PreviousRollupData, previous_rollup_block_data::PreviousRollupBlockData, }; -use crate::abis::{previous_rollup_data::PreviousRollupData, previous_rollup_block_data::PreviousRollupBlockData}; use dep::types::{ hash::{ - accumulate_sha256, silo_unencrypted_log_hash, compute_tx_logs_hash, silo_encrypted_log_hash, - compute_tx_note_logs_hash -}, - merkle_tree::VariableMerkleTree, + accumulate_sha256, silo_unencrypted_log_hash, compute_tx_logs_hash, silo_encrypted_log_hash, + compute_tx_note_logs_hash, + }, merkle_tree::VariableMerkleTree, constants::{ - AZTEC_EPOCH_DURATION, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, - MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX -}, - utils::{arrays::{array_length, array_merge}}, + AZTEC_EPOCH_DURATION, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, + MAX_L2_TO_L1_MSGS_PER_TX, MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, + }, utils::arrays::{array_length, array_merge}, abis::{ - accumulated_data::CombinedAccumulatedData, public_data_update_request::PublicDataUpdateRequest, - log_hash::{LogHash, ScopedLogHash} -} + accumulated_data::CombinedAccumulatedData, + public_data_update_request::PublicDataUpdateRequest, log_hash::{LogHash, ScopedLogHash}, + }, }; /** @@ -26,7 +27,7 @@ use dep::types::{ */ pub fn assert_txs_filled_from_left( left: BaseOrMergeRollupPublicInputs, - right: BaseOrMergeRollupPublicInputs + right: BaseOrMergeRollupPublicInputs, ) { // assert that the left rollup is either a base (1 tx) or a balanced tree (num txs = power of 2) if (left.rollup_type == 1) { @@ -34,14 +35,17 @@ pub fn assert_txs_filled_from_left( let right_txs = right.num_txs; // See https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 assert( - (left_txs) & (left_txs - 1) == 0, "The rollup should be filled greedily from L to R, but received an unbalanced left subtree" + (left_txs) & (left_txs - 1) == 0, + "The rollup should be filled greedily from L to R, but received an unbalanced left subtree", ); assert( - right_txs <= left_txs, "The rollup should be filled greedily from L to R, but received a L txs < R txs" + right_txs <= left_txs, + "The rollup should be filled greedily from L to R, but received a L txs < R txs", ); } else { assert( - right.rollup_type == 0, "The rollup should be filled greedily from L to R, but received a L base and R merge" + right.rollup_type == 0, + "The rollup should be filled greedily from L to R, but received a L base and R merge", ); } } @@ -52,7 +56,7 @@ pub fn assert_txs_filled_from_left( */ pub fn assert_equal_constants( left: BaseOrMergeRollupPublicInputs, - right: BaseOrMergeRollupPublicInputs + right: BaseOrMergeRollupPublicInputs, ) { assert(left.constants.eq(right.constants), "input proofs have different constants"); } @@ -61,70 +65,86 @@ pub fn assert_equal_constants( // follow on from one-another). Ensures that right uses the tres that was updated by left. pub fn assert_prev_rollups_follow_on_from_each_other( left: BaseOrMergeRollupPublicInputs, - right: BaseOrMergeRollupPublicInputs + right: BaseOrMergeRollupPublicInputs, ) { assert( - left.end.note_hash_tree.eq(right.start.note_hash_tree), "input proofs have different note hash tree snapshots" + left.end.note_hash_tree.eq(right.start.note_hash_tree), + "input proofs have different note hash tree snapshots", ); assert( - left.end.nullifier_tree.eq(right.start.nullifier_tree), "input proofs have different nullifier tree snapshots" + left.end.nullifier_tree.eq(right.start.nullifier_tree), + "input proofs have different nullifier tree snapshots", ); assert( - left.end.public_data_tree.eq(right.start.public_data_tree), "input proofs have different public data tree snapshots" + left.end.public_data_tree.eq(right.start.public_data_tree), + "input proofs have different public data tree snapshots", ); } // TODO(Miranda): split out? pub fn assert_prev_block_rollups_follow_on_from_each_other( left: BlockRootOrBlockMergePublicInputs, - right: BlockRootOrBlockMergePublicInputs + right: BlockRootOrBlockMergePublicInputs, ) { assert(left.vk_tree_root == right.vk_tree_root, "input blocks have different vk tree roots"); assert( - left.protocol_contract_tree_root == right.protocol_contract_tree_root, "input blocks have different protocol contract tree roots" + left.protocol_contract_tree_root == right.protocol_contract_tree_root, + "input blocks have different protocol contract tree roots", ); assert( - left.new_archive.eq(right.previous_archive), "input blocks have different archive tree snapshots" + left.new_archive.eq(right.previous_archive), + "input blocks have different archive tree snapshots", ); assert( - left.end_block_hash.eq(right.previous_block_hash), "input block hashes do not follow on from each other" + left.end_block_hash.eq(right.previous_block_hash), + "input block hashes do not follow on from each other", ); assert( - left.end_global_variables.chain_id == right.start_global_variables.chain_id, "input blocks have different chain id" + left.end_global_variables.chain_id == right.start_global_variables.chain_id, + "input blocks have different chain id", ); assert( - left.end_global_variables.version == right.start_global_variables.version, "input blocks have different chain version" + left.end_global_variables.version == right.start_global_variables.version, + "input blocks have different chain version", ); if right.is_padding() { assert( - left.end_global_variables.block_number == right.start_global_variables.block_number, "input block numbers do not match" + left.end_global_variables.block_number == right.start_global_variables.block_number, + "input block numbers do not match", ); assert( - left.end_global_variables.timestamp == right.start_global_variables.timestamp, "input block timestamps do not match" + left.end_global_variables.timestamp == right.start_global_variables.timestamp, + "input block timestamps do not match", ); } else { assert( - left.end_global_variables.block_number + 1 == right.start_global_variables.block_number, "input block numbers do not follow on from each other" + left.end_global_variables.block_number + 1 == right.start_global_variables.block_number, + "input block numbers do not follow on from each other", ); assert( - left.end_global_variables.timestamp < right.start_global_variables.timestamp, "input block timestamps do not follow on from each other" + left.end_global_variables.timestamp < right.start_global_variables.timestamp, + "input block timestamps do not follow on from each other", ); } } -pub fn accumulate_fees(left: BaseOrMergeRollupPublicInputs, right: BaseOrMergeRollupPublicInputs) -> Field { +pub fn accumulate_fees( + left: BaseOrMergeRollupPublicInputs, + right: BaseOrMergeRollupPublicInputs, +) -> Field { left.accumulated_fees + right.accumulated_fees } pub fn accumulate_blocks_fees( left: BlockRootOrBlockMergePublicInputs, - right: BlockRootOrBlockMergePublicInputs + right: BlockRootOrBlockMergePublicInputs, ) -> [FeeRecipient; AZTEC_EPOCH_DURATION] { let left_len = array_length(left.fees); let right_len = array_length(right.fees); assert( - left_len + right_len <= AZTEC_EPOCH_DURATION, "too many fee payment structs accumulated in rollup" + left_len + right_len <= AZTEC_EPOCH_DURATION, + "too many fee payment structs accumulated in rollup", ); // TODO(Miranda): combine fees with same recipient depending on rollup structure // Assuming that the final rollup tree (block root -> block merge -> root) has max 32 leaves (TODO: constrain in root), then @@ -140,24 +160,20 @@ pub fn accumulate_blocks_fees( * @return out hash stored in 2 fields */ pub fn compute_out_hash(previous_rollup_data: [PreviousRollupData; 2]) -> Field { - accumulate_sha256( - [ + accumulate_sha256([ previous_rollup_data[0].base_or_merge_rollup_public_inputs.out_hash, - previous_rollup_data[1].base_or_merge_rollup_public_inputs.out_hash - ] - ) + previous_rollup_data[1].base_or_merge_rollup_public_inputs.out_hash, + ]) } // TODO(Miranda): combine fns? pub fn compute_blocks_out_hash(previous_rollup_data: [PreviousRollupBlockData; 2]) -> Field { if previous_rollup_data[1].block_root_or_block_merge_public_inputs.is_padding() { previous_rollup_data[0].block_root_or_block_merge_public_inputs.out_hash } else { - accumulate_sha256( - [ + accumulate_sha256([ previous_rollup_data[0].block_root_or_block_merge_public_inputs.out_hash, - previous_rollup_data[1].block_root_or_block_merge_public_inputs.out_hash - ] - ) + previous_rollup_data[1].block_root_or_block_merge_public_inputs.out_hash, + ]) } } @@ -174,37 +190,35 @@ pub fn compute_kernel_out_hash(l2_to_l1_msgs: [Field; MAX_L2_TO_L1_MSGS_PER_TX]) * @return The hash of the transaction effects stored in 2 fields */ pub fn compute_txs_effects_hash(previous_rollup_data: [PreviousRollupData; 2]) -> Field { - accumulate_sha256( - [ + accumulate_sha256([ previous_rollup_data[0].base_or_merge_rollup_public_inputs.txs_effects_hash, - previous_rollup_data[1].base_or_merge_rollup_public_inputs.txs_effects_hash - ] - ) + previous_rollup_data[1].base_or_merge_rollup_public_inputs.txs_effects_hash, + ]) } -fn silo_and_hash_unencrypted_logs(unencrypted_logs_hashes: [ScopedLogHash; MAX_UNENCRYPTED_LOGS_PER_TX]) -> Field { - let siloed_logs = unencrypted_logs_hashes.map( - |log: ScopedLogHash| { +fn silo_and_hash_unencrypted_logs( + unencrypted_logs_hashes: [ScopedLogHash; MAX_UNENCRYPTED_LOGS_PER_TX], +) -> Field { + let siloed_logs = unencrypted_logs_hashes.map(|log: ScopedLogHash| { LogHash { value: silo_unencrypted_log_hash(log), counter: log.log_hash.counter, - length: log.log_hash.length + length: log.log_hash.length, } - } - ); + }); compute_tx_logs_hash(siloed_logs) } -fn silo_and_hash_encrypted_logs(encrypted_logs_hashes: [ScopedLogHash; MAX_UNENCRYPTED_LOGS_PER_TX]) -> Field { - let siloed_encrypted_logs = encrypted_logs_hashes.map( - |log: ScopedLogHash| { +fn silo_and_hash_encrypted_logs( + encrypted_logs_hashes: [ScopedLogHash; MAX_UNENCRYPTED_LOGS_PER_TX], +) -> Field { + let siloed_encrypted_logs = encrypted_logs_hashes.map(|log: ScopedLogHash| { LogHash { value: silo_encrypted_log_hash(log), counter: log.log_hash.counter, - length: log.log_hash.length + length: log.log_hash.length, } - } - ); + }); compute_tx_logs_hash(siloed_encrypted_logs) } @@ -223,7 +237,14 @@ fn silo_and_hash_encrypted_logs(encrypted_logs_hashes: [ScopedLogHash; MAX_UNENC // 1 note encrypted logs hash --> 1 sha256 hash -> 31 bytes -> 1 fields | Beware when populating bytes that we fill (prepend) to 32! | // 1 encrypted logs hash --> 1 sha256 hash -> 31 bytes -> 1 fields | Beware when populating bytes that we fill (prepend) to 32! | -> 3 types of logs - 3 fields for its hashes // 1 unencrypted logs hash --> 1 sha256 hash -> 31 bytes -> 1 fields | Beware when populating bytes that we fill (prepend) to 32! __| -global TX_EFFECTS_HASH_INPUT_FIELDS = 1 + 1 + MAX_NOTE_HASHES_PER_TX + MAX_NULLIFIERS_PER_TX + 1 + MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + 3 + 3; +global TX_EFFECTS_HASH_INPUT_FIELDS = 1 + + 1 + + MAX_NOTE_HASHES_PER_TX + + MAX_NULLIFIERS_PER_TX + + 1 + + MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + + 3 + + 3; // Computes the tx effects hash for a base rollup (a single transaction) pub fn compute_tx_effects_hash( @@ -231,7 +252,7 @@ pub fn compute_tx_effects_hash( revert_code: u8, transaction_fee: Field, all_public_data_update_requests: [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - out_hash: Field + out_hash: Field, ) -> Field { let mut tx_effects_hash_input = [0; TX_EFFECTS_HASH_INPUT_FIELDS]; @@ -240,7 +261,8 @@ pub fn compute_tx_effects_hash( // Public writes are the concatenation of all non-empty user update requests and protocol update requests, then padded with zeroes. // The incoming all_public_data_update_requests may have empty update requests in the middle, so we move those to the end of the array. - let public_data_update_requests = get_all_update_requests_for_tx_effects(all_public_data_update_requests); + let public_data_update_requests = + get_all_update_requests_for_tx_effects(all_public_data_update_requests); let note_logs_length = combined.note_encrypted_log_preimages_length; let encrypted_logs_length = combined.encrypted_log_preimages_length; let unencrypted_logs_length = combined.unencrypted_log_preimages_length; @@ -263,13 +285,13 @@ pub fn compute_tx_effects_hash( for j in 0..MAX_NOTE_HASHES_PER_TX { tx_effects_hash_input[offset + j] = note_hashes[j]; } - offset += MAX_NOTE_HASHES_PER_TX ; + offset += MAX_NOTE_HASHES_PER_TX; // NULLIFIERS for j in 0..MAX_NULLIFIERS_PER_TX { tx_effects_hash_input[offset + j] = nullifiers[j]; } - offset += MAX_NULLIFIERS_PER_TX ; + offset += MAX_NULLIFIERS_PER_TX; // L2 TO L1 MESSAGES tx_effects_hash_input[offset] = out_hash; @@ -277,10 +299,8 @@ pub fn compute_tx_effects_hash( // PUBLIC DATA UPDATE REQUESTS for j in 0..MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { - tx_effects_hash_input[offset + j * 2] = - public_data_update_requests[j].leaf_slot; - tx_effects_hash_input[offset + j * 2 + 1] = - public_data_update_requests[j].new_value; + tx_effects_hash_input[offset + j * 2] = public_data_update_requests[j].leaf_slot; + tx_effects_hash_input[offset + j * 2 + 1] = public_data_update_requests[j].new_value; } offset += MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2; @@ -309,7 +329,6 @@ pub fn compute_tx_effects_hash( offset += 1; assert_eq(offset, TX_EFFECTS_HASH_INPUT_FIELDS); // Sanity check - let mut hash_input_flattened = [0; TX_EFFECTS_HASH_INPUT_FIELDS * 32]; for offset in 0..TX_EFFECTS_HASH_INPUT_FIELDS { // TODO: This is not checking that the decomposition is smaller than P @@ -323,8 +342,11 @@ pub fn compute_tx_effects_hash( sha_digest } -fn get_all_update_requests_for_tx_effects(all_public_data_update_requests: [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX]) -> [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] { - let mut all_update_requests: BoundedVec = BoundedVec::new(); +fn get_all_update_requests_for_tx_effects( + all_public_data_update_requests: [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], +) -> [PublicDataUpdateRequest; MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] { + let mut all_update_requests: BoundedVec = + BoundedVec::new(); for update_request in all_public_data_update_requests { if !update_request.is_empty() { all_update_requests.push(update_request); @@ -336,12 +358,15 @@ fn get_all_update_requests_for_tx_effects(all_public_data_update_requests: [Publ #[test] fn consistent_TX_EFFECTS_HASH_INPUT_FIELDS() { let expected_size = 1 // revert code - + 1 // transaction fee + + 1 // transaction fee + MAX_NOTE_HASHES_PER_TX + MAX_NULLIFIERS_PER_TX + MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2 + 1 // out hash + 3 // logs lengths + 3; // logs hashes - assert(TX_EFFECTS_HASH_INPUT_FIELDS == expected_size, "tx effects hash input size is incorrect"); + assert( + TX_EFFECTS_HASH_INPUT_FIELDS == expected_size, + "tx effects hash input size is incorrect", + ); } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr index e6e9c7f0755..fdcc1ce5d1a 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/merge/merge_rollup_inputs.nr @@ -1,16 +1,15 @@ use dep::types::{traits::Empty, constants::{BASE_ROLLUP_INDEX, MERGE_ROLLUP_INDEX}}; use crate::abis::previous_rollup_data::PreviousRollupData; -use crate::abis::base_or_merge_rollup_public_inputs::{BaseOrMergeRollupPublicInputs, MERGE_ROLLUP_TYPE}; +use crate::abis::base_or_merge_rollup_public_inputs::{ + BaseOrMergeRollupPublicInputs, MERGE_ROLLUP_TYPE, +}; use crate::components; -global ALLOWED_PREVIOUS_CIRCUITS = [ - BASE_ROLLUP_INDEX, - MERGE_ROLLUP_INDEX, -]; +global ALLOWED_PREVIOUS_CIRCUITS = [BASE_ROLLUP_INDEX, MERGE_ROLLUP_INDEX]; pub struct MergeRollupInputs { // TODO(Kev): Why is this 2? - previous_rollup_data : [PreviousRollupData; 2] + previous_rollup_data: [PreviousRollupData; 2], } impl Empty for MergeRollupInputs { @@ -23,7 +22,6 @@ impl MergeRollupInputs { pub fn merge_rollup_circuit(self) -> BaseOrMergeRollupPublicInputs { // TODO(Lasse): Check both previous rollup vks (in previous_rollup_data) against the permitted set of kernel vks. // we don't have a set of permitted kernel vks yet. - // Verify the previous rollup proofs if !dep::std::runtime::is_unconstrained() { self.previous_rollup_data[0].verify(); @@ -54,7 +52,7 @@ impl MergeRollupInputs { end: right.end, txs_effects_hash, out_hash, - accumulated_fees + accumulated_fees, }; public_inputs @@ -62,7 +60,7 @@ impl MergeRollupInputs { } mod tests { - use crate::{tests::merge_rollup_inputs::default_merge_rollup_inputs}; + use crate::tests::merge_rollup_inputs::default_merge_rollup_inputs; use dep::types::hash::accumulate_sha256; use dep::types::constants::{MERGE_ROLLUP_INDEX, BASE_ROLLUP_INDEX, ROOT_PARITY_INDEX}; use types::merkle_tree::merkle_tree::MerkleTree; @@ -79,24 +77,30 @@ mod tests { #[test(should_fail_with = "input proofs have different constants")] fn constants_different_chain_id_fails() { let mut inputs = default_merge_rollup_inputs(); - inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = 1; - inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = 0; + inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = + 1; + inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = + 0; let _output = inputs.merge_rollup_circuit(); } #[test(should_fail_with = "input proofs have different note hash tree snapshots")] fn previous_rollups_dont_follow_note_hash() { let mut inputs = default_merge_rollup_inputs(); - inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.note_hash_tree.root = 0; - inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.note_hash_tree.root = 1; + inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.note_hash_tree.root = + 0; + inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.note_hash_tree.root = + 1; let _output = inputs.merge_rollup_circuit(); } #[test(should_fail_with = "input proofs have different nullifier tree snapshots")] fn previous_rollups_dont_follow_nullifier() { let mut inputs = default_merge_rollup_inputs(); - inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.nullifier_tree.root = 0; - inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.nullifier_tree.root = 1; + inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.nullifier_tree.root = + 0; + inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.nullifier_tree.root = + 1; let _output = inputs.merge_rollup_circuit(); } @@ -150,7 +154,9 @@ mod tests { let mut inputs = default_merge_rollup_inputs(); let outputs = inputs.merge_rollup_circuit(); - assert(outputs.start.eq(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.start)); + assert(outputs.start.eq( + inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.start, + )); assert(outputs.end.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end)); } @@ -168,25 +174,26 @@ mod tests { let mut inputs = default_merge_rollup_inputs(); let outputs = inputs.merge_rollup_circuit(); - assert( - inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.eq(outputs.constants) - ); - assert( - inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.eq(outputs.constants) - ); + assert(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.eq( + outputs.constants, + )); + assert(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.eq( + outputs.constants, + )); } #[test] fn valid_previous_circuit_base() { let mut inputs = default_merge_rollup_inputs(); - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; - inputs.previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(BASE_ROLLUP_INDEX); + inputs.previous_rollup_data[0].vk = + fixtures::vk_tree::generate_fake_honk_vk_for_index(BASE_ROLLUP_INDEX); inputs.previous_rollup_data[0].vk_witness.leaf_index = BASE_ROLLUP_INDEX as Field; - inputs.previous_rollup_data[0].vk_witness.sibling_path = vk_tree.get_sibling_path(BASE_ROLLUP_INDEX); + inputs.previous_rollup_data[0].vk_witness.sibling_path = + vk_tree.get_sibling_path(BASE_ROLLUP_INDEX); let _outputs = inputs.merge_rollup_circuit(); } @@ -195,13 +202,14 @@ mod tests { fn valid_previous_circuit_merge() { let mut inputs = default_merge_rollup_inputs(); - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; - inputs.previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(MERGE_ROLLUP_INDEX); + inputs.previous_rollup_data[0].vk = + fixtures::vk_tree::generate_fake_honk_vk_for_index(MERGE_ROLLUP_INDEX); inputs.previous_rollup_data[0].vk_witness.leaf_index = MERGE_ROLLUP_INDEX as Field; - inputs.previous_rollup_data[0].vk_witness.sibling_path = vk_tree.get_sibling_path(MERGE_ROLLUP_INDEX); + inputs.previous_rollup_data[0].vk_witness.sibling_path = + vk_tree.get_sibling_path(MERGE_ROLLUP_INDEX); let _outputs = inputs.merge_rollup_circuit(); } @@ -209,12 +217,13 @@ mod tests { #[test(should_fail_with = "Invalid vk index")] fn invalid_previous_circuit() { let mut inputs = default_merge_rollup_inputs(); - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; - inputs.previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(ROOT_PARITY_INDEX); + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; + inputs.previous_rollup_data[0].vk = + fixtures::vk_tree::generate_fake_honk_vk_for_index(ROOT_PARITY_INDEX); inputs.previous_rollup_data[0].vk_witness.leaf_index = ROOT_PARITY_INDEX as Field; - inputs.previous_rollup_data[0].vk_witness.sibling_path = vk_tree.get_sibling_path(ROOT_PARITY_INDEX); + inputs.previous_rollup_data[0].vk_witness.sibling_path = + vk_tree.get_sibling_path(ROOT_PARITY_INDEX); let _outputs = inputs.merge_rollup_circuit(); } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/mod.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/mod.nr index f4cff7750d2..acc9b715235 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/mod.nr @@ -6,7 +6,7 @@ pub use root_rollup_inputs::RootRollupInputs; pub use root_rollup_public_inputs::RootRollupPublicInputs; mod tests { - use crate::{tests::root_rollup_inputs::default_root_rollup_inputs}; + use crate::tests::root_rollup_inputs::default_root_rollup_inputs; use dep::types::hash::accumulate_sha256; #[test] @@ -25,22 +25,25 @@ mod tests { let inputs = default_root_rollup_inputs(); let outputs = inputs.root_rollup_circuit(); - assert( - outputs.previous_archive.eq(inputs.previous_rollup_data[0].block_root_or_block_merge_public_inputs.previous_archive) - ); - - assert( - outputs.end_archive.eq(inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.new_archive) - ); - - assert( - outputs.end_timestamp.eq( - inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_global_variables.timestamp - ) - ); - - assert( - outputs.end_block_hash.eq(inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_block_hash) - ); + assert(outputs.previous_archive.eq( + inputs.previous_rollup_data[0] + .block_root_or_block_merge_public_inputs + .previous_archive, + )); + + assert(outputs.end_archive.eq( + inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.new_archive, + )); + + assert(outputs.end_timestamp.eq( + inputs.previous_rollup_data[1] + .block_root_or_block_merge_public_inputs + .end_global_variables + .timestamp, + )); + + assert(outputs.end_block_hash.eq( + inputs.previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_block_hash, + )); } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup_inputs.nr index ff01e0012c7..5711b1bb5ed 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/root/root_rollup_inputs.nr @@ -1,17 +1,14 @@ use crate::{ abis::previous_rollup_block_data::PreviousRollupBlockData, components, - root::root_rollup_public_inputs::RootRollupPublicInputs + root::root_rollup_public_inputs::RootRollupPublicInputs, }; use types::{ traits::Empty, - constants::{BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX, BLOCK_ROOT_ROLLUP_EMPTY_INDEX} + constants::{BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX, BLOCK_ROOT_ROLLUP_EMPTY_INDEX}, }; // TODO(#7346): Currently unused! Will be used when batch rollup circuits are integrated. -global ALLOWED_PREVIOUS_CIRCUITS = [ - BLOCK_ROOT_ROLLUP_INDEX, - BLOCK_MERGE_ROLLUP_INDEX, - BLOCK_ROOT_ROLLUP_EMPTY_INDEX -]; +global ALLOWED_PREVIOUS_CIRCUITS = + [BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX, BLOCK_ROOT_ROLLUP_EMPTY_INDEX]; pub struct RootRollupInputs { previous_rollup_data: [PreviousRollupBlockData; 2], @@ -20,7 +17,10 @@ pub struct RootRollupInputs { impl Empty for RootRollupInputs { fn empty() -> Self { - RootRollupInputs { previous_rollup_data: [PreviousRollupBlockData::empty(); 2], prover_id: 0 } + RootRollupInputs { + previous_rollup_data: [PreviousRollupBlockData::empty(); 2], + prover_id: 0, + } } } @@ -45,7 +45,6 @@ impl RootRollupInputs { // assert(left.num_blocks == right.num_blocks) // if (num_blocks == 1) { assert(vk_witness.index == BLOCK_ROOT_ROLLUP_INDEX) } else { assert(vk_witness.index == BLOCK_MERGE_ROLLUP_INDEX)} // ^ Where instead of num_txs, use num_blocks = (end_global_variables.block_number - start_global_variables.block_number) + 1 - components::assert_prev_block_rollups_follow_on_from_each_other(left, right); let out_hash = components::compute_blocks_out_hash(self.previous_rollup_data); @@ -63,7 +62,7 @@ impl RootRollupInputs { fees, vk_tree_root: left.vk_tree_root, protocol_contract_tree_root: left.protocol_contract_tree_root, - prover_id: self.prover_id + prover_id: self.prover_id, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/block_root_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/block_root_rollup_inputs.nr index e8c4d2ffbe7..85007c7a404 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/block_root_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/block_root_rollup_inputs.nr @@ -2,10 +2,9 @@ use crate::block_root::block_root_rollup_inputs::BlockRootRollupInputs; use dep::types::{ abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, constants::{ - L1_TO_L2_MSG_TREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, L1_TO_L2_MSG_SUBTREE_HEIGHT, - ARCHIVE_HEIGHT -}, - tests::merkle_tree_utils::compute_zero_hashes + L1_TO_L2_MSG_TREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, + L1_TO_L2_MSG_SUBTREE_HEIGHT, ARCHIVE_HEIGHT, + }, tests::merkle_tree_utils::compute_zero_hashes, }; use crate::tests::previous_rollup_data::default_previous_rollup_data; use crate::tests::l1_to_l2_roots::default_root_rollup_parity_input; @@ -20,7 +19,10 @@ pub fn compute_l1_l2_empty_snapshot() -> (AppendOnlyTreeSnapshot, [Field; L1_TO_ } ( - AppendOnlyTreeSnapshot { root: zero_hashes[zero_hashes.len() - 1], next_available_leaf_index: 0 }, l1_to_l2_message_subtree_sibling_path + AppendOnlyTreeSnapshot { + root: zero_hashes[zero_hashes.len() - 1], + next_available_leaf_index: 0, + }, l1_to_l2_message_subtree_sibling_path, ) } @@ -28,10 +30,13 @@ pub fn compute_archive_snapshot() -> (AppendOnlyTreeSnapshot, [Field; ARCHIVE_HE let zero_hashes = compute_zero_hashes([0; ARCHIVE_HEIGHT]); let mut sibling_path = [0; ARCHIVE_HEIGHT]; for i in 1..ARCHIVE_HEIGHT { - sibling_path[i] = zero_hashes[i-1]; + sibling_path[i] = zero_hashes[i - 1]; } ( - AppendOnlyTreeSnapshot { root: zero_hashes[zero_hashes.len() - 1], next_available_leaf_index: 0 }, sibling_path + AppendOnlyTreeSnapshot { + root: zero_hashes[zero_hashes.len() - 1], + next_available_leaf_index: 0, + }, sibling_path, ) } diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/l1_to_l2_roots.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/l1_to_l2_roots.nr index 22392e83b4e..f67fc7637c5 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/l1_to_l2_roots.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/l1_to_l2_roots.nr @@ -1,15 +1,14 @@ use dep::types::constants::ROOT_PARITY_INDEX; use dep::types::tests::fixtures; -use dep::parity_lib::{root::root_rollup_parity_input::RootRollupParityInput}; +use dep::parity_lib::root::root_rollup_parity_input::RootRollupParityInput; use types::merkle_tree::merkle_tree::MerkleTree; pub fn default_root_rollup_parity_input() -> RootRollupParityInput { let mut input = RootRollupParityInput::empty(); let vk_index = ROOT_PARITY_INDEX; - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; let vk_path = vk_tree.get_sibling_path(vk_index); let vk_tree_root = vk_tree.get_root(); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_block_data.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_block_data.nr index ac0cfefee62..d34e5b3c08f 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_block_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_block_data.nr @@ -9,9 +9,8 @@ pub fn default_previous_rollup_block_data() -> [PreviousRollupBlockData; 2] { let mut previous_rollup_data = [PreviousRollupBlockData::empty(); 2]; let vk_index = BLOCK_ROOT_ROLLUP_INDEX; - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; let vk_path = vk_tree.get_sibling_path(vk_index); let vk_tree_root = vk_tree.get_root(); @@ -21,31 +20,19 @@ pub fn default_previous_rollup_block_data() -> [PreviousRollupBlockData; 2] { previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(vk_index); previous_rollup_data[1].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(vk_index); - previous_rollup_data[0].vk_witness = MembershipWitness { - leaf_index: vk_index as Field, - sibling_path: vk_path - }; - previous_rollup_data[1].vk_witness = MembershipWitness { - leaf_index: vk_index as Field, - sibling_path: vk_path - }; + previous_rollup_data[0].vk_witness = + MembershipWitness { leaf_index: vk_index as Field, sibling_path: vk_path }; + previous_rollup_data[1].vk_witness = + MembershipWitness { leaf_index: vk_index as Field, sibling_path: vk_path }; - previous_rollup_data[0].block_root_or_block_merge_public_inputs.previous_archive = AppendOnlyTreeSnapshot { - root: 0, - next_available_leaf_index: 0 - }; - previous_rollup_data[0].block_root_or_block_merge_public_inputs.new_archive = AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 1 - }; - previous_rollup_data[1].block_root_or_block_merge_public_inputs.previous_archive= AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 1 - }; - previous_rollup_data[1].block_root_or_block_merge_public_inputs.new_archive = AppendOnlyTreeSnapshot { - root: 2, - next_available_leaf_index: 2 - }; + previous_rollup_data[0].block_root_or_block_merge_public_inputs.previous_archive = + AppendOnlyTreeSnapshot { root: 0, next_available_leaf_index: 0 }; + previous_rollup_data[0].block_root_or_block_merge_public_inputs.new_archive = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 1 }; + previous_rollup_data[1].block_root_or_block_merge_public_inputs.previous_archive = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 1 }; + previous_rollup_data[1].block_root_or_block_merge_public_inputs.new_archive = + AppendOnlyTreeSnapshot { root: 2, next_available_leaf_index: 2 }; previous_rollup_data[0].block_root_or_block_merge_public_inputs.previous_block_hash = 1; previous_rollup_data[0].block_root_or_block_merge_public_inputs.end_block_hash = 2; @@ -53,10 +40,14 @@ pub fn default_previous_rollup_block_data() -> [PreviousRollupBlockData; 2] { previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_block_hash = 3; // previous_rollup_data is from one block_root circuit => ecompasses a single block (block 1) - previous_rollup_data[1].block_root_or_block_merge_public_inputs.start_global_variables.block_number = 1; - previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_global_variables.block_number = 1; - previous_rollup_data[1].block_root_or_block_merge_public_inputs.start_global_variables.timestamp = 2; - previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_global_variables.timestamp = 2; + previous_rollup_data[1].block_root_or_block_merge_public_inputs.start_global_variables.block_number = + 1; + previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_global_variables.block_number = + 1; + previous_rollup_data[1].block_root_or_block_merge_public_inputs.start_global_variables.timestamp = + 2; + previous_rollup_data[1].block_root_or_block_merge_public_inputs.end_global_variables.timestamp = + 2; previous_rollup_data[0].block_root_or_block_merge_public_inputs.out_hash = 1; previous_rollup_data[1].block_root_or_block_merge_public_inputs.out_hash = 2; diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_data.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_data.nr index cfcb107eaf6..1bccb203cc4 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/tests/previous_rollup_data.nr @@ -10,77 +10,50 @@ pub fn default_previous_rollup_data() -> [PreviousRollupData; 2] { let mut previous_rollup_data = [PreviousRollupData::empty(); 2]; let vk_index = BASE_ROLLUP_INDEX; - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; let vk_path = vk_tree.get_sibling_path(vk_index); let vk_tree_root = vk_tree.get_root(); - previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.vk_tree_root = vk_tree_root; - previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.vk_tree_root = vk_tree_root; + previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.vk_tree_root = + vk_tree_root; + previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.vk_tree_root = + vk_tree_root; previous_rollup_data[0].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(vk_index); previous_rollup_data[1].vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(vk_index); - previous_rollup_data[0].vk_witness = MembershipWitness { - leaf_index: vk_index as Field, - sibling_path: vk_path - }; - previous_rollup_data[1].vk_witness = MembershipWitness { - leaf_index: vk_index as Field, - sibling_path: vk_path - }; + previous_rollup_data[0].vk_witness = + MembershipWitness { leaf_index: vk_index as Field, sibling_path: vk_path }; + previous_rollup_data[1].vk_witness = + MembershipWitness { leaf_index: vk_index as Field, sibling_path: vk_path }; - previous_rollup_data[0].base_or_merge_rollup_public_inputs.start.note_hash_tree = AppendOnlyTreeSnapshot { - root: 0, - next_available_leaf_index: 0 - }; - previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.note_hash_tree = AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 1 - }; - previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.note_hash_tree = AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 1 - }; - previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.note_hash_tree = AppendOnlyTreeSnapshot { - root: 2, - next_available_leaf_index: 2 - }; + previous_rollup_data[0].base_or_merge_rollup_public_inputs.start.note_hash_tree = + AppendOnlyTreeSnapshot { root: 0, next_available_leaf_index: 0 }; + previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.note_hash_tree = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 1 }; + previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.note_hash_tree = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 1 }; + previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.note_hash_tree = + AppendOnlyTreeSnapshot { root: 2, next_available_leaf_index: 2 }; - previous_rollup_data[0].base_or_merge_rollup_public_inputs.start.nullifier_tree = AppendOnlyTreeSnapshot { - root: 0, - next_available_leaf_index: 0 - }; - previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.nullifier_tree = AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 1 - }; - previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.nullifier_tree = AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 1 - }; - previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.nullifier_tree = AppendOnlyTreeSnapshot { - root: 2, - next_available_leaf_index: 2 - }; + previous_rollup_data[0].base_or_merge_rollup_public_inputs.start.nullifier_tree = + AppendOnlyTreeSnapshot { root: 0, next_available_leaf_index: 0 }; + previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.nullifier_tree = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 1 }; + previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.nullifier_tree = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 1 }; + previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.nullifier_tree = + AppendOnlyTreeSnapshot { root: 2, next_available_leaf_index: 2 }; - previous_rollup_data[0].base_or_merge_rollup_public_inputs.start.public_data_tree = AppendOnlyTreeSnapshot { - root: 0, - next_available_leaf_index: 1 - }; - previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.public_data_tree =AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 2 - }; - previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.public_data_tree = AppendOnlyTreeSnapshot { - root: 1, - next_available_leaf_index: 2 - }; - previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.public_data_tree = AppendOnlyTreeSnapshot { - root: 2, - next_available_leaf_index: 3 - }; + previous_rollup_data[0].base_or_merge_rollup_public_inputs.start.public_data_tree = + AppendOnlyTreeSnapshot { root: 0, next_available_leaf_index: 1 }; + previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.public_data_tree = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 2 }; + previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.public_data_tree = + AppendOnlyTreeSnapshot { root: 1, next_available_leaf_index: 2 }; + previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.public_data_tree = + AppendOnlyTreeSnapshot { root: 2, next_available_leaf_index: 3 }; previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_type = BASE_ROLLUP_TYPE; previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_type = BASE_ROLLUP_TYPE; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr index 6d712c88add..aabd69b5316 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr @@ -1,12 +1,13 @@ use crate::{ - abis::{public_data_update_request::PublicDataUpdateRequest, log_hash::{LogHash, ScopedLogHash}, gas::Gas}, - messaging::l2_to_l1_message::ScopedL2ToL1Message, + abis::{ + public_data_update_request::PublicDataUpdateRequest, log_hash::{LogHash, ScopedLogHash}, + gas::Gas, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, constants::{ - MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, COMBINED_ACCUMULATED_DATA_LENGTH, - MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX -}, - utils::reader::Reader, traits::{Empty, Serialize, Deserialize} + MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, COMBINED_ACCUMULATED_DATA_LENGTH, + MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, + }, utils::reader::Reader, traits::{Empty, Serialize, Deserialize}, }; pub struct CombinedAccumulatedData { @@ -41,8 +42,10 @@ impl Empty for CombinedAccumulatedData { note_encrypted_log_preimages_length: 0, encrypted_log_preimages_length: 0, unencrypted_log_preimages_length: 0, - public_data_update_requests: [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - gas_used: Gas::empty() + public_data_update_requests: [ + PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + ], + gas_used: Gas::empty(), } } } @@ -90,28 +93,28 @@ impl Deserialize for CombinedAccumulatedData { nullifiers: reader.read_array([0; MAX_NULLIFIERS_PER_TX]), l2_to_l1_msgs: reader.read_struct_array( ScopedL2ToL1Message::deserialize, - [ScopedL2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_TX] + [ScopedL2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_TX], ), note_encrypted_logs_hashes: reader.read_struct_array( LogHash::deserialize, - [LogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_TX] + [LogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_TX], ), encrypted_logs_hashes: reader.read_struct_array( ScopedLogHash::deserialize, - [ScopedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX] + [ScopedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX], ), unencrypted_logs_hashes: reader.read_struct_array( ScopedLogHash::deserialize, - [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX] + [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX], ), note_encrypted_log_preimages_length: reader.read(), encrypted_log_preimages_length: reader.read(), unencrypted_log_preimages_length: reader.read(), public_data_update_requests: reader.read_struct_array( PublicDataUpdateRequest::deserialize, - [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] + [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], ), - gas_used: reader.read_struct(Gas::deserialize) + gas_used: reader.read_struct(Gas::deserialize), }; reader.finish(); item @@ -126,14 +129,13 @@ impl Eq for CombinedAccumulatedData { & (self.note_encrypted_logs_hashes == other.note_encrypted_logs_hashes) & (self.encrypted_logs_hashes == other.encrypted_logs_hashes) & (self.unencrypted_logs_hashes == other.unencrypted_logs_hashes) - & (self.note_encrypted_log_preimages_length - == other.note_encrypted_log_preimages_length) - & (self.encrypted_log_preimages_length - == other.encrypted_log_preimages_length) - & (self.unencrypted_log_preimages_length - == other.unencrypted_log_preimages_length) - & (self.public_data_update_requests - == other.public_data_update_requests) + & ( + self.note_encrypted_log_preimages_length + == other.note_encrypted_log_preimages_length + ) + & (self.encrypted_log_preimages_length == other.encrypted_log_preimages_length) + & (self.unencrypted_log_preimages_length == other.unencrypted_log_preimages_length) + & (self.public_data_update_requests == other.public_data_update_requests) & (self.gas_used == other.gas_used) } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr index 75d0abd27ba..421e7c815eb 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr @@ -1,16 +1,15 @@ use crate::{ abis::{ - note_hash::ScopedNoteHash, nullifier::ScopedNullifier, private_call_request::PrivateCallRequest, - public_call_request::PublicCallRequest, - log_hash::{ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash} -}, - traits::{Serialize, Deserialize, Empty}, messaging::l2_to_l1_message::ScopedL2ToL1Message, - utils::reader::Reader + note_hash::ScopedNoteHash, nullifier::ScopedNullifier, + private_call_request::PrivateCallRequest, public_call_request::PublicCallRequest, + log_hash::{ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash}, + }, traits::{Serialize, Deserialize, Empty}, messaging::l2_to_l1_message::ScopedL2ToL1Message, + utils::reader::Reader, }; use crate::constants::{ MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, PRIVATE_ACCUMULATED_DATA_LENGTH + MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, PRIVATE_ACCUMULATED_DATA_LENGTH, }; pub struct PrivateAccumulatedData { @@ -75,36 +74,36 @@ impl Deserialize for PrivateAccumulatedData { let item = PrivateAccumulatedData { note_hashes: reader.read_struct_array( ScopedNoteHash::deserialize, - [ScopedNoteHash::empty(); MAX_NOTE_HASHES_PER_TX] + [ScopedNoteHash::empty(); MAX_NOTE_HASHES_PER_TX], ), nullifiers: reader.read_struct_array( ScopedNullifier::deserialize, - [ScopedNullifier::empty(); MAX_NULLIFIERS_PER_TX] + [ScopedNullifier::empty(); MAX_NULLIFIERS_PER_TX], ), l2_to_l1_msgs: reader.read_struct_array( ScopedL2ToL1Message::deserialize, - [ScopedL2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_TX] + [ScopedL2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_TX], ), note_encrypted_logs_hashes: reader.read_struct_array( NoteLogHash::deserialize, - [NoteLogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_TX] + [NoteLogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_TX], ), encrypted_logs_hashes: reader.read_struct_array( ScopedEncryptedLogHash::deserialize, - [ScopedEncryptedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX] + [ScopedEncryptedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX], ), unencrypted_logs_hashes: reader.read_struct_array( ScopedLogHash::deserialize, - [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX] + [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX], ), public_call_requests: reader.read_struct_array( PublicCallRequest::deserialize, - [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX] + [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], ), private_call_stack: reader.read_struct_array( PrivateCallRequest::deserialize, - [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX] - ) + [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], + ), }; reader.finish(); item @@ -134,7 +133,7 @@ impl Empty for PrivateAccumulatedData { encrypted_logs_hashes: [ScopedEncryptedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX], unencrypted_logs_hashes: [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX], public_call_requests: [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], - private_call_stack: [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX] + private_call_stack: [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr index d0d3c841f63..34933ce092f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr @@ -1,16 +1,15 @@ use crate::{ abis::{ - accumulated_data::{private_accumulated_data::PrivateAccumulatedData}, note_hash::ScopedNoteHash, - nullifier::ScopedNullifier, private_call_request::PrivateCallRequest, - public_call_request::PublicCallRequest, - log_hash::{ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash} -}, + accumulated_data::private_accumulated_data::PrivateAccumulatedData, + note_hash::ScopedNoteHash, nullifier::ScopedNullifier, + private_call_request::PrivateCallRequest, public_call_request::PublicCallRequest, + log_hash::{ScopedEncryptedLogHash, NoteLogHash, ScopedLogHash}, + }, constants::{ - MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX -}, - messaging::l2_to_l1_message::ScopedL2ToL1Message, traits::Empty + MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, traits::Empty, }; pub struct PrivateAccumulatedDataBuilder { @@ -24,7 +23,6 @@ pub struct PrivateAccumulatedDataBuilder { public_call_requests: BoundedVec, private_call_stack: BoundedVec, - } impl PrivateAccumulatedDataBuilder { @@ -37,7 +35,7 @@ impl PrivateAccumulatedDataBuilder { encrypted_logs_hashes: self.encrypted_logs_hashes.storage, unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, public_call_requests: self.public_call_requests.storage, - private_call_stack: self.private_call_stack.storage + private_call_stack: self.private_call_stack.storage, } } } @@ -52,7 +50,7 @@ impl Empty for PrivateAccumulatedDataBuilder { encrypted_logs_hashes: BoundedVec::new(), unencrypted_logs_hashes: BoundedVec::new(), public_call_requests: BoundedVec::new(), - private_call_stack: BoundedVec::new() + private_call_stack: BoundedVec::new(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr index 1eec6ab169e..56fdeb8565a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr @@ -1,16 +1,15 @@ use crate::{ abis::{ - public_data_update_request::PublicDataUpdateRequest, gas::Gas, note_hash::ScopedNoteHash, - nullifier::Nullifier, log_hash::{LogHash, ScopedLogHash}, public_call_request::PublicCallRequest -}, - messaging::l2_to_l1_message::ScopedL2ToL1Message, + public_data_update_request::PublicDataUpdateRequest, gas::Gas, note_hash::ScopedNoteHash, + nullifier::Nullifier, log_hash::{LogHash, ScopedLogHash}, + public_call_request::PublicCallRequest, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, constants::{ - MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS, - PUBLIC_ACCUMULATED_DATA_LENGTH -}, - traits::{Empty, Serialize, Deserialize}, utils::{arrays::array_length, reader::Reader} + MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, + NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS, PUBLIC_ACCUMULATED_DATA_LENGTH, + }, traits::{Empty, Serialize, Deserialize}, utils::{arrays::array_length, reader::Reader}, }; pub struct PublicAccumulatedData { @@ -38,9 +37,11 @@ impl Empty for PublicAccumulatedData { note_encrypted_logs_hashes: [LogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_TX], encrypted_logs_hashes: [ScopedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX], unencrypted_logs_hashes: [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX], - public_data_update_requests: [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + public_data_update_requests: [ + PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + ], public_call_stack: [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], - gas_used: Gas::empty() + gas_used: Gas::empty(), } } } @@ -96,37 +97,37 @@ impl Deserialize for PublicAccumulatedData { let item = PublicAccumulatedData { note_hashes: reader.read_struct_array( ScopedNoteHash::deserialize, - [ScopedNoteHash::empty(); MAX_NOTE_HASHES_PER_TX] + [ScopedNoteHash::empty(); MAX_NOTE_HASHES_PER_TX], ), nullifiers: reader.read_struct_array( Nullifier::deserialize, - [Nullifier::empty(); MAX_NULLIFIERS_PER_TX] + [Nullifier::empty(); MAX_NULLIFIERS_PER_TX], ), l2_to_l1_msgs: reader.read_struct_array( ScopedL2ToL1Message::deserialize, - [ScopedL2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_TX] + [ScopedL2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_TX], ), note_encrypted_logs_hashes: reader.read_struct_array( LogHash::deserialize, - [LogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_TX] + [LogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_TX], ), encrypted_logs_hashes: reader.read_struct_array( ScopedLogHash::deserialize, - [ScopedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX] + [ScopedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_TX], ), unencrypted_logs_hashes: reader.read_struct_array( ScopedLogHash::deserialize, - [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX] + [ScopedLogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_TX], ), public_data_update_requests: reader.read_struct_array( PublicDataUpdateRequest::deserialize, - [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] + [PublicDataUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], ), public_call_stack: reader.read_struct_array( PublicCallRequest::deserialize, - [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX] + [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], ), - gas_used: reader.read_struct(Gas::deserialize) + gas_used: reader.read_struct(Gas::deserialize), }; reader.finish(); item @@ -141,8 +142,7 @@ impl Eq for PublicAccumulatedData { & (self.note_encrypted_logs_hashes == other.note_encrypted_logs_hashes) & (self.encrypted_logs_hashes == other.encrypted_logs_hashes) & (self.unencrypted_logs_hashes == other.unencrypted_logs_hashes) - & (self.public_data_update_requests - == other.public_data_update_requests) + & (self.public_data_update_requests == other.public_data_update_requests) & (self.public_call_stack == other.public_call_stack) & (self.gas_used == other.gas_used) } @@ -169,7 +169,7 @@ impl PublicAccumulatedDataArrayLengths { encrypted_logs_hashes: array_length(data.encrypted_logs_hashes), unencrypted_logs_hashes: array_length(data.unencrypted_logs_hashes), public_data_update_requests: array_length(data.public_data_update_requests), - public_call_stack: array_length(data.public_call_stack) + public_call_stack: array_length(data.public_call_stack), } } } @@ -184,7 +184,7 @@ impl Empty for PublicAccumulatedDataArrayLengths { encrypted_logs_hashes: 0, unencrypted_logs_hashes: 0, public_data_update_requests: 0, - public_call_stack: 0 + public_call_stack: 0, } } } @@ -197,8 +197,7 @@ impl Eq for PublicAccumulatedDataArrayLengths { & (self.note_encrypted_logs_hashes == other.note_encrypted_logs_hashes) & (self.encrypted_logs_hashes == other.encrypted_logs_hashes) & (self.unencrypted_logs_hashes == other.unencrypted_logs_hashes) - & (self.public_data_update_requests - == other.public_data_update_requests) + & (self.public_data_update_requests == other.public_data_update_requests) & (self.public_call_stack == other.public_call_stack) } } @@ -221,7 +220,9 @@ impl Serialize for PublicAccumulatedDataArra } impl Deserialize for PublicAccumulatedDataArrayLengths { - fn deserialize(fields: [Field; NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS]) -> PublicAccumulatedDataArrayLengths { + fn deserialize( + fields: [Field; NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS], + ) -> PublicAccumulatedDataArrayLengths { let mut reader = Reader::new(fields); let item = Self { @@ -232,7 +233,7 @@ impl Deserialize for PublicAccumulatedDataAr encrypted_logs_hashes: reader.read_u32(), unencrypted_logs_hashes: reader.read_u32(), public_data_update_requests: reader.read_u32(), - public_call_stack: reader.read_u32() + public_call_stack: reader.read_u32(), }; reader.finish(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr index e69d6dc7432..ea5958c89e9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr @@ -1,16 +1,14 @@ use crate::{ abis::{ - gas::Gas, accumulated_data::public_accumulated_data::PublicAccumulatedData, - note_hash::ScopedNoteHash, nullifier::Nullifier, public_call_request::PublicCallRequest, - public_data_update_request::PublicDataUpdateRequest, log_hash::{LogHash, ScopedLogHash} -}, - messaging::l2_to_l1_message::ScopedL2ToL1Message, + gas::Gas, accumulated_data::public_accumulated_data::PublicAccumulatedData, + note_hash::ScopedNoteHash, nullifier::Nullifier, public_call_request::PublicCallRequest, + public_data_update_request::PublicDataUpdateRequest, log_hash::{LogHash, ScopedLogHash}, + }, messaging::l2_to_l1_message::ScopedL2ToL1Message, constants::{ - MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX -}, - traits::Empty, utils::arrays::array_to_bounded_vec + MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX, + MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, + }, traits::Empty, utils::arrays::array_to_bounded_vec, }; pub struct PublicAccumulatedDataBuilder { @@ -40,7 +38,7 @@ impl PublicAccumulatedDataBuilder { unencrypted_logs_hashes: array_to_bounded_vec(data.unencrypted_logs_hashes), public_data_update_requests: array_to_bounded_vec(data.public_data_update_requests), public_call_stack: array_to_bounded_vec(data.public_call_stack), - gas_used: data.gas_used + gas_used: data.gas_used, } } @@ -54,7 +52,7 @@ impl PublicAccumulatedDataBuilder { unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage, public_data_update_requests: self.public_data_update_requests.storage, public_call_stack: self.public_call_stack.storage, - gas_used: self.gas_used + gas_used: self.gas_used, } } } @@ -70,7 +68,7 @@ impl Empty for PublicAccumulatedDataBuilder { unencrypted_logs_hashes: BoundedVec::new(), public_data_update_requests: BoundedVec::new(), public_call_stack: BoundedVec::new(), - gas_used: Gas::empty() + gas_used: Gas::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/append_only_tree_snapshot.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/append_only_tree_snapshot.nr index 5967effa446..793b5dc4dc2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/append_only_tree_snapshot.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/append_only_tree_snapshot.nr @@ -1,7 +1,7 @@ pub struct AppendOnlyTreeSnapshot { - root : Field, + root: Field, // TODO(Alvaro) change this to a u64 - next_available_leaf_index : u32 + next_available_leaf_index: u32, } global APPEND_ONLY_TREE_SNAPSHOT_LENGTH: u32 = 2; @@ -11,8 +11,13 @@ impl AppendOnlyTreeSnapshot { [self.root, self.next_available_leaf_index as Field] } - pub fn deserialize(serialized: [Field; APPEND_ONLY_TREE_SNAPSHOT_LENGTH]) -> AppendOnlyTreeSnapshot { - AppendOnlyTreeSnapshot { root: serialized[0], next_available_leaf_index: serialized[1] as u32 } + pub fn deserialize( + serialized: [Field; APPEND_ONLY_TREE_SNAPSHOT_LENGTH], + ) -> AppendOnlyTreeSnapshot { + AppendOnlyTreeSnapshot { + root: serialized[0], + next_available_leaf_index: serialized[1] as u32, + } } pub fn zero() -> Self { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr index 83cddfbd6cb..88cd270c42e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/call_context.nr @@ -1,6 +1,6 @@ use crate::{ - abis::function_selector::FunctionSelector, address::AztecAddress, constants::CALL_CONTEXT_LENGTH, - traits::{Deserialize, Serialize, Empty}, utils::reader::Reader + abis::function_selector::FunctionSelector, address::AztecAddress, + constants::CALL_CONTEXT_LENGTH, traits::{Deserialize, Serialize, Empty}, utils::reader::Reader, }; // docs:start:call-context @@ -41,7 +41,7 @@ impl Deserialize for CallContext { msg_sender: AztecAddress::from_field(reader.read()), contract_address: AztecAddress::from_field(reader.read()), function_selector: FunctionSelector::from_field(reader.read()), - is_static_call: reader.read() as bool + is_static_call: reader.read() as bool, } } } @@ -52,7 +52,7 @@ impl Empty for CallContext { msg_sender: AztecAddress::empty(), contract_address: AztecAddress::empty(), function_selector: FunctionSelector::empty(), - is_static_call: false + is_static_call: false, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/combined_constant_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/combined_constant_data.nr index 09ed2675779..40d0e8b05ae 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/combined_constant_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/combined_constant_data.nr @@ -25,14 +25,14 @@ impl CombinedConstantData { historical_header: Header, tx_context: TxContext, vk_tree_root: Field, - protocol_contract_tree_root: Field + protocol_contract_tree_root: Field, ) -> CombinedConstantData { CombinedConstantData { historical_header, tx_context, vk_tree_root, protocol_contract_tree_root, - global_variables: GlobalVariables::empty() + global_variables: GlobalVariables::empty(), } } } @@ -44,7 +44,7 @@ impl Empty for CombinedConstantData { tx_context: TxContext::empty(), vk_tree_root: 0, protocol_contract_tree_root: 0, - global_variables: GlobalVariables::empty() + global_variables: GlobalVariables::empty(), } } } @@ -74,7 +74,7 @@ impl Deserialize for CombinedConstantData { tx_context: reader.read_struct(TxContext::deserialize), vk_tree_root: reader.read(), protocol_contract_tree_root: reader.read(), - global_variables: reader.read_struct(GlobalVariables::deserialize) + global_variables: reader.read_struct(GlobalVariables::deserialize), }; reader.finish(); item diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/contract_class_function_leaf_preimage.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/contract_class_function_leaf_preimage.nr index 9a6349b4e6d..2e82f407044 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/contract_class_function_leaf_preimage.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/contract_class_function_leaf_preimage.nr @@ -4,18 +4,15 @@ use crate::traits::Hash; use crate::hash::poseidon2_hash_with_separator; pub struct ContractClassFunctionLeafPreimage { - selector : FunctionSelector, - vk_hash : Field, + selector: FunctionSelector, + vk_hash: Field, } impl Hash for ContractClassFunctionLeafPreimage { fn hash(self) -> Field { poseidon2_hash_with_separator( - [ - self.selector.to_field(), - self.vk_hash - ], - GENERATOR_INDEX__FUNCTION_LEAF + [self.selector.to_field(), self.vk_hash], + GENERATOR_INDEX__FUNCTION_LEAF, ) } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/enqueued_call_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/enqueued_call_data.nr index 8aa99d22665..06c8db2ef42 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/enqueued_call_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/enqueued_call_data.nr @@ -1,4 +1,4 @@ -use crate::abis::{kernel_circuit_public_inputs::vm_circuit_public_inputs::VMCircuitPublicInputs}; +use crate::abis::kernel_circuit_public_inputs::vm_circuit_public_inputs::VMCircuitPublicInputs; // Mocked here as the only remaining non-recursive proof pub struct Proof {} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_data.nr index 2e62c732e46..66a337f675f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_data.nr @@ -1,11 +1,11 @@ use crate::{ abis::function_selector::FunctionSelector, constants::FUNCTION_DATA_LENGTH, - traits::{Serialize, Deserialize, Empty} + traits::{Serialize, Deserialize, Empty}, }; pub struct FunctionData { - selector : FunctionSelector, - is_private : bool, + selector: FunctionSelector, + is_private: bool, } impl Eq for FunctionData { @@ -19,16 +19,16 @@ impl Serialize for FunctionData { // TODO(https://github.com/AztecProtocol/aztec-packages/issues/3057): Since, function data can fit into a Field, // This method will simply return a bit packed Field instead of hashing fn serialize(self) -> [Field; FUNCTION_DATA_LENGTH] { - [ - self.selector.to_field(), - self.is_private as Field - ] + [self.selector.to_field(), self.is_private as Field] } } impl Deserialize for FunctionData { fn deserialize(serialized: [Field; FUNCTION_DATA_LENGTH]) -> Self { - Self { selector: FunctionSelector::from_field(serialized[0]), is_private: serialized[1] as bool } + Self { + selector: FunctionSelector::from_field(serialized[0]), + is_private: serialized[1] as bool, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr index 6722a8f25e9..7e742dba38d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/function_selector.nr @@ -67,6 +67,7 @@ fn test_is_valid_selector() { #[test] fn test_long_selector() { - let selector = FunctionSelector::from_signature("foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo"); + let selector = + FunctionSelector::from_signature("foo_and_bar_and_baz_and_foo_bar_baz_and_bar_foo"); assert_eq(selector.to_field(), 0x7590a997); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas.nr index 3225fdbc51d..a485eb7cd14 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas.nr @@ -1,6 +1,6 @@ use crate::{ constants::{GAS_LENGTH, FIXED_DA_GAS, FIXED_L2_GAS}, traits::{Deserialize, Serialize, Empty}, - abis::gas_fees::GasFees + abis::gas_fees::GasFees, }; use std::ops::{Add, Sub}; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr index 004e7321a27..212875f1580 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/gas_settings.nr @@ -1,10 +1,9 @@ use crate::{ abis::{gas::Gas, gas_fees::GasFees}, constants::{ - GAS_SETTINGS_LENGTH, DEFAULT_GAS_LIMIT, DEFAULT_TEARDOWN_GAS_LIMIT, DEFAULT_MAX_FEE_PER_GAS, - DEFAULT_INCLUSION_FEE -}, - traits::{Deserialize, Serialize, Empty}, utils::reader::Reader + GAS_SETTINGS_LENGTH, DEFAULT_GAS_LIMIT, DEFAULT_TEARDOWN_GAS_LIMIT, DEFAULT_MAX_FEE_PER_GAS, + DEFAULT_INCLUSION_FEE, + }, traits::{Deserialize, Serialize, Empty}, utils::reader::Reader, }; pub struct GasSettings { @@ -19,7 +18,7 @@ impl GasSettings { gas_limits: Gas, teardown_gas_limits: Gas, max_fees_per_gas: GasFees, - inclusion_fee: Field + inclusion_fee: Field, ) -> Self { Self { gas_limits, teardown_gas_limits, max_fees_per_gas, inclusion_fee } } @@ -29,7 +28,7 @@ impl GasSettings { Gas::new(DEFAULT_GAS_LIMIT, DEFAULT_GAS_LIMIT), Gas::new(DEFAULT_TEARDOWN_GAS_LIMIT, DEFAULT_TEARDOWN_GAS_LIMIT), GasFees::new(DEFAULT_MAX_FEE_PER_GAS, DEFAULT_MAX_FEE_PER_GAS), - DEFAULT_INCLUSION_FEE + DEFAULT_INCLUSION_FEE, ) } } @@ -69,7 +68,7 @@ impl Deserialize for GasSettings { reader.read_struct(Gas::deserialize), reader.read_struct(Gas::deserialize), reader.read_struct(GasFees::deserialize), - reader.read() + reader.read(), ) } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/global_variables.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/global_variables.nr index 799c9617c75..8980b18b01f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/global_variables.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/global_variables.nr @@ -1,18 +1,19 @@ use crate::{ - address::{AztecAddress, EthAddress}, abis::gas_fees::GasFees, constants::GLOBAL_VARIABLES_LENGTH, - traits::{Deserialize, Empty, Serialize}, utils::reader::Reader + address::{AztecAddress, EthAddress}, abis::gas_fees::GasFees, + constants::GLOBAL_VARIABLES_LENGTH, traits::{Deserialize, Empty, Serialize}, + utils::reader::Reader, }; // docs:start:global-variables pub struct GlobalVariables { - chain_id : Field, - version : Field, - block_number : Field, - slot_number : Field, - timestamp : u64, - coinbase : EthAddress, - fee_recipient : AztecAddress, - gas_fees : GasFees + chain_id: Field, + version: Field, + block_number: Field, + slot_number: Field, + timestamp: u64, + coinbase: EthAddress, + fee_recipient: AztecAddress, + gas_fees: GasFees, } // docs:end:global-variables @@ -57,7 +58,7 @@ impl Deserialize for GlobalVariables { timestamp: reader.read() as u64, coinbase: EthAddress::from_field(reader.read()), fee_recipient: AztecAddress::from_field(reader.read()), - gas_fees: reader.read_struct(GasFees::deserialize) + gas_fees: reader.read_struct(GasFees::deserialize), } } } @@ -85,7 +86,7 @@ impl Empty for GlobalVariables { timestamp: 0, coinbase: EthAddress::empty(), fee_recipient: AztecAddress::empty(), - gas_fees: GasFees::empty() + gas_fees: GasFees::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr index e1fa46b77e8..20aa177237d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr @@ -1,11 +1,10 @@ use crate::{ abis::{ - accumulated_data::CombinedAccumulatedData, combined_constant_data::CombinedConstantData, - validation_requests::RollupValidationRequests, gas_fees::GasFees -}, - address::AztecAddress, partial_state_reference::PartialStateReference, + accumulated_data::CombinedAccumulatedData, combined_constant_data::CombinedConstantData, + validation_requests::RollupValidationRequests, gas_fees::GasFees, + }, address::AztecAddress, partial_state_reference::PartialStateReference, traits::{Empty, Serialize, Deserialize}, constants::KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH, - utils::reader::Reader + utils::reader::Reader, }; pub struct KernelCircuitPublicInputs { @@ -14,7 +13,7 @@ pub struct KernelCircuitPublicInputs { constants: CombinedConstantData, start_state: PartialStateReference, revert_code: u8, - fee_payer: AztecAddress + fee_payer: AztecAddress, } impl KernelCircuitPublicInputs { @@ -32,7 +31,7 @@ impl Empty for KernelCircuitPublicInputs { constants: CombinedConstantData::empty(), start_state: PartialStateReference::empty(), revert_code: 0, - fee_payer: AztecAddress::empty() + fee_payer: AztecAddress::empty(), } } } @@ -66,7 +65,9 @@ impl Serialize for KernelCircuitPublicInput } impl Deserialize for KernelCircuitPublicInputs { - fn deserialize(fields: [Field; KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH]) -> KernelCircuitPublicInputs { + fn deserialize( + fields: [Field; KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH], + ) -> KernelCircuitPublicInputs { let mut reader = Reader::new(fields); let item = Self { rollup_validation_requests: reader.read_struct(RollupValidationRequests::deserialize), @@ -74,7 +75,7 @@ impl Deserialize for KernelCircuitPublicInp constants: reader.read_struct(CombinedConstantData::deserialize), start_state: reader.read_struct(PartialStateReference::deserialize), revert_code: reader.read() as u8, - fee_payer: reader.read_struct(AztecAddress::deserialize) + fee_payer: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); @@ -86,7 +87,7 @@ mod tests { use crate::abis::{ kernel_circuit_public_inputs::kernel_circuit_public_inputs::KernelCircuitPublicInputs, accumulated_data::CombinedAccumulatedData, combined_constant_data::CombinedConstantData, - validation_requests::RollupValidationRequests, gas::Gas, gas_fees::GasFees + validation_requests::RollupValidationRequests, gas::Gas, gas_fees::GasFees, }; use crate::address::AztecAddress; use crate::partial_state_reference::PartialStateReference; @@ -105,13 +106,10 @@ mod tests { constants: CombinedConstantData::empty(), start_state: PartialStateReference::empty(), revert_code: 0, - fee_payer: AztecAddress::empty() + fee_payer: AztecAddress::empty(), }; - inputs.end.gas_used = Gas { - da_gas: 10, - l2_gas: 20 - }; + inputs.end.gas_used = Gas { da_gas: 10, l2_gas: 20 }; inputs.constants.tx_context.gas_settings.inclusion_fee = 42; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/mod.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/mod.nr index 9ae785af23c..cc3ba303c15 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/mod.nr @@ -6,7 +6,9 @@ mod public_kernel_circuit_public_inputs_builder; mod vm_circuit_public_inputs; pub use kernel_circuit_public_inputs::KernelCircuitPublicInputs; -pub use private_kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths}; +pub use private_kernel_circuit_public_inputs::{ + PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsArrayLengths, +}; pub use private_kernel_circuit_public_inputs_builder::PrivateKernelCircuitPublicInputsBuilder; pub use public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs; pub use public_kernel_circuit_public_inputs_builder::PublicKernelCircuitPublicInputsBuilder; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr index a84b06e1a21..992fb75c8f2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr @@ -1,10 +1,9 @@ use crate::{ abis::{ - accumulated_data::PrivateAccumulatedData, combined_constant_data::CombinedConstantData, - public_call_request::PublicCallRequest, validation_requests::PrivateValidationRequests -}, - address::AztecAddress, constants::PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH, - traits::{Serialize, Deserialize, Empty}, utils::{arrays::array_length, reader::Reader} + accumulated_data::PrivateAccumulatedData, combined_constant_data::CombinedConstantData, + public_call_request::PublicCallRequest, validation_requests::PrivateValidationRequests, + }, address::AztecAddress, constants::PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH, + traits::{Serialize, Deserialize, Empty}, utils::{arrays::array_length, reader::Reader}, }; pub struct PrivateKernelCircuitPublicInputsArrayLengths { @@ -24,9 +23,15 @@ pub struct PrivateKernelCircuitPublicInputsArrayLengths { impl PrivateKernelCircuitPublicInputsArrayLengths { pub fn new(public_inputs: PrivateKernelCircuitPublicInputs) -> Self { PrivateKernelCircuitPublicInputsArrayLengths { - note_hash_read_requests: array_length(public_inputs.validation_requests.note_hash_read_requests), - nullifier_read_requests: array_length(public_inputs.validation_requests.nullifier_read_requests), - scoped_key_validation_requests_and_generators: array_length(public_inputs.validation_requests.scoped_key_validation_requests_and_generators), + note_hash_read_requests: array_length( + public_inputs.validation_requests.note_hash_read_requests, + ), + nullifier_read_requests: array_length( + public_inputs.validation_requests.nullifier_read_requests, + ), + scoped_key_validation_requests_and_generators: array_length( + public_inputs.validation_requests.scoped_key_validation_requests_and_generators, + ), note_hashes: array_length(public_inputs.end.note_hashes), nullifiers: array_length(public_inputs.end.nullifiers), l2_to_l1_msgs: array_length(public_inputs.end.l2_to_l1_msgs), @@ -34,7 +39,7 @@ impl PrivateKernelCircuitPublicInputsArrayLengths { encrypted_logs_hashes: array_length(public_inputs.end.encrypted_logs_hashes), unencrypted_logs_hashes: array_length(public_inputs.end.unencrypted_logs_hashes), public_call_requests: array_length(public_inputs.end.public_call_requests), - private_call_stack: array_length(public_inputs.end.private_call_stack) + private_call_stack: array_length(public_inputs.end.private_call_stack), } } @@ -50,7 +55,7 @@ impl PrivateKernelCircuitPublicInputsArrayLengths { encrypted_logs_hashes: 0, unencrypted_logs_hashes: 0, public_call_requests: 0, - private_call_stack: 0 + private_call_stack: 0, } } } @@ -59,15 +64,16 @@ impl Eq for PrivateKernelCircuitPublicInputsArrayLengths { fn eq(self, other: Self) -> bool { (self.note_hash_read_requests == other.note_hash_read_requests) & (self.nullifier_read_requests == other.nullifier_read_requests) - & (self.scoped_key_validation_requests_and_generators - == other.scoped_key_validation_requests_and_generators) + & ( + self.scoped_key_validation_requests_and_generators + == other.scoped_key_validation_requests_and_generators + ) & (self.note_hashes == other.note_hashes) & (self.nullifiers == other.nullifiers) & (self.l2_to_l1_msgs == other.l2_to_l1_msgs) & (self.note_encrypted_logs_hashes == other.note_encrypted_logs_hashes) & (self.encrypted_logs_hashes == other.encrypted_logs_hashes) - & (self.unencrypted_logs_hashes - == other.unencrypted_logs_hashes) + & (self.unencrypted_logs_hashes == other.unencrypted_logs_hashes) & (self.public_call_requests == other.public_call_requests) & (self.private_call_stack == other.private_call_stack) } @@ -79,12 +85,13 @@ pub struct PrivateKernelCircuitPublicInputs { end: PrivateAccumulatedData, constants: CombinedConstantData, public_teardown_call_request: PublicCallRequest, - fee_payer: AztecAddress + fee_payer: AztecAddress, } impl Serialize for PrivateKernelCircuitPublicInputs { fn serialize(self) -> [Field; PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH] { - let mut fields: BoundedVec = BoundedVec::new(); + let mut fields: BoundedVec = + BoundedVec::new(); fields.push(self.min_revertible_side_effect_counter as Field); fields.extend_from_array(self.validation_requests.serialize()); @@ -100,7 +107,9 @@ impl Serialize for PrivateKernelCir } impl Deserialize for PrivateKernelCircuitPublicInputs { - fn deserialize(fields: [Field; PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH]) -> PrivateKernelCircuitPublicInputs { + fn deserialize( + fields: [Field; PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH], + ) -> PrivateKernelCircuitPublicInputs { let mut reader = Reader::new(fields); let item = Self { min_revertible_side_effect_counter: reader.read() as u32, @@ -108,7 +117,7 @@ impl Deserialize for PrivateKernelC end: reader.read_struct(PrivateAccumulatedData::deserialize), constants: reader.read_struct(CombinedConstantData::deserialize), public_teardown_call_request: reader.read_struct(PublicCallRequest::deserialize), - fee_payer: reader.read_struct(AztecAddress::deserialize) + fee_payer: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); @@ -134,7 +143,7 @@ impl Empty for PrivateKernelCircuitPublicInputs { end: PrivateAccumulatedData::empty(), constants: CombinedConstantData::empty(), public_teardown_call_request: PublicCallRequest::empty(), - fee_payer: AztecAddress::empty() + fee_payer: AztecAddress::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr index 8c84cf9b8b8..94a770fbf9d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr @@ -1,10 +1,11 @@ use crate::{ abis::{ - accumulated_data::PrivateAccumulatedDataBuilder, combined_constant_data::CombinedConstantData, - kernel_circuit_public_inputs::private_kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, - public_call_request::PublicCallRequest, validation_requests::PrivateValidationRequestsBuilder -}, - address::AztecAddress, traits::Empty + accumulated_data::PrivateAccumulatedDataBuilder, + combined_constant_data::CombinedConstantData, + kernel_circuit_public_inputs::private_kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + public_call_request::PublicCallRequest, + validation_requests::PrivateValidationRequestsBuilder, + }, address::AztecAddress, traits::Empty, }; pub struct PrivateKernelCircuitPublicInputsBuilder { @@ -13,7 +14,7 @@ pub struct PrivateKernelCircuitPublicInputsBuilder { end: PrivateAccumulatedDataBuilder, constants: CombinedConstantData, public_teardown_call_request: PublicCallRequest, - fee_payer: AztecAddress + fee_payer: AztecAddress, } impl PrivateKernelCircuitPublicInputsBuilder { @@ -24,7 +25,7 @@ impl PrivateKernelCircuitPublicInputsBuilder { end: self.end.finish(), constants: self.constants, public_teardown_call_request: self.public_teardown_call_request, - fee_payer: self.fee_payer + fee_payer: self.fee_payer, } } } @@ -37,7 +38,7 @@ impl Empty for PrivateKernelCircuitPublicInputsBuilder { end: PrivateAccumulatedDataBuilder::empty(), constants: CombinedConstantData::empty(), public_teardown_call_request: PublicCallRequest::empty(), - fee_payer: AztecAddress::empty() + fee_payer: AztecAddress::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr index 5f3351423e5..341a839e2bc 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr @@ -1,10 +1,9 @@ use crate::{ abis::{ - accumulated_data::PublicAccumulatedData, combined_constant_data::CombinedConstantData, - public_call_request::PublicCallRequest, validation_requests::PublicValidationRequests -}, - address::AztecAddress, constants::PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH, - traits::{Empty, Serialize, Deserialize}, utils::reader::Reader + accumulated_data::PublicAccumulatedData, combined_constant_data::CombinedConstantData, + public_call_request::PublicCallRequest, validation_requests::PublicValidationRequests, + }, address::AztecAddress, constants::PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH, + traits::{Empty, Serialize, Deserialize}, utils::reader::Reader, }; pub struct PublicKernelCircuitPublicInputs { @@ -28,14 +27,15 @@ impl Empty for PublicKernelCircuitPublicInputs { end_side_effect_counter: 0, public_teardown_call_request: PublicCallRequest::empty(), fee_payer: AztecAddress::empty(), - revert_code: 0 + revert_code: 0, } } } impl Serialize for PublicKernelCircuitPublicInputs { fn serialize(self) -> [Field; PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH] { - let mut fields: BoundedVec = BoundedVec::new(); + let mut fields: BoundedVec = + BoundedVec::new(); fields.extend_from_array(self.constants.serialize()); fields.extend_from_array(self.validation_requests.serialize()); @@ -53,7 +53,9 @@ impl Serialize for PublicKernelCircu } impl Deserialize for PublicKernelCircuitPublicInputs { - fn deserialize(fields: [Field; PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH]) -> PublicKernelCircuitPublicInputs { + fn deserialize( + fields: [Field; PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH], + ) -> PublicKernelCircuitPublicInputs { let mut reader = Reader::new(fields); let item = PublicKernelCircuitPublicInputs { @@ -64,7 +66,7 @@ impl Deserialize for PublicKernelCir end_side_effect_counter: reader.read_u32(), public_teardown_call_request: reader.read_struct(PublicCallRequest::deserialize), fee_payer: reader.read_struct(AztecAddress::deserialize), - revert_code: reader.read() as u8 + revert_code: reader.read() as u8, }; reader.finish(); item diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr index e40de7784e9..87d4a1f7e37 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr @@ -1,10 +1,11 @@ use crate::{ abis::{ - accumulated_data::PublicAccumulatedDataBuilder, combined_constant_data::CombinedConstantData, - kernel_circuit_public_inputs::{public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs}, - public_call_request::PublicCallRequest, validation_requests::PublicValidationRequestsBuilder -}, - address::AztecAddress, traits::Empty + accumulated_data::PublicAccumulatedDataBuilder, + combined_constant_data::CombinedConstantData, + kernel_circuit_public_inputs::public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + public_call_request::PublicCallRequest, + validation_requests::PublicValidationRequestsBuilder, + }, address::AztecAddress, traits::Empty, }; pub struct PublicKernelCircuitPublicInputsBuilder { @@ -28,7 +29,7 @@ impl PublicKernelCircuitPublicInputsBuilder { end_side_effect_counter: data.end_side_effect_counter, public_teardown_call_request: data.public_teardown_call_request, fee_payer: data.fee_payer, - revert_code: data.revert_code + revert_code: data.revert_code, } } @@ -44,7 +45,7 @@ impl PublicKernelCircuitPublicInputsBuilder { end_side_effect_counter: self.end_side_effect_counter, public_teardown_call_request: self.public_teardown_call_request, fee_payer: self.fee_payer, - revert_code: self.revert_code + revert_code: self.revert_code, } } } @@ -59,7 +60,7 @@ impl Empty for PublicKernelCircuitPublicInputsBuilder { end_side_effect_counter: 0, public_teardown_call_request: PublicCallRequest::empty(), fee_payer: AztecAddress::empty(), - revert_code: 0 as u8 + revert_code: 0 as u8, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/vm_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/vm_circuit_public_inputs.nr index 8aec60ac157..0c56f0f34bb 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/vm_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/vm_circuit_public_inputs.nr @@ -1,12 +1,11 @@ use crate::{ abis::{ - accumulated_data::{PublicAccumulatedData, PublicAccumulatedDataArrayLengths}, - combined_constant_data::CombinedConstantData, gas::Gas, public_call_request::PublicCallRequest, - public_inner_call_request::PublicInnerCallRequest, - validation_requests::{PublicValidationRequests, PublicValidationRequestArrayLengths} -}, - constants::{MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, VM_CIRCUIT_PUBLIC_INPUTS_LENGTH}, - traits::{Deserialize, Empty, Serialize}, utils::reader::Reader + accumulated_data::{PublicAccumulatedData, PublicAccumulatedDataArrayLengths}, + combined_constant_data::CombinedConstantData, gas::Gas, + public_call_request::PublicCallRequest, public_inner_call_request::PublicInnerCallRequest, + validation_requests::{PublicValidationRequests, PublicValidationRequestArrayLengths}, + }, constants::{MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, VM_CIRCUIT_PUBLIC_INPUTS_LENGTH}, + traits::{Deserialize, Empty, Serialize}, utils::reader::Reader, }; pub struct VMCircuitPublicInputs { @@ -32,7 +31,9 @@ impl Empty for VMCircuitPublicInputs { VMCircuitPublicInputs { constants: CombinedConstantData::empty(), call_request: PublicCallRequest::empty(), - public_call_stack: [PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], + public_call_stack: [ + PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX + ], previous_validation_request_array_lengths: PublicValidationRequestArrayLengths::empty(), validation_requests: PublicValidationRequests::empty(), previous_accumulated_data_array_lengths: PublicAccumulatedDataArrayLengths::empty(), @@ -41,7 +42,7 @@ impl Empty for VMCircuitPublicInputs { end_side_effect_counter: 0, start_gas_left: Gas::empty(), transaction_fee: 0, - reverted: false + reverted: false, } } } @@ -51,16 +52,18 @@ impl Eq for VMCircuitPublicInputs { (self.constants == other.constants) & (self.call_request == other.call_request) & (self.public_call_stack == other.public_call_stack) - & (self.previous_validation_request_array_lengths - == other.previous_validation_request_array_lengths) + & ( + self.previous_validation_request_array_lengths + == other.previous_validation_request_array_lengths + ) & (self.validation_requests == other.validation_requests) - & (self.previous_accumulated_data_array_lengths - == other.previous_accumulated_data_array_lengths) + & ( + self.previous_accumulated_data_array_lengths + == other.previous_accumulated_data_array_lengths + ) & (self.accumulated_data == other.accumulated_data) - & (self.start_side_effect_counter - == other.start_side_effect_counter) - & (self.end_side_effect_counter - == other.end_side_effect_counter) + & (self.start_side_effect_counter == other.start_side_effect_counter) + & (self.end_side_effect_counter == other.end_side_effect_counter) & (self.start_gas_left == other.start_gas_left) & (self.transaction_fee == other.transaction_fee) & (self.reverted == other.reverted) @@ -100,17 +103,21 @@ impl Deserialize for VMCircuitPublicInputs { call_request: reader.read_struct(PublicCallRequest::deserialize), public_call_stack: reader.read_struct_array( PublicInnerCallRequest::deserialize, - [PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX] + [PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], + ), + previous_validation_request_array_lengths: reader.read_struct( + PublicValidationRequestArrayLengths::deserialize, ), - previous_validation_request_array_lengths: reader.read_struct(PublicValidationRequestArrayLengths::deserialize), validation_requests: reader.read_struct(PublicValidationRequests::deserialize), - previous_accumulated_data_array_lengths: reader.read_struct(PublicAccumulatedDataArrayLengths::deserialize), + previous_accumulated_data_array_lengths: reader.read_struct( + PublicAccumulatedDataArrayLengths::deserialize, + ), accumulated_data: reader.read_struct(PublicAccumulatedData::deserialize), start_side_effect_counter: reader.read_u32(), end_side_effect_counter: reader.read_u32(), start_gas_left: reader.read_struct(Gas::deserialize), transaction_fee: reader.read(), - reverted: reader.read() as bool + reverted: reader.read() as bool, }; reader.finish(); item diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr index e4fd5d86ce2..92dc2b13ef2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr @@ -1,8 +1,9 @@ use crate::{ abis::kernel_circuit_public_inputs::KernelCircuitPublicInputs, constants::{VK_TREE_HEIGHT, TUBE_INDEX}, merkle_tree::membership::check_membership, - recursion::{proof::NestedRecursiveProof, verification_key::HonkVerificationKey, traits::Verifiable}, - utils::arrays::find_index_hint + recursion::{ + proof::NestedRecursiveProof, verification_key::HonkVerificationKey, traits::Verifiable, + }, utils::arrays::find_index_hint, }; pub struct KernelData { @@ -24,21 +25,20 @@ impl KernelData { fn validate_in_vk_tree(self, allowed_indices: [u32; N]) { self.vk.check_hash(); - let index_hint = unsafe { - find_index_hint(allowed_indices, |index: u32| index == self.vk_index) - }; + let index_hint = + unsafe { find_index_hint(allowed_indices, |index: u32| index == self.vk_index) }; assert(index_hint < N, "Invalid vk index"); assert_eq(allowed_indices[index_hint], self.vk_index, "Invalid vk index"); // TODO(#7410) Remove the exception for the tube index assert( check_membership( - self.vk.hash, - self.vk_index as Field, - self.vk_path, - self.public_inputs.constants.vk_tree_root - ) - | (self.vk_index == TUBE_INDEX) + self.vk.hash, + self.vk_index as Field, + self.vk_path, + self.public_inputs.constants.vk_tree_root, + ) + | (self.vk_index == TUBE_INDEX), ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr index 48de98abbc5..bacd96d4503 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/log_hash.nr @@ -1,10 +1,9 @@ use crate::{ abis::side_effect::{Ordered, OrderedValue, Scoped}, address::AztecAddress, constants::{ - LOG_HASH_LENGTH, NOTE_LOG_HASH_LENGTH, ENCRYPTED_LOG_HASH_LENGTH, SCOPED_LOG_HASH_LENGTH, - SCOPED_ENCRYPTED_LOG_HASH_LENGTH -}, - traits::{Empty, Serialize, Deserialize}, utils::{arrays::array_concat, reader::Reader} + LOG_HASH_LENGTH, NOTE_LOG_HASH_LENGTH, ENCRYPTED_LOG_HASH_LENGTH, SCOPED_LOG_HASH_LENGTH, + SCOPED_ENCRYPTED_LOG_HASH_LENGTH, + }, traits::{Empty, Serialize, Deserialize}, utils::{arrays::array_concat, reader::Reader}, }; pub struct LogHash { @@ -103,7 +102,10 @@ impl Empty for ScopedLogHash { impl Serialize for ScopedLogHash { fn serialize(self) -> [Field; SCOPED_LOG_HASH_LENGTH] { - array_concat(self.log_hash.serialize(), [self.contract_address.to_field()]) + array_concat( + self.log_hash.serialize(), + [self.contract_address.to_field()], + ) } } @@ -112,7 +114,7 @@ impl Deserialize for ScopedLogHash { let mut reader = Reader::new(values); let res = Self { log_hash: reader.read_struct(LogHash::deserialize), - contract_address: reader.read_struct(AztecAddress::deserialize) + contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); res @@ -123,8 +125,12 @@ impl ScopedLogHash { pub fn expose_to_public(self) -> Self { // Hide the counter when exposing to public. Self { - log_hash: LogHash { value: self.log_hash.value, counter: 0, length: self.log_hash.length }, - contract_address: self.contract_address + log_hash: LogHash { + value: self.log_hash.value, + counter: 0, + length: self.log_hash.length, + }, + contract_address: self.contract_address, } } } @@ -174,7 +180,12 @@ impl Serialize for EncryptedLogHash { impl Deserialize for EncryptedLogHash { fn deserialize(values: [Field; ENCRYPTED_LOG_HASH_LENGTH]) -> Self { - Self { value: values[0], counter: values[1] as u32, length: values[2], randomness: values[3] } + Self { + value: values[0], + counter: values[1] as u32, + length: values[2], + randomness: values[3], + } } } @@ -204,7 +215,11 @@ impl ScopedEncryptedLogHash { // Expose as a ScopedLogHash. The contract address is assumed to be masked before calling this. ScopedLogHash { contract_address: self.contract_address, - log_hash: LogHash { value: self.log_hash.value, counter: 0, length: self.log_hash.length } + log_hash: LogHash { + value: self.log_hash.value, + counter: 0, + length: self.log_hash.length, + }, } } } @@ -232,13 +247,19 @@ impl Eq for ScopedEncryptedLogHash { impl Empty for ScopedEncryptedLogHash { fn empty() -> Self { - ScopedEncryptedLogHash { log_hash: EncryptedLogHash::empty(), contract_address: AztecAddress::empty() } + ScopedEncryptedLogHash { + log_hash: EncryptedLogHash::empty(), + contract_address: AztecAddress::empty(), + } } } impl Serialize for ScopedEncryptedLogHash { fn serialize(self) -> [Field; SCOPED_ENCRYPTED_LOG_HASH_LENGTH] { - array_concat(self.log_hash.serialize(), [self.contract_address.to_field()]) + array_concat( + self.log_hash.serialize(), + [self.contract_address.to_field()], + ) } } @@ -247,7 +268,7 @@ impl Deserialize for ScopedEncryptedLogHash { let mut reader = Reader::new(values); let res = Self { log_hash: reader.read_struct(EncryptedLogHash::deserialize), - contract_address: reader.read_struct(AztecAddress::deserialize) + contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); res @@ -308,6 +329,11 @@ impl Serialize for NoteLogHash { impl Deserialize for NoteLogHash { fn deserialize(values: [Field; NOTE_LOG_HASH_LENGTH]) -> Self { - Self { value: values[0], counter: values[1] as u32, length: values[2], note_hash_counter: values[3] as u32 } + Self { + value: values[0], + counter: values[1] as u32, + length: values[2], + note_hash_counter: values[3] as u32, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/max_block_number.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/max_block_number.nr index f9d6a09c372..c2df0f417c9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/max_block_number.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/max_block_number.nr @@ -1,7 +1,7 @@ use crate::{constants::MAX_BLOCK_NUMBER_LENGTH, traits::{Deserialize, Serialize, Empty}}; pub struct MaxBlockNumber { - _opt: Option + _opt: Option, } impl Empty for MaxBlockNumber { @@ -24,7 +24,9 @@ impl Serialize for MaxBlockNumber { impl Deserialize for MaxBlockNumber { fn deserialize(serialized: [Field; MAX_BLOCK_NUMBER_LENGTH]) -> MaxBlockNumber { - MaxBlockNumber { _opt: Option { _is_some: serialized[0] as bool, _value: serialized[1] as u32 } } + MaxBlockNumber { + _opt: Option { _is_some: serialized[0] as bool, _value: serialized[1] as u32 }, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr index 22a2c7e5238..e7096bf0175 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash.nr @@ -2,7 +2,7 @@ use crate::{ abis::read_request::ScopedReadRequest, address::AztecAddress, abis::side_effect::{Ordered, OrderedValue, Readable, Scoped}, constants::{NOTE_HASH_LENGTH, SCOPED_NOTE_HASH_LENGTH}, traits::{Empty, Serialize, Deserialize}, - utils::{arrays::array_concat, reader::Reader} + utils::{arrays::array_concat, reader::Reader}, }; pub struct NoteHash { @@ -91,7 +91,7 @@ impl Serialize for ScopedNoteHash { fn serialize(self) -> [Field; SCOPED_NOTE_HASH_LENGTH] { array_concat( self.note_hash.serialize(), - [self.contract_address.to_field()] + [self.contract_address.to_field()], ) } } @@ -101,7 +101,7 @@ impl Deserialize for ScopedNoteHash { let mut reader = Reader::new(values); let res = Self { note_hash: reader.read_struct(NoteHash::deserialize), - contract_address: reader.read_struct(AztecAddress::deserialize) + contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); res @@ -111,13 +111,18 @@ impl Deserialize for ScopedNoteHash { impl Readable for ScopedNoteHash { fn assert_match_read_request(self, read_request: ScopedReadRequest) { assert_eq( - self.note_hash.value, read_request.value(), "Value of the note hash does not match read request" + self.note_hash.value, + read_request.value(), + "Value of the note hash does not match read request", ); assert_eq( - self.contract_address, read_request.contract_address, "Contract address of the note hash does not match read request" + self.contract_address, + read_request.contract_address, + "Contract address of the note hash does not match read request", ); assert( - read_request.counter() > self.note_hash.counter, "Read request counter must be greater than the counter of the note hash" + read_request.counter() > self.note_hash.counter, + "Read request counter must be greater than the counter of the note hash", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash_leaf_preimage.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash_leaf_preimage.nr index deebd8fb118..1c0cedca919 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash_leaf_preimage.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/note_hash_leaf_preimage.nr @@ -2,11 +2,11 @@ global NOTE_HASH_LEAF_PREIMAGE_LENGTH: u32 = 1; use crate::{ abis::{read_request::ScopedReadRequest, side_effect::Readable}, hash::compute_siloed_note_hash, - merkle_tree::leaf_preimage::LeafPreimage, traits::Empty + merkle_tree::leaf_preimage::LeafPreimage, traits::Empty, }; pub struct NoteHashLeafPreimage { - value : Field, + value: Field, } impl Empty for NoteHashLeafPreimage { @@ -27,8 +27,13 @@ impl LeafPreimage for NoteHashLeafPreimage { impl Readable for NoteHashLeafPreimage { fn assert_match_read_request(self, read_request: ScopedReadRequest) { - let siloed_value = compute_siloed_note_hash(read_request.contract_address, read_request.value()); - assert_eq(self.value, siloed_value, "Value of the note hash leaf does not match read request"); + let siloed_value = + compute_siloed_note_hash(read_request.contract_address, read_request.value()); + assert_eq( + self.value, + siloed_value, + "Value of the note hash leaf does not match read request", + ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr index 93bf2cfec28..834247cec8e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier.nr @@ -2,7 +2,7 @@ use crate::{ abis::{side_effect::{Ordered, OrderedValue, Readable, Scoped}, read_request::ScopedReadRequest}, address::AztecAddress, constants::{NULLIFIER_LENGTH, SCOPED_NULLIFIER_LENGTH}, hash::compute_siloed_nullifier, traits::{Empty, Serialize, Deserialize}, - utils::{arrays::array_concat, reader::Reader} + utils::{arrays::array_concat, reader::Reader}, }; pub struct Nullifier { @@ -56,10 +56,16 @@ impl Readable for Nullifier { fn assert_match_read_request(self, read_request: ScopedReadRequest) { // Public kernels output Nullifier instead of ScopedNullifier. // The nullifier value has been siloed. - let siloed_request_value = compute_siloed_nullifier(read_request.contract_address, read_request.value()); - assert_eq(self.value, siloed_request_value, "Value of the nullifier does not match read request"); + let siloed_request_value = + compute_siloed_nullifier(read_request.contract_address, read_request.value()); + assert_eq( + self.value, + siloed_request_value, + "Value of the nullifier does not match read request", + ); assert( - read_request.counter() > self.counter, "Read request counter must be greater than the counter of the nullifier" + read_request.counter() > self.counter, + "Read request counter must be greater than the counter of the nullifier", ); } } @@ -115,7 +121,7 @@ impl Serialize for ScopedNullifier { fn serialize(self) -> [Field; SCOPED_NULLIFIER_LENGTH] { array_concat( self.nullifier.serialize(), - [self.contract_address.to_field()] + [self.contract_address.to_field()], ) } } @@ -125,7 +131,7 @@ impl Deserialize for ScopedNullifier { let mut reader = Reader::new(values); let res = Self { nullifier: reader.read_struct(Nullifier::deserialize), - contract_address: reader.read_struct(AztecAddress::deserialize) + contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); res @@ -135,13 +141,18 @@ impl Deserialize for ScopedNullifier { impl Readable for ScopedNullifier { fn assert_match_read_request(self, read_request: ScopedReadRequest) { assert_eq( - self.nullifier.value, read_request.value(), "Value of the nullifier does not match read request" + self.nullifier.value, + read_request.value(), + "Value of the nullifier does not match read request", ); assert_eq( - self.contract_address, read_request.contract_address, "Contract address of the nullifier does not match read request" + self.contract_address, + read_request.contract_address, + "Contract address of the nullifier does not match read request", ); assert( - read_request.counter() > self.nullifier.counter, "Read request counter must be greater than the counter of the nullifier" + read_request.counter() > self.nullifier.counter, + "Read request counter must be greater than the counter of the nullifier", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier_leaf_preimage.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier_leaf_preimage.nr index 4321af0c13f..9a957395e6a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier_leaf_preimage.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/nullifier_leaf_preimage.nr @@ -2,13 +2,13 @@ global NULLIFIER_LEAF_PREIMAGE_LENGTH: u32 = 3; use crate::{ abis::{read_request::ScopedReadRequest, side_effect::Readable}, hash::compute_siloed_nullifier, - merkle_tree::leaf_preimage::{LeafPreimage, IndexedTreeLeafPreimage}, traits::{Empty, Hash} + merkle_tree::leaf_preimage::{LeafPreimage, IndexedTreeLeafPreimage}, traits::{Empty, Hash}, }; pub struct NullifierLeafPreimage { - nullifier : Field, - next_nullifier :Field, - next_index : u32, + nullifier: Field, + next_nullifier: Field, + next_index: u32, } impl Empty for NullifierLeafPreimage { @@ -53,8 +53,13 @@ impl IndexedTreeLeafPreimage for NullifierLeafPreimage { impl Readable for NullifierLeafPreimage { fn assert_match_read_request(self, read_request: ScopedReadRequest) { - let siloed_value = compute_siloed_nullifier(read_request.contract_address, read_request.value()); - assert_eq(self.nullifier, siloed_value, "Value of the nullifier leaf does not match read request"); + let siloed_value = + compute_siloed_nullifier(read_request.contract_address, read_request.value()); + assert_eq( + self.nullifier, + siloed_value, + "Value of the nullifier leaf does not match read request", + ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr index e9953d474cb..5165d1ad434 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_call_request.nr @@ -1,7 +1,7 @@ use crate::{ abis::{call_context::CallContext, side_effect::{Ordered, RangeOrdered}}, constants::PRIVATE_CALL_REQUEST_LENGTH, traits::{Empty, Serialize, Deserialize}, - utils::reader::Reader + utils::reader::Reader, }; pub struct PrivateCallRequest { @@ -44,7 +44,7 @@ impl Empty for PrivateCallRequest { args_hash: 0, returns_hash: 0, start_side_effect_counter: 0, - end_side_effect_counter: 0 + end_side_effect_counter: 0, } } } @@ -73,7 +73,7 @@ impl Deserialize for PrivateCallRequest { args_hash: reader.read(), returns_hash: reader.read(), start_side_effect_counter: reader.read_u32(), - end_side_effect_counter: reader.read_u32() + end_side_effect_counter: reader.read_u32(), }; reader.finish(); item diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr index 0c9121a206b..52361319969 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_circuit_public_inputs.nr @@ -1,19 +1,21 @@ use crate::{ abis::{ - call_context::CallContext, max_block_number::MaxBlockNumber, - validation_requests::KeyValidationRequestAndGenerator, note_hash::NoteHash, nullifier::Nullifier, - private_call_request::PrivateCallRequest, public_call_request::PublicCallRequest, - read_request::ReadRequest, log_hash::{LogHash, NoteLogHash, EncryptedLogHash} -}, + call_context::CallContext, max_block_number::MaxBlockNumber, + validation_requests::KeyValidationRequestAndGenerator, note_hash::NoteHash, + nullifier::Nullifier, private_call_request::PrivateCallRequest, + public_call_request::PublicCallRequest, read_request::ReadRequest, + log_hash::{LogHash, NoteLogHash, EncryptedLogHash}, + }, constants::{ - MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, - MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_NOTE_HASHES_PER_CALL, MAX_NULLIFIERS_PER_CALL, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, - MAX_L2_TO_L1_MSGS_PER_CALL, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, MAX_ENCRYPTED_LOGS_PER_CALL, - MAX_UNENCRYPTED_LOGS_PER_CALL, MAX_NOTE_ENCRYPTED_LOGS_PER_CALL -}, - header::Header, messaging::l2_to_l1_message::L2ToL1Message, traits::{Deserialize, Serialize, Empty}, - utils::reader::Reader, transaction::tx_context::TxContext, utils::arrays::validate_array + MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, + MAX_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_NOTE_HASHES_PER_CALL, MAX_NULLIFIERS_PER_CALL, + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, + MAX_L2_TO_L1_MSGS_PER_CALL, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, + MAX_ENCRYPTED_LOGS_PER_CALL, MAX_UNENCRYPTED_LOGS_PER_CALL, + MAX_NOTE_ENCRYPTED_LOGS_PER_CALL, + }, header::Header, messaging::l2_to_l1_message::L2ToL1Message, + traits::{Deserialize, Serialize, Empty}, utils::reader::Reader, + transaction::tx_context::TxContext, utils::arrays::validate_array, }; pub struct PrivateCircuitPublicInputsArrayLengths { @@ -35,7 +37,9 @@ impl PrivateCircuitPublicInputsArrayLengths { PrivateCircuitPublicInputsArrayLengths { note_hash_read_requests: validate_array(public_inputs.note_hash_read_requests), nullifier_read_requests: validate_array(public_inputs.nullifier_read_requests), - key_validation_requests_and_generators: validate_array(public_inputs.key_validation_requests_and_generators), + key_validation_requests_and_generators: validate_array( + public_inputs.key_validation_requests_and_generators, + ), note_hashes: validate_array(public_inputs.note_hashes), nullifiers: validate_array(public_inputs.nullifiers), l2_to_l1_msgs: validate_array(public_inputs.l2_to_l1_msgs), @@ -43,7 +47,7 @@ impl PrivateCircuitPublicInputsArrayLengths { public_call_requests: validate_array(public_inputs.public_call_requests), note_encrypted_logs_hashes: validate_array(public_inputs.note_encrypted_logs_hashes), encrypted_logs_hashes: validate_array(public_inputs.encrypted_logs_hashes), - unencrypted_logs_hashes: validate_array(public_inputs.unencrypted_logs_hashes) + unencrypted_logs_hashes: validate_array(public_inputs.unencrypted_logs_hashes), } } } @@ -71,8 +75,8 @@ pub struct PrivateCircuitPublicInputs { public_teardown_call_request: PublicCallRequest, l2_to_l1_msgs: [L2ToL1Message; MAX_L2_TO_L1_MSGS_PER_CALL], - start_side_effect_counter : u32, - end_side_effect_counter : u32, + start_side_effect_counter: u32, + end_side_effect_counter: u32, note_encrypted_logs_hashes: [NoteLogHash; MAX_NOTE_ENCRYPTED_LOGS_PER_CALL], encrypted_logs_hashes: [EncryptedLogHash; MAX_ENCRYPTED_LOGS_PER_CALL], unencrypted_logs_hashes: [LogHash; MAX_UNENCRYPTED_LOGS_PER_CALL], @@ -91,38 +95,27 @@ impl Eq for PrivateCircuitPublicInputs { self.call_context.eq(other.call_context) & self.args_hash.eq(other.args_hash) & (self.returns_hash == other.returns_hash) - & (self.min_revertible_side_effect_counter - == other.min_revertible_side_effect_counter) + & (self.min_revertible_side_effect_counter == other.min_revertible_side_effect_counter) & (self.is_fee_payer == other.is_fee_payer) & (self.max_block_number == other.max_block_number) & (self.note_hash_read_requests == other.note_hash_read_requests) & (self.nullifier_read_requests == other.nullifier_read_requests) - & (self.key_validation_requests_and_generators - == other.key_validation_requests_and_generators) + & ( + self.key_validation_requests_and_generators + == other.key_validation_requests_and_generators + ) & (self.note_hashes == other.note_hashes) & (self.nullifiers == other.nullifiers) - & (self.private_call_requests - == other.private_call_requests) - & (self.public_call_requests - == other.public_call_requests) - & (self.l2_to_l1_msgs - == other.l2_to_l1_msgs) - & (self.start_side_effect_counter - == other.start_side_effect_counter) - & (self.end_side_effect_counter - == other.end_side_effect_counter) - & (self.note_encrypted_logs_hashes - == other.note_encrypted_logs_hashes) - & (self.encrypted_logs_hashes - == other.encrypted_logs_hashes) - & (self.unencrypted_logs_hashes - == other.unencrypted_logs_hashes) - & self.historical_header.eq( - other.historical_header - ) - & self.tx_context.eq( - other.tx_context - ) + & (self.private_call_requests == other.private_call_requests) + & (self.public_call_requests == other.public_call_requests) + & (self.l2_to_l1_msgs == other.l2_to_l1_msgs) + & (self.start_side_effect_counter == other.start_side_effect_counter) + & (self.end_side_effect_counter == other.end_side_effect_counter) + & (self.note_encrypted_logs_hashes == other.note_encrypted_logs_hashes) + & (self.encrypted_logs_hashes == other.encrypted_logs_hashes) + & (self.unencrypted_logs_hashes == other.unencrypted_logs_hashes) + & self.historical_header.eq(other.historical_header) + & self.tx_context.eq(other.tx_context) } } @@ -196,53 +189,53 @@ impl Deserialize for PrivateCircuitPublicI max_block_number: reader.read_struct(MaxBlockNumber::deserialize), note_hash_read_requests: reader.read_struct_array( ReadRequest::deserialize, - [ReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] + [ReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], ), nullifier_read_requests: reader.read_struct_array( ReadRequest::deserialize, - [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL] + [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL], ), key_validation_requests_and_generators: reader.read_struct_array( KeyValidationRequestAndGenerator::deserialize, - [KeyValidationRequestAndGenerator::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_CALL] + [KeyValidationRequestAndGenerator::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_CALL], ), note_hashes: reader.read_struct_array( NoteHash::deserialize, - [NoteHash::empty(); MAX_NOTE_HASHES_PER_CALL] + [NoteHash::empty(); MAX_NOTE_HASHES_PER_CALL], ), nullifiers: reader.read_struct_array( Nullifier::deserialize, - [Nullifier::empty(); MAX_NULLIFIERS_PER_CALL] + [Nullifier::empty(); MAX_NULLIFIERS_PER_CALL], ), private_call_requests: reader.read_struct_array( PrivateCallRequest::deserialize, - [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL] + [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], ), public_call_requests: reader.read_struct_array( PublicCallRequest::deserialize, - [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL] + [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], ), public_teardown_call_request: reader.read_struct(PublicCallRequest::deserialize), l2_to_l1_msgs: reader.read_struct_array( L2ToL1Message::deserialize, - [L2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_CALL] + [L2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_CALL], ), start_side_effect_counter: reader.read() as u32, end_side_effect_counter: reader.read() as u32, note_encrypted_logs_hashes: reader.read_struct_array( NoteLogHash::deserialize, - [NoteLogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_CALL] + [NoteLogHash::empty(); MAX_NOTE_ENCRYPTED_LOGS_PER_CALL], ), encrypted_logs_hashes: reader.read_struct_array( EncryptedLogHash::deserialize, - [EncryptedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_CALL] + [EncryptedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_CALL], ), unencrypted_logs_hashes: reader.read_struct_array( LogHash::deserialize, - [LogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL] + [LogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL], ), historical_header: reader.read_struct(Header::deserialize), - tx_context: reader.read_struct(TxContext::deserialize) + tx_context: reader.read_struct(TxContext::deserialize), }; reader.finish(); @@ -261,11 +254,17 @@ impl Empty for PrivateCircuitPublicInputs { max_block_number: MaxBlockNumber::empty(), note_hash_read_requests: [ReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], nullifier_read_requests: [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL], - key_validation_requests_and_generators: [KeyValidationRequestAndGenerator::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_CALL], + key_validation_requests_and_generators: [ + KeyValidationRequestAndGenerator::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_CALL + ], note_hashes: [NoteHash::empty(); MAX_NOTE_HASHES_PER_CALL], nullifiers: [Nullifier::empty(); MAX_NULLIFIERS_PER_CALL], - private_call_requests: [PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], - public_call_requests: [PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], + private_call_requests: [ + PrivateCallRequest::empty(); MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + ], + public_call_requests: [ + PublicCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + ], public_teardown_call_request: PublicCallRequest::empty(), l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_CALL], start_side_effect_counter: 0 as u32, @@ -274,7 +273,7 @@ impl Empty for PrivateCircuitPublicInputs { encrypted_logs_hashes: [EncryptedLogHash::empty(); MAX_ENCRYPTED_LOGS_PER_CALL], unencrypted_logs_hashes: [LogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL], historical_header: Header::empty(), - tx_context: TxContext::empty() + tx_context: TxContext::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr index d88b790a711..8ac455d134f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel/private_call_data.nr @@ -1,8 +1,9 @@ use crate::{ - abis::{private_circuit_public_inputs::PrivateCircuitPublicInputs}, + abis::private_circuit_public_inputs::PrivateCircuitPublicInputs, address::SaltedInitializationHash, public_keys::PublicKeys, constants::{FUNCTION_TREE_HEIGHT, PROTOCOL_CONTRACT_TREE_HEIGHT}, - merkle_tree::membership::MembershipWitness, recursion::{verification_key::ClientIVCVerificationKey} + merkle_tree::membership::MembershipWitness, + recursion::verification_key::ClientIVCVerificationKey, }; pub struct PrivateCallData { @@ -34,17 +35,21 @@ pub struct PrivateCallDataWithoutPublicInputs { } impl PrivateCallDataWithoutPublicInputs { - pub fn to_private_call_data(self, public_inputs: PrivateCircuitPublicInputs) -> PrivateCallData { + pub fn to_private_call_data( + self, + public_inputs: PrivateCircuitPublicInputs, + ) -> PrivateCallData { PrivateCallData { public_inputs, vk: self.vk, salted_initialization_hash: self.salted_initialization_hash, public_keys: self.public_keys, contract_class_artifact_hash: self.contract_class_artifact_hash, - contract_class_public_bytecode_commitment: self.contract_class_public_bytecode_commitment, + contract_class_public_bytecode_commitment: self + .contract_class_public_bytecode_commitment, function_leaf_membership_witness: self.function_leaf_membership_witness, protocol_contract_sibling_path: self.protocol_contract_sibling_path, - acir_hash: self.acir_hash + acir_hash: self.acir_hash, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr index 150f33fdcf2..813f04794b3 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr @@ -2,7 +2,7 @@ use crate::{ abis::kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, constants::{PRIVATE_KERNEL_RESET_INDEX, VK_TREE_HEIGHT}, merkle_tree::membership::assert_check_membership, - recursion::{verification_key::ClientIVCVerificationKey}, utils::arrays::find_index_hint + recursion::verification_key::ClientIVCVerificationKey, utils::arrays::find_index_hint, }; pub struct PrivateKernelData { @@ -32,7 +32,7 @@ impl PrivateKernelData { self.vk.hash, self.vk_index as Field, self.vk_path, - self.public_inputs.constants.vk_tree_root + self.public_inputs.constants.vk_tree_root, ); } } @@ -44,7 +44,15 @@ pub struct PrivateKernelDataWithoutPublicInputs { } impl PrivateKernelDataWithoutPublicInputs { - pub fn to_private_kernel_data(self, public_inputs: PrivateKernelCircuitPublicInputs) -> PrivateKernelData { - PrivateKernelData { public_inputs, vk: self.vk, vk_index: self.vk_index, vk_path: self.vk_path } + pub fn to_private_kernel_data( + self, + public_inputs: PrivateKernelCircuitPublicInputs, + ) -> PrivateKernelData { + PrivateKernelData { + public_inputs, + vk: self.vk, + vk_index: self.vk_index, + vk_path: self.vk_path, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr index f7a12a6c949..dd0472b4f29 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_request.nr @@ -1,7 +1,7 @@ use crate::{ abis::{call_context::CallContext, side_effect::Ordered}, address::AztecAddress, constants::PUBLIC_CALL_REQUEST_LENGTH, traits::{Empty, Serialize, Deserialize}, - utils::reader::Reader + utils::reader::Reader, }; pub struct PublicCallRequest { @@ -57,7 +57,7 @@ impl Deserialize for PublicCallRequest { let request = PublicCallRequest { call_context: reader.read_struct(CallContext::deserialize), args_hash: reader.read(), - counter: reader.read_u32() + counter: reader.read_u32(), }; reader.finish(); request diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item_compressed.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item_compressed.nr index 42efa7eb2fb..c3348f0e107 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item_compressed.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_call_stack_item_compressed.nr @@ -49,14 +49,15 @@ impl Empty for PublicCallStackItemCompressed { returns_hash: 0, revert_code: 0, start_gas_left: Gas::empty(), - end_gas_left: Gas::empty() + end_gas_left: Gas::empty(), } } } impl Serialize for PublicCallStackItemCompressed { fn serialize(self) -> [Field; PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH] { - let mut fields: BoundedVec = BoundedVec::new(); + let mut fields: BoundedVec = + BoundedVec::new(); fields.push(self.contract_address.to_field()); fields.extend_from_array(self.call_context.serialize()); @@ -73,7 +74,9 @@ impl Serialize for PublicCallStackItem } impl Deserialize for PublicCallStackItemCompressed { - fn deserialize(fields: [Field; PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH]) -> PublicCallStackItemCompressed { + fn deserialize( + fields: [Field; PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH], + ) -> PublicCallStackItemCompressed { let mut reader = Reader::new(fields); let item = PublicCallStackItemCompressed { @@ -83,7 +86,7 @@ impl Deserialize for PublicCallStackIt returns_hash: reader.read(), revert_code: reader.read() as u8, start_gas_left: reader.read_struct(Gas::deserialize), - end_gas_left: reader.read_struct(Gas::deserialize) + end_gas_left: reader.read_struct(Gas::deserialize), }; reader.finish(); item diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr index 294406aeb10..dd2da003f28 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_circuit_public_inputs.nr @@ -1,21 +1,20 @@ use crate::{ abis::{ - call_context::CallContext, note_hash::NoteHash, nullifier::Nullifier, read_request::ReadRequest, - tree_leaf_read_request::TreeLeafReadRequest, gas::Gas, global_variables::GlobalVariables, - log_hash::LogHash, public_inner_call_request::PublicInnerCallRequest -}, - address::AztecAddress, + call_context::CallContext, note_hash::NoteHash, nullifier::Nullifier, + read_request::ReadRequest, tree_leaf_read_request::TreeLeafReadRequest, gas::Gas, + global_variables::GlobalVariables, log_hash::LogHash, + public_inner_call_request::PublicInnerCallRequest, + }, address::AztecAddress, constants::{ - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL, MAX_NULLIFIERS_PER_CALL, - MAX_NOTE_HASHES_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH, - MAX_UNENCRYPTED_LOGS_PER_CALL -}, - contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, header::Header, - messaging::l2_to_l1_message::L2ToL1Message, traits::{Serialize, Deserialize, Empty}, - utils::reader::Reader + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL, MAX_L2_TO_L1_MSGS_PER_CALL, + MAX_NULLIFIERS_PER_CALL, MAX_NOTE_HASHES_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, + MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH, + MAX_UNENCRYPTED_LOGS_PER_CALL, + }, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, + header::Header, messaging::l2_to_l1_message::L2ToL1Message, + traits::{Serialize, Deserialize, Empty}, utils::reader::Reader, }; // Public inputs to public app circuit. @@ -129,49 +128,49 @@ impl Deserialize for PublicCircuitPublicInp returns_hash: reader.read(), note_hash_read_requests: reader.read_struct_array( TreeLeafReadRequest::deserialize, - [TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] + [TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], ), nullifier_read_requests: reader.read_struct_array( ReadRequest::deserialize, - [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL] + [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL], ), nullifier_non_existent_read_requests: reader.read_struct_array( ReadRequest::deserialize, - [ReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL] + [ReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL], ), l1_to_l2_msg_read_requests: reader.read_struct_array( TreeLeafReadRequest::deserialize, - [TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL] + [TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL], ), contract_storage_update_requests: reader.read_struct_array( StorageUpdateRequest::deserialize, - [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL] + [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], ), contract_storage_reads: reader.read_struct_array( StorageRead::deserialize, - [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL] + [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL], ), public_call_requests: reader.read_struct_array( PublicInnerCallRequest::deserialize, - [PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL] + [PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], ), note_hashes: reader.read_struct_array( NoteHash::deserialize, - [NoteHash::empty(); MAX_NOTE_HASHES_PER_CALL] + [NoteHash::empty(); MAX_NOTE_HASHES_PER_CALL], ), nullifiers: reader.read_struct_array( Nullifier::deserialize, - [Nullifier::empty(); MAX_NULLIFIERS_PER_CALL] + [Nullifier::empty(); MAX_NULLIFIERS_PER_CALL], ), l2_to_l1_msgs: reader.read_struct_array( L2ToL1Message::deserialize, - [L2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_CALL] + [L2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_CALL], ), start_side_effect_counter: reader.read() as u32, end_side_effect_counter: reader.read() as u32, unencrypted_logs_hashes: reader.read_struct_array( LogHash::deserialize, - [LogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL] + [LogHash::empty(); MAX_UNENCRYPTED_LOGS_PER_CALL], ), historical_header: reader.read_struct(Header::deserialize), global_variables: reader.read_struct(GlobalVariables::deserialize), @@ -179,7 +178,7 @@ impl Deserialize for PublicCircuitPublicInp revert_code: reader.read() as u8, start_gas_left: reader.read_struct(Gas::deserialize), end_gas_left: reader.read_struct(Gas::deserialize), - transaction_fee: reader.read() + transaction_fee: reader.read(), }; reader.finish(); @@ -193,13 +192,23 @@ impl Empty for PublicCircuitPublicInputs { call_context: CallContext::empty(), args_hash: 0, returns_hash: 0, - note_hash_read_requests: [TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL], + note_hash_read_requests: [ + TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL + ], nullifier_read_requests: [ReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_CALL], - nullifier_non_existent_read_requests: [ReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL], - l1_to_l2_msg_read_requests: [TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL], - contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], + nullifier_non_existent_read_requests: [ + ReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL + ], + l1_to_l2_msg_read_requests: [ + TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL + ], + contract_storage_update_requests: [ + StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL + ], contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL], - public_call_requests: [PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], + public_call_requests: [ + PublicInnerCallRequest::empty(); MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + ], note_hashes: [NoteHash::empty(); MAX_NOTE_HASHES_PER_CALL], nullifiers: [Nullifier::empty(); MAX_NULLIFIERS_PER_CALL], l2_to_l1_msgs: [L2ToL1Message::empty(); MAX_L2_TO_L1_MSGS_PER_CALL], @@ -212,7 +221,7 @@ impl Empty for PublicCircuitPublicInputs { revert_code: 0 as u8, start_gas_left: Gas::empty(), end_gas_left: Gas::empty(), - transaction_fee: 0 + transaction_fee: 0, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_read.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_read.nr index 7ba5ce28f44..1b45465e30a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_read.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_read.nr @@ -2,7 +2,7 @@ use crate::{ abis::side_effect::Ordered, address::AztecAddress, constants::PUBLIC_DATA_READ_LENGTH, contrakt::storage_read::StorageRead, data::hash::{compute_public_data_tree_value, compute_public_data_tree_index}, - traits::{Empty, Serialize, Deserialize} + traits::{Empty, Serialize, Deserialize}, }; pub struct PublicDataRead { @@ -12,11 +12,14 @@ pub struct PublicDataRead { } impl PublicDataRead { - pub fn from_contract_storage_read(contract_address: AztecAddress, read_request: StorageRead) -> PublicDataRead { + pub fn from_contract_storage_read( + contract_address: AztecAddress, + read_request: StorageRead, + ) -> PublicDataRead { PublicDataRead { leaf_slot: compute_public_data_tree_index(contract_address, read_request.storage_slot), value: compute_public_data_tree_value(read_request.current_value), - counter: read_request.counter + counter: read_request.counter, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_update_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_update_request.nr index 3222c469775..7dd85276626 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_update_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_update_request.nr @@ -1,29 +1,31 @@ use crate::{ - abis::{side_effect::Ordered}, address::AztecAddress, constants::PUBLIC_DATA_UPDATE_REQUEST_LENGTH, + abis::side_effect::Ordered, address::AztecAddress, constants::PUBLIC_DATA_UPDATE_REQUEST_LENGTH, contrakt::storage_update_request::StorageUpdateRequest, data::{ - hash::{compute_public_data_tree_value, compute_public_data_tree_index}, - public_data_tree_leaf::PublicDataTreeLeaf -}, - traits::{Empty, Serialize, Deserialize} + hash::{compute_public_data_tree_value, compute_public_data_tree_index}, + public_data_tree_leaf::PublicDataTreeLeaf, + }, traits::{Empty, Serialize, Deserialize}, }; // TODO: Rename to PublicDataWrite pub struct PublicDataUpdateRequest { - leaf_slot : Field, - new_value : Field, - counter: u32 + leaf_slot: Field, + new_value: Field, + counter: u32, } impl PublicDataUpdateRequest { pub fn from_contract_storage_update_request( contract_address: AztecAddress, - update_request: StorageUpdateRequest + update_request: StorageUpdateRequest, ) -> PublicDataUpdateRequest { PublicDataUpdateRequest { - leaf_slot: compute_public_data_tree_index(contract_address, update_request.storage_slot), + leaf_slot: compute_public_data_tree_index( + contract_address, + update_request.storage_slot, + ), new_value: compute_public_data_tree_value(update_request.new_value), - counter: update_request.counter + counter: update_request.counter, } } } @@ -66,7 +68,11 @@ impl Serialize for PublicDataUpdateRequest { impl Deserialize for PublicDataUpdateRequest { fn deserialize(fields: [Field; PUBLIC_DATA_UPDATE_REQUEST_LENGTH]) -> PublicDataUpdateRequest { - PublicDataUpdateRequest { leaf_slot: fields[0], new_value: fields[1], counter: fields[2] as u32 } + PublicDataUpdateRequest { + leaf_slot: fields[0], + new_value: fields[1], + counter: fields[2] as u32, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_write.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_write.nr index 134e00f7b30..b829d06d7b4 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_write.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_data_write.nr @@ -1,9 +1,8 @@ use crate::{ abis::{ - public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, - side_effect::{Inner, Ordered, Overridable, Readable} -}, - traits::Empty + public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, + side_effect::{Inner, Ordered, Overridable, Readable}, + }, traits::Empty, }; pub struct OverridablePublicDataWrite { @@ -32,10 +31,14 @@ impl Ordered for OverridablePublicDataWrite { impl Readable for OverridablePublicDataWrite { fn assert_match_read_request(self, read_request: PublicDataRead) { assert_eq( - self.write.leaf_slot, read_request.leaf_slot, "leaf_slot in OverridablePublicDataWrite does not match read request" + self.write.leaf_slot, + read_request.leaf_slot, + "leaf_slot in OverridablePublicDataWrite does not match read request", ); assert_eq( - self.write.new_value, read_request.value, "value in OverridablePublicDataWrite does not match read request" + self.write.new_value, + read_request.value, + "value in OverridablePublicDataWrite does not match read request", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_inner_call_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_inner_call_request.nr index ab77f5aca60..cdabed4663e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_inner_call_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_inner_call_request.nr @@ -1,7 +1,7 @@ use crate::{ abis::{public_call_stack_item_compressed::PublicCallStackItemCompressed, side_effect::Ordered}, constants::PUBLIC_INNER_CALL_REQUEST_LENGTH, traits::{Empty, Serialize, Deserialize}, - utils::reader::Reader + utils::reader::Reader, }; // TODO(#7124): To be deprecated. @@ -45,7 +45,10 @@ impl Deserialize for PublicInnerCallRequest { fn deserialize(fields: [Field; PUBLIC_INNER_CALL_REQUEST_LENGTH]) -> PublicInnerCallRequest { let mut reader = Reader::new(fields); - let request = PublicInnerCallRequest { item: reader.read_struct(PublicCallStackItemCompressed::deserialize), counter: reader.read_u32() }; + let request = PublicInnerCallRequest { + item: reader.read_struct(PublicCallStackItemCompressed::deserialize), + counter: reader.read_u32(), + }; reader.finish(); request } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_data.nr index 3277655de97..13c68e9d82b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_data.nr @@ -1,8 +1,9 @@ use crate::{ abis::kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, constants::{VK_TREE_HEIGHT, TUBE_INDEX}, merkle_tree::membership::check_membership, - recursion::{proof::NestedRecursiveProof, verification_key::HonkVerificationKey, traits::Verifiable}, - utils::arrays::find_index_hint + recursion::{ + proof::NestedRecursiveProof, verification_key::HonkVerificationKey, traits::Verifiable, + }, utils::arrays::find_index_hint, }; pub struct PublicKernelData { @@ -24,21 +25,20 @@ impl PublicKernelData { fn validate_in_vk_tree(self, allowed_indices: [u32; N]) { self.vk.check_hash(); - let index_hint = unsafe { - find_index_hint(allowed_indices, |index: u32| index == self.vk_index) - }; + let index_hint = + unsafe { find_index_hint(allowed_indices, |index: u32| index == self.vk_index) }; assert(index_hint < N, "Invalid vk index"); assert_eq(allowed_indices[index_hint], self.vk_index, "Invalid vk index"); // TODO(#7410) Remove the exception for the tube index assert( check_membership( - self.vk.hash, - self.vk_index as Field, - self.vk_path, - self.public_inputs.constants.vk_tree_root - ) - | (self.vk_index == TUBE_INDEX) + self.vk.hash, + self.vk_index as Field, + self.vk_path, + self.public_inputs.constants.vk_tree_root, + ) + | (self.vk_index == TUBE_INDEX), ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_inner_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_inner_data.nr index d1979110ba5..491abeb3169 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_inner_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/public_kernel_inner_data.nr @@ -1,6 +1,8 @@ use crate::{ abis::kernel_circuit_public_inputs::VMCircuitPublicInputs, - recursion::{proof::NestedRecursiveProof, verification_key::HonkVerificationKey, traits::Verifiable} + recursion::{ + proof::NestedRecursiveProof, verification_key::HonkVerificationKey, traits::Verifiable, + }, }; pub struct PublicKernelInnerData { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr index 6497dba6419..fc7742e4eb4 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/read_request.nr @@ -1,7 +1,7 @@ use crate::{ abis::side_effect::{Ordered, Scoped}, traits::{Empty, Serialize, Deserialize}, address::AztecAddress, constants::{READ_REQUEST_LENGTH, SCOPED_READ_REQUEST_LEN}, - utils::{arrays::array_concat, reader::Reader} + utils::{arrays::array_concat, reader::Reader}, }; pub struct ReadRequest { @@ -68,7 +68,10 @@ impl Eq for ScopedReadRequest { impl Empty for ScopedReadRequest { fn empty() -> Self { - ScopedReadRequest { read_request: ReadRequest::empty(), contract_address: AztecAddress::empty() } + ScopedReadRequest { + read_request: ReadRequest::empty(), + contract_address: AztecAddress::empty(), + } } } @@ -76,7 +79,7 @@ impl Serialize for ScopedReadRequest { fn serialize(self) -> [Field; SCOPED_READ_REQUEST_LEN] { array_concat( self.read_request.serialize(), - [self.contract_address.to_field()] + [self.contract_address.to_field()], ) } } @@ -86,7 +89,7 @@ impl Deserialize for ScopedReadRequest { let mut reader = Reader::new(values); let res = Self { read_request: reader.read_struct(ReadRequest::deserialize), - contract_address: reader.read_struct(AztecAddress::deserialize) + contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); res diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr index df8eea9d545..67929ad3d89 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/side_effect.nr @@ -1,4 +1,4 @@ -use crate::{address::AztecAddress}; +use crate::address::AztecAddress; pub trait Ordered { fn counter(self) -> u32; @@ -9,12 +9,18 @@ pub trait RangeOrdered { fn counter_end(self) -> u32; } -pub trait OrderedValue where T: Eq { +pub trait OrderedValue +where + T: Eq, +{ fn value(self) -> T; fn counter(self) -> u32; } -pub trait Scoped where T: Eq { +pub trait Scoped +where + T: Eq, +{ fn contract_address(self) -> AztecAddress; fn inner(self) -> T; } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr index ef1a6196598..2929f3a15ca 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request.nr @@ -20,17 +20,15 @@ impl Empty for KeyValidationRequest { impl Serialize for KeyValidationRequest { fn serialize(self) -> [Field; KEY_VALIDATION_REQUEST_LENGTH] { - [ - self.pk_m.x, - self.pk_m.y, - self.pk_m.is_infinite as Field, - self.sk_app - ] + [self.pk_m.x, self.pk_m.y, self.pk_m.is_infinite as Field, self.sk_app] } } impl Deserialize for KeyValidationRequest { fn deserialize(fields: [Field; KEY_VALIDATION_REQUEST_LENGTH]) -> Self { - Self { pk_m: Point { x: fields[0], y: fields[1], is_infinite: fields[2] as bool }, sk_app: fields[3] } + Self { + pk_m: Point { x: fields[0], y: fields[1], is_infinite: fields[2] as bool }, + sk_app: fields[3], + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_generator.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_generator.nr index 184fa47535e..604a0d3aa5f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_generator.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/key_validation_request_and_generator.nr @@ -1,11 +1,10 @@ use crate::{ address::AztecAddress, abis::validation_requests::{ - key_validation_request::KeyValidationRequest, - scoped_key_validation_request_and_generator::ScopedKeyValidationRequestAndGenerator -}, - constants::KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH, traits::{Empty, Serialize, Deserialize}, - utils::{arrays::array_concat, reader::Reader} + key_validation_request::KeyValidationRequest, + scoped_key_validation_request_and_generator::ScopedKeyValidationRequestAndGenerator, + }, constants::KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH, + traits::{Empty, Serialize, Deserialize}, utils::{arrays::array_concat, reader::Reader}, }; pub struct KeyValidationRequestAndGenerator { @@ -21,7 +20,10 @@ impl Eq for KeyValidationRequestAndGenerator { impl Empty for KeyValidationRequestAndGenerator { fn empty() -> Self { - KeyValidationRequestAndGenerator { request: KeyValidationRequest::empty(), sk_app_generator: 0 } + KeyValidationRequestAndGenerator { + request: KeyValidationRequest::empty(), + sk_app_generator: 0, + } } } @@ -34,7 +36,10 @@ impl Serialize for KeyValidationReq impl Deserialize for KeyValidationRequestAndGenerator { fn deserialize(fields: [Field; KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH]) -> Self { let mut reader = Reader::new(fields); - let res = Self { request: reader.read_struct(KeyValidationRequest::deserialize), sk_app_generator: reader.read() }; + let res = Self { + request: reader.read_struct(KeyValidationRequest::deserialize), + sk_app_generator: reader.read(), + }; reader.finish(); res } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests.nr index 4b8ceeef053..6025c64900d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests.nr @@ -1,16 +1,15 @@ use crate::{ abis::{ - read_request::ScopedReadRequest, - validation_requests::{ - rollup_validation_requests::RollupValidationRequests, - scoped_key_validation_request_and_generator::ScopedKeyValidationRequestAndGenerator -} -}, + read_request::ScopedReadRequest, + validation_requests::{ + rollup_validation_requests::RollupValidationRequests, + scoped_key_validation_request_and_generator::ScopedKeyValidationRequestAndGenerator, + }, + }, constants::{ - MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, - MAX_KEY_VALIDATION_REQUESTS_PER_TX, PRIVATE_VALIDATION_REQUESTS_LENGTH -}, - traits::{Serialize, Deserialize, Empty}, utils::reader::Reader + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, + MAX_KEY_VALIDATION_REQUESTS_PER_TX, PRIVATE_VALIDATION_REQUESTS_LENGTH, + }, traits::{Serialize, Deserialize, Empty}, utils::reader::Reader, }; pub struct PrivateValidationRequests { @@ -36,7 +35,8 @@ impl Serialize for PrivateValidationRequests } for i in 0..MAX_KEY_VALIDATION_REQUESTS_PER_TX { - fields.extend_from_array(self.scoped_key_validation_requests_and_generators[i].serialize()); + fields.extend_from_array(self.scoped_key_validation_requests_and_generators[i] + .serialize()); } fields.push(self.split_counter.is_some() as Field); @@ -55,17 +55,20 @@ impl Deserialize for PrivateValidationReques for_rollup: reader.read_struct(RollupValidationRequests::deserialize), note_hash_read_requests: reader.read_struct_array( ScopedReadRequest::deserialize, - [ScopedReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX] + [ScopedReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX], ), nullifier_read_requests: reader.read_struct_array( ScopedReadRequest::deserialize, - [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX] + [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX], ), scoped_key_validation_requests_and_generators: reader.read_struct_array( ScopedKeyValidationRequestAndGenerator::deserialize, - [ScopedKeyValidationRequestAndGenerator::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_TX] - ), - split_counter: Option { _is_some: reader.read_bool(), _value: reader.read_u32() } + [ + ScopedKeyValidationRequestAndGenerator::empty(); + MAX_KEY_VALIDATION_REQUESTS_PER_TX + ], + ), + split_counter: Option { _is_some: reader.read_bool(), _value: reader.read_u32() }, }; reader.finish(); @@ -77,10 +80,16 @@ impl Empty for PrivateValidationRequests { fn empty() -> Self { PrivateValidationRequests { for_rollup: RollupValidationRequests::empty(), - note_hash_read_requests: [ScopedReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX], - nullifier_read_requests: [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX], - scoped_key_validation_requests_and_generators: [ScopedKeyValidationRequestAndGenerator::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_TX], - split_counter: Option::none() + note_hash_read_requests: [ + ScopedReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX + ], + nullifier_read_requests: [ + ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX + ], + scoped_key_validation_requests_and_generators: [ + ScopedKeyValidationRequestAndGenerator::empty(); MAX_KEY_VALIDATION_REQUESTS_PER_TX + ], + split_counter: Option::none(), } } } @@ -90,8 +99,10 @@ impl Eq for PrivateValidationRequests { (self.for_rollup.eq(other.for_rollup)) & (self.note_hash_read_requests == other.note_hash_read_requests) & (self.nullifier_read_requests == other.nullifier_read_requests) - & (self.scoped_key_validation_requests_and_generators - == other.scoped_key_validation_requests_and_generators) + & ( + self.scoped_key_validation_requests_and_generators + == other.scoped_key_validation_requests_and_generators + ) & (self.split_counter == other.split_counter) } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests_builder.nr index 109eb77956c..e395c1ff6a7 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/private_validation_requests_builder.nr @@ -1,17 +1,16 @@ use crate::{ abis::{ - max_block_number::MaxBlockNumber, read_request::ScopedReadRequest, - validation_requests::{ - private_validation_requests::PrivateValidationRequests, - rollup_validation_requests::RollupValidationRequests, - scoped_key_validation_request_and_generator::ScopedKeyValidationRequestAndGenerator -} -}, + max_block_number::MaxBlockNumber, read_request::ScopedReadRequest, + validation_requests::{ + private_validation_requests::PrivateValidationRequests, + rollup_validation_requests::RollupValidationRequests, + scoped_key_validation_request_and_generator::ScopedKeyValidationRequestAndGenerator, + }, + }, constants::{ - MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, - MAX_KEY_VALIDATION_REQUESTS_PER_TX -}, - traits::Empty + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, + MAX_KEY_VALIDATION_REQUESTS_PER_TX, + }, traits::Empty, }; pub struct PrivateValidationRequestsBuilder { @@ -28,8 +27,10 @@ impl PrivateValidationRequestsBuilder { for_rollup: self.for_rollup(), note_hash_read_requests: self.note_hash_read_requests.storage, nullifier_read_requests: self.nullifier_read_requests.storage, - scoped_key_validation_requests_and_generators: self.scoped_key_validation_requests_and_generators.storage, - split_counter: self.split_counter + scoped_key_validation_requests_and_generators: self + .scoped_key_validation_requests_and_generators + .storage, + split_counter: self.split_counter, } } @@ -45,7 +46,7 @@ impl Empty for PrivateValidationRequestsBuilder { note_hash_read_requests: BoundedVec::new(), nullifier_read_requests: BoundedVec::new(), scoped_key_validation_requests_and_generators: BoundedVec::new(), - split_counter: Option::none() + split_counter: Option::none(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests.nr index 8eba0da9316..b0c8ce4a3c4 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests.nr @@ -1,16 +1,15 @@ use crate::{ abis::{ - public_data_read::PublicDataRead, read_request::ScopedReadRequest, - tree_leaf_read_request::TreeLeafReadRequest, - validation_requests::{rollup_validation_requests::RollupValidationRequests} -}, + public_data_read::PublicDataRead, read_request::ScopedReadRequest, + tree_leaf_read_request::TreeLeafReadRequest, + validation_requests::rollup_validation_requests::RollupValidationRequests, + }, constants::{ - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, NUM_PUBLIC_VALIDATION_REQUEST_ARRAYS, - PUBLIC_VALIDATION_REQUESTS_LENGTH -}, - traits::{Serialize, Deserialize, Empty}, utils::{arrays::array_length, reader::Reader} + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_READS_PER_TX, NUM_PUBLIC_VALIDATION_REQUEST_ARRAYS, + PUBLIC_VALIDATION_REQUESTS_LENGTH, + }, traits::{Serialize, Deserialize, Empty}, utils::{arrays::array_length, reader::Reader}, }; pub struct PublicValidationRequests { @@ -62,24 +61,24 @@ impl Deserialize for PublicValidationRequests for_rollup: reader.read_struct(RollupValidationRequests::deserialize), note_hash_read_requests: reader.read_struct_array( TreeLeafReadRequest::deserialize, - [TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX] + [TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX], ), nullifier_read_requests: reader.read_struct_array( ScopedReadRequest::deserialize, - [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX] + [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX], ), nullifier_non_existent_read_requests: reader.read_struct_array( ScopedReadRequest::deserialize, - [ScopedReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX] + [ScopedReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX], ), l1_to_l2_msg_read_requests: reader.read_struct_array( TreeLeafReadRequest::deserialize, - [TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX] + [TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX], ), public_data_reads: reader.read_struct_array( PublicDataRead::deserialize, - [PublicDataRead::empty(); MAX_PUBLIC_DATA_READS_PER_TX] - ) + [PublicDataRead::empty(); MAX_PUBLIC_DATA_READS_PER_TX], + ), }; reader.finish(); @@ -91,11 +90,19 @@ impl Empty for PublicValidationRequests { fn empty() -> Self { PublicValidationRequests { for_rollup: RollupValidationRequests::empty(), - note_hash_read_requests: [TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX], - nullifier_read_requests: [ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX], - nullifier_non_existent_read_requests: [ScopedReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX], - l1_to_l2_msg_read_requests: [TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX], - public_data_reads: [PublicDataRead::empty(); MAX_PUBLIC_DATA_READS_PER_TX] + note_hash_read_requests: [ + TreeLeafReadRequest::empty(); MAX_NOTE_HASH_READ_REQUESTS_PER_TX + ], + nullifier_read_requests: [ + ScopedReadRequest::empty(); MAX_NULLIFIER_READ_REQUESTS_PER_TX + ], + nullifier_non_existent_read_requests: [ + ScopedReadRequest::empty(); MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX + ], + l1_to_l2_msg_read_requests: [ + TreeLeafReadRequest::empty(); MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX + ], + public_data_reads: [PublicDataRead::empty(); MAX_PUBLIC_DATA_READS_PER_TX], } } } @@ -105,8 +112,10 @@ impl Eq for PublicValidationRequests { (self.for_rollup.eq(other.for_rollup)) & (self.note_hash_read_requests == other.note_hash_read_requests) & (self.nullifier_read_requests == other.nullifier_read_requests) - & (self.nullifier_non_existent_read_requests - == other.nullifier_non_existent_read_requests) + & ( + self.nullifier_non_existent_read_requests + == other.nullifier_non_existent_read_requests + ) & (self.l1_to_l2_msg_read_requests == other.l1_to_l2_msg_read_requests) & (self.public_data_reads == other.public_data_reads) } @@ -125,9 +134,11 @@ impl PublicValidationRequestArrayLengths { PublicValidationRequestArrayLengths { note_hash_read_requests: array_length(requests.note_hash_read_requests), nullifier_read_requests: array_length(requests.nullifier_read_requests), - nullifier_non_existent_read_requests: array_length(requests.nullifier_non_existent_read_requests), + nullifier_non_existent_read_requests: array_length( + requests.nullifier_non_existent_read_requests, + ), l1_to_l2_msg_read_requests: array_length(requests.l1_to_l2_msg_read_requests), - public_data_reads: array_length(requests.public_data_reads) + public_data_reads: array_length(requests.public_data_reads), } } } @@ -139,7 +150,7 @@ impl Empty for PublicValidationRequestArrayLengths { nullifier_read_requests: 0, nullifier_non_existent_read_requests: 0, l1_to_l2_msg_read_requests: 0, - public_data_reads: 0 + public_data_reads: 0, } } } @@ -148,8 +159,10 @@ impl Eq for PublicValidationRequestArrayLengths { fn eq(self, other: Self) -> bool { (self.note_hash_read_requests == other.note_hash_read_requests) & (self.nullifier_read_requests == other.nullifier_read_requests) - & (self.nullifier_non_existent_read_requests - == other.nullifier_non_existent_read_requests) + & ( + self.nullifier_non_existent_read_requests + == other.nullifier_non_existent_read_requests + ) & (self.l1_to_l2_msg_read_requests == other.l1_to_l2_msg_read_requests) & (self.public_data_reads == other.public_data_reads) } @@ -177,7 +190,7 @@ impl Deserialize for PublicValidationReque nullifier_read_requests: reader.read_u32(), nullifier_non_existent_read_requests: reader.read_u32(), l1_to_l2_msg_read_requests: reader.read_u32(), - public_data_reads: reader.read_u32() + public_data_reads: reader.read_u32(), }; reader.finish(); item diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests_builder.nr index 3b541ca6aa0..4fcbe4a6cb9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/public_validation_requests_builder.nr @@ -1,18 +1,17 @@ use crate::{ abis::{ - max_block_number::MaxBlockNumber, public_data_read::PublicDataRead, read_request::ScopedReadRequest, - tree_leaf_read_request::TreeLeafReadRequest, - validation_requests::{ - public_validation_requests::PublicValidationRequests, - rollup_validation_requests::RollupValidationRequests -} -}, + max_block_number::MaxBlockNumber, public_data_read::PublicDataRead, + read_request::ScopedReadRequest, tree_leaf_read_request::TreeLeafReadRequest, + validation_requests::{ + public_validation_requests::PublicValidationRequests, + rollup_validation_requests::RollupValidationRequests, + }, + }, constants::{ - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX -}, - traits::Empty, utils::arrays::array_to_bounded_vec + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_READS_PER_TX, + }, traits::Empty, utils::arrays::array_to_bounded_vec, }; pub struct PublicValidationRequestsBuilder { @@ -30,9 +29,11 @@ impl PublicValidationRequestsBuilder { max_block_number: requests.for_rollup.max_block_number, note_hash_read_requests: array_to_bounded_vec(requests.note_hash_read_requests), nullifier_read_requests: array_to_bounded_vec(requests.nullifier_read_requests), - nullifier_non_existent_read_requests: array_to_bounded_vec(requests.nullifier_non_existent_read_requests), + nullifier_non_existent_read_requests: array_to_bounded_vec( + requests.nullifier_non_existent_read_requests, + ), public_data_reads: array_to_bounded_vec(requests.public_data_reads), - l1_to_l2_msg_read_requests: array_to_bounded_vec(requests.l1_to_l2_msg_read_requests) + l1_to_l2_msg_read_requests: array_to_bounded_vec(requests.l1_to_l2_msg_read_requests), } } @@ -43,7 +44,7 @@ impl PublicValidationRequestsBuilder { nullifier_read_requests: self.nullifier_read_requests.storage, nullifier_non_existent_read_requests: self.nullifier_non_existent_read_requests.storage, public_data_reads: self.public_data_reads.storage, - l1_to_l2_msg_read_requests: self.l1_to_l2_msg_read_requests.storage + l1_to_l2_msg_read_requests: self.l1_to_l2_msg_read_requests.storage, } } @@ -60,7 +61,7 @@ impl Empty for PublicValidationRequestsBuilder { nullifier_read_requests: BoundedVec::new(), nullifier_non_existent_read_requests: BoundedVec::new(), public_data_reads: BoundedVec::new(), - l1_to_l2_msg_read_requests: BoundedVec::new() + l1_to_l2_msg_read_requests: BoundedVec::new(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/rollup_validation_requests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/rollup_validation_requests.nr index 59921e2103c..c29122fbc1f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/rollup_validation_requests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/rollup_validation_requests.nr @@ -1,6 +1,6 @@ use crate::{ abis::max_block_number::MaxBlockNumber, traits::{Empty, Serialize, Deserialize}, - constants::ROLLUP_VALIDATION_REQUESTS_LENGTH, utils::reader::Reader + constants::ROLLUP_VALIDATION_REQUESTS_LENGTH, utils::reader::Reader, }; // These are validation requests that cannot be fulfilled in the current context (private or public), and must be diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/scoped_key_validation_request_and_generator.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/scoped_key_validation_request_and_generator.nr index d42bf260460..259ba94bc9b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/scoped_key_validation_request_and_generator.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/validation_requests/scoped_key_validation_request_and_generator.nr @@ -2,9 +2,9 @@ use crate::{ address::AztecAddress, constants::SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH, traits::{Empty, Serialize, Deserialize}, utils::{arrays::array_concat, reader::Reader}, abis::{ - side_effect::Scoped, - validation_requests::key_validation_request_and_generator::KeyValidationRequestAndGenerator -} + side_effect::Scoped, + validation_requests::key_validation_request_and_generator::KeyValidationRequestAndGenerator, + }, }; pub struct ScopedKeyValidationRequestAndGenerator { @@ -29,7 +29,10 @@ impl Eq for ScopedKeyValidationRequestAndGenerator { impl Empty for ScopedKeyValidationRequestAndGenerator { fn empty() -> Self { - ScopedKeyValidationRequestAndGenerator { request: KeyValidationRequestAndGenerator::empty(), contract_address: AztecAddress::zero() } + ScopedKeyValidationRequestAndGenerator { + request: KeyValidationRequestAndGenerator::empty(), + contract_address: AztecAddress::zero(), + } } } @@ -44,7 +47,7 @@ impl Deserialize for ScopedK let mut reader = Reader::new(fields); let res = Self { request: reader.read_struct(KeyValidationRequestAndGenerator::deserialize), - contract_address: reader.read_struct(AztecAddress::deserialize) + contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); res diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr index 4fe04afcb26..c1515da11b0 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr @@ -1,19 +1,19 @@ use crate::{ abis::function_selector::FunctionSelector, address::{ - partial_address::PartialAddress, public_keys_hash::PublicKeysHash, - salted_initialization_hash::SaltedInitializationHash -}, + partial_address::PartialAddress, public_keys_hash::PublicKeysHash, + salted_initialization_hash::SaltedInitializationHash, + }, constants::{AZTEC_ADDRESS_LENGTH, FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__CONTRACT_ADDRESS_V1}, contract_class_id::ContractClassId, hash::{poseidon2_hash_with_separator, private_functions_root_from_siblings}, merkle_tree::membership::MembershipWitness, - traits::{Empty, FromField, ToField, Serialize, Deserialize}, utils + traits::{Empty, FromField, ToField, Serialize, Deserialize}, utils, }; // Aztec address pub struct AztecAddress { - inner : Field + inner: Field, } impl Eq for AztecAddress { @@ -58,12 +58,10 @@ impl AztecAddress { } pub fn compute(pub_keys_hash: PublicKeysHash, partial_address: PartialAddress) -> AztecAddress { - AztecAddress::from_field( - poseidon2_hash_with_separator( - [pub_keys_hash.to_field(), partial_address.to_field()], - GENERATOR_INDEX__CONTRACT_ADDRESS_V1 - ) - ) + AztecAddress::from_field(poseidon2_hash_with_separator( + [pub_keys_hash.to_field(), partial_address.to_field()], + GENERATOR_INDEX__CONTRACT_ADDRESS_V1, + )) } pub fn compute_from_private_function( @@ -73,23 +71,26 @@ impl AztecAddress { contract_class_artifact_hash: Field, contract_class_public_bytecode_commitment: Field, salted_initialization_hash: SaltedInitializationHash, - public_keys_hash: PublicKeysHash + public_keys_hash: PublicKeysHash, ) -> Self { let private_functions_root = private_functions_root_from_siblings( function_selector, functino_vk_hash, function_leaf_membership_witness.leaf_index, - function_leaf_membership_witness.sibling_path + function_leaf_membership_witness.sibling_path, ); let contract_class_id = ContractClassId::compute( contract_class_artifact_hash, private_functions_root, - contract_class_public_bytecode_commitment + contract_class_public_bytecode_commitment, ); // Compute contract address using the preimage which includes the class_id. - let partial_address = PartialAddress::compute_from_salted_initialization_hash(contract_class_id, salted_initialization_hash); + let partial_address = PartialAddress::compute_from_salted_initialization_hash( + contract_class_id, + salted_initialization_hash, + ); AztecAddress::compute(public_keys_hash, partial_address) } @@ -114,7 +115,8 @@ fn compute_address_from_partial_and_pub_keys_hash() { let partial_address = PartialAddress::from_field(2); let address = AztecAddress::compute(pub_keys_hash, partial_address); - let expected_computed_address_from_partial_and_pubkey = 0x23ce9be3fa3c846b0f9245cc796902e731d04f086e8a42473bb29e405fc98075; + let expected_computed_address_from_partial_and_pubkey = + 0x23ce9be3fa3c846b0f9245cc796902e731d04f086e8a42473bb29e405fc98075; assert(address.to_field() == expected_computed_address_from_partial_and_pubkey); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/eth_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/eth_address.nr index aad2c111949..22c40cc3876 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/eth_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/eth_address.nr @@ -1,7 +1,7 @@ use crate::{constants::ETH_ADDRESS_LENGTH, traits::{Empty, ToField, Serialize, Deserialize}, utils}; -pub struct EthAddress{ - inner : Field +pub struct EthAddress { + inner: Field, } impl Eq for EthAddress { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr index de1ca920cea..d0be0319866 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/partial_address.nr @@ -1,14 +1,14 @@ use crate::{ address::{salted_initialization_hash::SaltedInitializationHash, aztec_address::AztecAddress}, constants::GENERATOR_INDEX__PARTIAL_ADDRESS, contract_class_id::ContractClassId, - hash::poseidon2_hash_with_separator, traits::{ToField, Serialize, Deserialize} + hash::poseidon2_hash_with_separator, traits::{ToField, Serialize, Deserialize}, }; global PARTIAL_ADDRESS_LENGTH: u32 = 1; // Partial address pub struct PartialAddress { - inner : Field + inner: Field, } impl ToField for PartialAddress { @@ -38,27 +38,22 @@ impl PartialAddress { contract_class_id: ContractClassId, salt: Field, initialization_hash: Field, - deployer: AztecAddress + deployer: AztecAddress, ) -> Self { PartialAddress::compute_from_salted_initialization_hash( contract_class_id, - SaltedInitializationHash::compute(salt, initialization_hash, deployer) + SaltedInitializationHash::compute(salt, initialization_hash, deployer), ) } pub fn compute_from_salted_initialization_hash( contract_class_id: ContractClassId, - salted_initialization_hash: SaltedInitializationHash + salted_initialization_hash: SaltedInitializationHash, ) -> Self { - PartialAddress::from_field( - poseidon2_hash_with_separator( - [ - contract_class_id.to_field(), - salted_initialization_hash.to_field() - ], - GENERATOR_INDEX__PARTIAL_ADDRESS - ) - ) + PartialAddress::from_field(poseidon2_hash_with_separator( + [contract_class_id.to_field(), salted_initialization_hash.to_field()], + GENERATOR_INDEX__PARTIAL_ADDRESS, + )) } pub fn to_field(self) -> Field { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr index 9e05807428a..6e18b46788d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/public_keys_hash.nr @@ -2,7 +2,7 @@ use crate::traits::{ToField, Serialize, Deserialize}; // Public keys hash. Used in the computation of an address. pub struct PublicKeysHash { - inner: Field + inner: Field, } impl ToField for PublicKeysHash { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr index 27c4cf7a65f..5ef32bae6e8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/address/salted_initialization_hash.nr @@ -1,11 +1,11 @@ use crate::{ - address::{aztec_address::AztecAddress}, constants::GENERATOR_INDEX__PARTIAL_ADDRESS, - hash::poseidon2_hash_with_separator, traits::ToField + address::aztec_address::AztecAddress, constants::GENERATOR_INDEX__PARTIAL_ADDRESS, + hash::poseidon2_hash_with_separator, traits::ToField, }; // Salted initialization hash. Used in the computation of a partial address. pub struct SaltedInitializationHash { - inner: Field + inner: Field, } impl ToField for SaltedInitializationHash { @@ -20,16 +20,10 @@ impl SaltedInitializationHash { } pub fn compute(salt: Field, initialization_hash: Field, deployer: AztecAddress) -> Self { - SaltedInitializationHash::from_field( - poseidon2_hash_with_separator( - [ - salt, - initialization_hash, - deployer.to_field() - ], - GENERATOR_INDEX__PARTIAL_ADDRESS - ) - ) + SaltedInitializationHash::from_field(poseidon2_hash_with_separator( + [salt, initialization_hash, deployer.to_field()], + GENERATOR_INDEX__PARTIAL_ADDRESS, + )) } pub fn assert_is_zero(self) { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index ae51e49b698..7a680ae9601 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -1,6 +1,7 @@ use crate::address::AztecAddress; -global MAX_FIELD_VALUE: Field = 21888242871839275222246405745257275088548364400416034343698204186575808495616; +global MAX_FIELD_VALUE: Field = + 21888242871839275222246405745257275088548364400416034343698204186575808495616; global ARGS_LENGTH: u32 = 16; /** @@ -62,10 +63,14 @@ global NOTE_HASH_SUBTREE_HEIGHT: u32 = 6; global NULLIFIER_SUBTREE_HEIGHT: u32 = 6; global PUBLIC_DATA_SUBTREE_HEIGHT: u32 = 6; global L1_TO_L2_MSG_SUBTREE_HEIGHT: u32 = 4; -global NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: u32 = NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT; -global NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: u32 = NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT; -global PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: u32 = PUBLIC_DATA_TREE_HEIGHT - PUBLIC_DATA_SUBTREE_HEIGHT; -global L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: u32 = L1_TO_L2_MSG_TREE_HEIGHT - L1_TO_L2_MSG_SUBTREE_HEIGHT; +global NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: u32 = + NOTE_HASH_TREE_HEIGHT - NOTE_HASH_SUBTREE_HEIGHT; +global NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: u32 = + NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT; +global PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH: u32 = + PUBLIC_DATA_TREE_HEIGHT - PUBLIC_DATA_SUBTREE_HEIGHT; +global L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: u32 = + L1_TO_L2_MSG_TREE_HEIGHT - L1_TO_L2_MSG_SUBTREE_HEIGHT; // "PER TRANSACTION" CONSTANTS global MAX_NOTE_HASHES_PER_TX: u32 = (1 as u8 << NOTE_HASH_SUBTREE_HEIGHT as u8) as u32; @@ -73,8 +78,10 @@ global MAX_NULLIFIERS_PER_TX: u32 = (1 as u8 << NULLIFIER_SUBTREE_HEIGHT as u8) global MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: u32 = 8; global MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: u32 = 32; global PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u32 = 1; -global MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u32 = (1 as u8 << PUBLIC_DATA_SUBTREE_HEIGHT as u8) as u32; -global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u32 = MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; +global MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u32 = + (1 as u8 << PUBLIC_DATA_SUBTREE_HEIGHT as u8) as u32; +global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u32 = + MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; global MAX_PUBLIC_DATA_READS_PER_TX: u32 = 64; global MAX_L2_TO_L1_MSGS_PER_TX: u32 = 8; global MAX_NOTE_HASH_READ_REQUESTS_PER_TX: u32 = 64; @@ -137,7 +144,8 @@ global AZTEC_TARGET_COMMITTEE_SIZE: u32 = 48; global AZTEC_EPOCH_PROOF_CLAIM_WINDOW_IN_L2_SLOTS: u32 = 13; // The following is taken from building a block and looking at the `lastArchive` value in it. // You can run the `integration_l1_publisher.test.ts` and look at the first blocks in the fixtures. -global GENESIS_ARCHIVE_ROOT: Field = 0x1200a06aae1368abe36530b585bd7a4d2ba4de5037b82076412691a187d7621e; +global GENESIS_ARCHIVE_ROOT: Field = + 0x1200a06aae1368abe36530b585bd7a4d2ba4de5037b82076412691a187d7621e; // The following and the value in `deploy_l1_contracts` must match. We should not have the code both places, but // we are running into circular dependency issues. #3342 global FEE_JUICE_INITIAL_MINT: Field = 20000000000; @@ -158,15 +166,19 @@ global REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS: u32 = 12 // Since we are not yet emitting selectors we'll use this magic value to identify events emitted by the ClassRegisterer. // This is just a stopgap until we implement proper selectors. // sha224sum 'struct ContractClassRegistered {contract_class_id: ContractClassId, version: Field, artifact_hash: Field, private_functions_root: Field, packed_public_bytecode: [Field; MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS] }' -global REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE = 0x6999d1e02b08a447a463563453cb36919c9dd7150336fc7c4d2b52f8; +global REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE = + 0x6999d1e02b08a447a463563453cb36919c9dd7150336fc7c4d2b52f8; // sha224sum 'struct ClassPrivateFunctionBroadcasted' -global REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE = 0x1b70e95fde0b70adc30496b90a327af6a5e383e028e7a43211a07bcd; +global REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE = + 0x1b70e95fde0b70adc30496b90a327af6a5e383e028e7a43211a07bcd; // sha224sum 'struct ClassUnconstrainedFunctionBroadcasted' -global REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE = 0xe7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d99; +global REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE = + 0xe7af816635466f128568edb04c9fa024f6c87fb9010fdbffa68b3d99; // CONTRACT INSTANCE CONSTANTS // sha224sum 'struct ContractInstanceDeployed' -global DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631; +global DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE = + 0x85864497636cf755ae7bde03f267ce01a520981c21c3682aaf82a631; // GAS DEFAULTS global DEFAULT_GAS_LIMIT: u32 = 1_000_000_000; @@ -194,17 +206,22 @@ global L2_GAS_PER_READ_MERKLE_HASH: u32 = 30; global L2_GAS_PER_WRITE_MERKLE_HASH: u32 = 40; // Gas for tree insertions and associated storage -global L2_GAS_PER_PUBLIC_DATA_UPDATE: u32 = L2_GAS_DISTRIBUTED_STORAGE_PREMIUM + (PUBLIC_DATA_TREE_HEIGHT * L2_GAS_PER_WRITE_MERKLE_HASH); -global L2_GAS_PER_NOTE_HASH: u32 = L2_GAS_DISTRIBUTED_STORAGE_PREMIUM + (NOTE_HASH_TREE_HEIGHT * L2_GAS_PER_WRITE_MERKLE_HASH); +global L2_GAS_PER_PUBLIC_DATA_UPDATE: u32 = + L2_GAS_DISTRIBUTED_STORAGE_PREMIUM + (PUBLIC_DATA_TREE_HEIGHT * L2_GAS_PER_WRITE_MERKLE_HASH); +global L2_GAS_PER_NOTE_HASH: u32 = + L2_GAS_DISTRIBUTED_STORAGE_PREMIUM + (NOTE_HASH_TREE_HEIGHT * L2_GAS_PER_WRITE_MERKLE_HASH); // 2x because insertion into indexed tree requires a low-leaf membership check and a standard insertion -global L2_GAS_PER_NULLIFIER: u32 = L2_GAS_DISTRIBUTED_STORAGE_PREMIUM + (2 * NULLIFIER_TREE_HEIGHT * L2_GAS_PER_WRITE_MERKLE_HASH); +global L2_GAS_PER_NULLIFIER: u32 = + L2_GAS_DISTRIBUTED_STORAGE_PREMIUM + (2 * NULLIFIER_TREE_HEIGHT * L2_GAS_PER_WRITE_MERKLE_HASH); // Gas for tree read requests global L2_GAS_PER_PUBLIC_DATA_READ: u32 = PUBLIC_DATA_TREE_HEIGHT * L2_GAS_PER_READ_MERKLE_HASH; global L2_GAS_PER_NOTE_HASH_READ_REQUEST: u32 = NOTE_HASH_TREE_HEIGHT * L2_GAS_PER_READ_MERKLE_HASH; // 2x because non-membership checks are really 2 membership checks -global L2_GAS_PER_NULLIFIER_READ_REQUEST: u32 = 2 * NULLIFIER_TREE_HEIGHT * L2_GAS_PER_READ_MERKLE_HASH; -global L2_GAS_PER_L1_TO_L2_MSG_READ_REQUEST: u32 = L1_TO_L2_MSG_TREE_HEIGHT * L2_GAS_PER_READ_MERKLE_HASH; +global L2_GAS_PER_NULLIFIER_READ_REQUEST: u32 = + 2 * NULLIFIER_TREE_HEIGHT * L2_GAS_PER_READ_MERKLE_HASH; +global L2_GAS_PER_L1_TO_L2_MSG_READ_REQUEST: u32 = + L1_TO_L2_MSG_TREE_HEIGHT * L2_GAS_PER_READ_MERKLE_HASH; // Gas for hashing and validating logs global L2_GAS_PER_LOG_BYTE: u32 = 4; @@ -242,7 +259,8 @@ global SCOPED_L2_TO_L1_MESSAGE_LENGTH: u32 = L2_TO_L1_MESSAGE_LENGTH + 1; global MAX_BLOCK_NUMBER_LENGTH: u32 = 2; // 1 for the option flag, 1 for the value global KEY_VALIDATION_REQUEST_LENGTH: u32 = 4; global KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_LENGTH + 1; -global SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH + 1; +global SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = + KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH + 1; global PARTIAL_STATE_REFERENCE_LENGTH: u32 = 6; global READ_REQUEST_LENGTH: u32 = 2; global TREE_LEAF_READ_REQUEST_LENGTH: u32 = 2; @@ -255,55 +273,180 @@ global NOTE_HASH_LENGTH: u32 = 2; global SCOPED_NOTE_HASH_LENGTH: u32 = NOTE_HASH_LENGTH + 1; global NULLIFIER_LENGTH: u32 = 3; global SCOPED_NULLIFIER_LENGTH: u32 = NULLIFIER_LENGTH + 1; -global PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH: u32 = AZTEC_ADDRESS_LENGTH + CALL_CONTEXT_LENGTH + 3 + 2 * GAS_LENGTH; +global PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH: u32 = + AZTEC_ADDRESS_LENGTH + CALL_CONTEXT_LENGTH + 3 + 2 * GAS_LENGTH; global PRIVATE_CALL_REQUEST_LENGTH: u32 = CALL_CONTEXT_LENGTH + 4; global PUBLIC_CALL_REQUEST_LENGTH: u32 = CALL_CONTEXT_LENGTH + 1 /* args_hash */ + 1 /* counter */; -global PUBLIC_INNER_CALL_REQUEST_LENGTH: u32 = PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH + 1 /* counter */; +global PUBLIC_INNER_CALL_REQUEST_LENGTH: u32 = + PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH + 1 /* counter */; global ROLLUP_VALIDATION_REQUESTS_LENGTH: u32 = MAX_BLOCK_NUMBER_LENGTH; -global STATE_REFERENCE_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; +global STATE_REFERENCE_LENGTH: u32 = + APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; global TX_CONTEXT_LENGTH: u32 = 2 + GAS_SETTINGS_LENGTH; global TX_REQUEST_LENGTH: u32 = 2 + TX_CONTEXT_LENGTH + FUNCTION_DATA_LENGTH; global TOTAL_FEES_LENGTH: u32 = 1; -global HEADER_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + CONTENT_COMMITMENT_LENGTH + STATE_REFERENCE_LENGTH + GLOBAL_VARIABLES_LENGTH + TOTAL_FEES_LENGTH; -global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + 4 + MAX_BLOCK_NUMBER_LENGTH + (READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH * MAX_KEY_VALIDATION_REQUESTS_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_CALL) + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL) + (PUBLIC_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL) + PUBLIC_CALL_REQUEST_LENGTH + (L2_TO_L1_MESSAGE_LENGTH * MAX_L2_TO_L1_MSGS_PER_CALL) + 2 + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_CALL) + (ENCRYPTED_LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + HEADER_LENGTH + TX_CONTEXT_LENGTH; -global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + /*argsHash + returnsHash*/ 2 + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + (READ_REQUEST_LENGTH * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL) + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL) + (CONTRACT_STORAGE_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_CALL) + (PUBLIC_INNER_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL) + (NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_CALL) + (NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_CALL) + (L2_TO_L1_MESSAGE_LENGTH * MAX_L2_TO_L1_MSGS_PER_CALL) + 2 + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + HEADER_LENGTH + GLOBAL_VARIABLES_LENGTH + AZTEC_ADDRESS_LENGTH + /* revert_code */ 1 + 2 * GAS_LENGTH + /* transaction_fee */ 1; -global PRIVATE_CONTEXT_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + HEADER_LENGTH + TX_CONTEXT_LENGTH + 1; -global PUBLIC_CONTEXT_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + HEADER_LENGTH + GLOBAL_VARIABLES_LENGTH + GAS_LENGTH + 2; +global HEADER_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + + CONTENT_COMMITMENT_LENGTH + + STATE_REFERENCE_LENGTH + + GLOBAL_VARIABLES_LENGTH + + TOTAL_FEES_LENGTH; +global PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + + 4 + + MAX_BLOCK_NUMBER_LENGTH + + (READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + + (KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH * MAX_KEY_VALIDATION_REQUESTS_PER_CALL) + + (NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_CALL) + + (NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_CALL) + + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL) + + (PUBLIC_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL) + + PUBLIC_CALL_REQUEST_LENGTH + + (L2_TO_L1_MESSAGE_LENGTH * MAX_L2_TO_L1_MSGS_PER_CALL) + + 2 + + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_CALL) + + (ENCRYPTED_LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_CALL) + + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + + HEADER_LENGTH + + TX_CONTEXT_LENGTH; +global PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = CALL_CONTEXT_LENGTH + + /*argsHash + returnsHash*/ 2 + + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_CALL) + + (READ_REQUEST_LENGTH * MAX_NULLIFIER_READ_REQUESTS_PER_CALL) + + (READ_REQUEST_LENGTH * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL) + + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL) + + (CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL) + + (CONTRACT_STORAGE_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_CALL) + + (PUBLIC_INNER_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL) + + (NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_CALL) + + (NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_CALL) + + (L2_TO_L1_MESSAGE_LENGTH * MAX_L2_TO_L1_MSGS_PER_CALL) + + 2 + + (LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_CALL) + + HEADER_LENGTH + + GLOBAL_VARIABLES_LENGTH + + AZTEC_ADDRESS_LENGTH + + /* revert_code */ 1 + + 2 * GAS_LENGTH + + /* transaction_fee */ 1; +global PRIVATE_CONTEXT_INPUTS_LENGTH: u32 = + CALL_CONTEXT_LENGTH + HEADER_LENGTH + TX_CONTEXT_LENGTH + 1; +global PUBLIC_CONTEXT_INPUTS_LENGTH: u32 = + CALL_CONTEXT_LENGTH + HEADER_LENGTH + GLOBAL_VARIABLES_LENGTH + GAS_LENGTH + 2; global FEE_RECIPIENT_LENGTH: u32 = 2; global AGGREGATION_OBJECT_LENGTH: u32 = 16; global SCOPED_READ_REQUEST_LEN: u32 = READ_REQUEST_LENGTH + 1; global PUBLIC_DATA_READ_LENGTH: u32 = 3; -global PRIVATE_VALIDATION_REQUESTS_LENGTH: u32 = ROLLUP_VALIDATION_REQUESTS_LENGTH + (SCOPED_READ_REQUEST_LEN * MAX_NOTE_HASH_READ_REQUESTS_PER_TX) + (SCOPED_READ_REQUEST_LEN * MAX_NULLIFIER_READ_REQUESTS_PER_TX) + (SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH * MAX_KEY_VALIDATION_REQUESTS_PER_TX) + 2; +global PRIVATE_VALIDATION_REQUESTS_LENGTH: u32 = ROLLUP_VALIDATION_REQUESTS_LENGTH + + (SCOPED_READ_REQUEST_LEN * MAX_NOTE_HASH_READ_REQUESTS_PER_TX) + + (SCOPED_READ_REQUEST_LEN * MAX_NULLIFIER_READ_REQUESTS_PER_TX) + + (SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH * MAX_KEY_VALIDATION_REQUESTS_PER_TX) + + 2; global NUM_PUBLIC_VALIDATION_REQUEST_ARRAYS: u32 = 5; -global PUBLIC_VALIDATION_REQUESTS_LENGTH: u32 = ROLLUP_VALIDATION_REQUESTS_LENGTH + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_TX) + (SCOPED_READ_REQUEST_LEN * MAX_NULLIFIER_READ_REQUESTS_PER_TX) + (SCOPED_READ_REQUEST_LEN * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX) + (PUBLIC_DATA_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_TX) + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX); +global PUBLIC_VALIDATION_REQUESTS_LENGTH: u32 = ROLLUP_VALIDATION_REQUESTS_LENGTH + + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_NOTE_HASH_READ_REQUESTS_PER_TX) + + (SCOPED_READ_REQUEST_LEN * MAX_NULLIFIER_READ_REQUESTS_PER_TX) + + (SCOPED_READ_REQUEST_LEN * MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX) + + (PUBLIC_DATA_READ_LENGTH * MAX_PUBLIC_DATA_READS_PER_TX) + + (TREE_LEAF_READ_REQUEST_LENGTH * MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX); global PUBLIC_DATA_UPDATE_REQUEST_LENGTH: u32 = 3; -global COMBINED_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) + (LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + (SCOPED_LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + 3 + (MAX_UNENCRYPTED_LOGS_PER_TX * SCOPED_LOG_HASH_LENGTH) + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + GAS_LENGTH; -global COMBINED_CONSTANT_DATA_LENGTH: u32 = HEADER_LENGTH + TX_CONTEXT_LENGTH + GLOBAL_VARIABLES_LENGTH + 1 /* vk_tree_root */ + 1 /* protocol_contract_tree_root */; - -global PRIVATE_ACCUMULATED_DATA_LENGTH: u32 = (SCOPED_NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_TX) + (SCOPED_NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_TX) + (MAX_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + (SCOPED_ENCRYPTED_LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + (SCOPED_LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX) + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + (PUBLIC_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); -global PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = 1 + PRIVATE_VALIDATION_REQUESTS_LENGTH + PRIVATE_ACCUMULATED_DATA_LENGTH + COMBINED_CONSTANT_DATA_LENGTH + PUBLIC_CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH; - -global PUBLIC_ACCUMULATED_DATA_LENGTH: u32 = (MAX_NOTE_HASHES_PER_TX * SCOPED_NOTE_HASH_LENGTH) + (MAX_NULLIFIERS_PER_TX * NULLIFIER_LENGTH) + (MAX_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + (MAX_NOTE_ENCRYPTED_LOGS_PER_TX * LOG_HASH_LENGTH) + (MAX_ENCRYPTED_LOGS_PER_TX * SCOPED_LOG_HASH_LENGTH) + (MAX_UNENCRYPTED_LOGS_PER_TX * SCOPED_LOG_HASH_LENGTH) + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + (MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX * PUBLIC_CALL_REQUEST_LENGTH) + GAS_LENGTH; +global COMBINED_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) + + (LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + + (SCOPED_LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + + 3 + + (MAX_UNENCRYPTED_LOGS_PER_TX * SCOPED_LOG_HASH_LENGTH) + + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + + GAS_LENGTH; +global COMBINED_CONSTANT_DATA_LENGTH: u32 = HEADER_LENGTH + + TX_CONTEXT_LENGTH + + GLOBAL_VARIABLES_LENGTH + + 1 /* vk_tree_root */ + + 1 /* protocol_contract_tree_root */; + +global PRIVATE_ACCUMULATED_DATA_LENGTH: u32 = (SCOPED_NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_TX) + + (SCOPED_NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_TX) + + (MAX_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + + (NOTE_LOG_HASH_LENGTH * MAX_NOTE_ENCRYPTED_LOGS_PER_TX) + + (SCOPED_ENCRYPTED_LOG_HASH_LENGTH * MAX_ENCRYPTED_LOGS_PER_TX) + + (SCOPED_LOG_HASH_LENGTH * MAX_UNENCRYPTED_LOGS_PER_TX) + + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX) + + (PUBLIC_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); +global PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = 1 + + PRIVATE_VALIDATION_REQUESTS_LENGTH + + PRIVATE_ACCUMULATED_DATA_LENGTH + + COMBINED_CONSTANT_DATA_LENGTH + + PUBLIC_CALL_REQUEST_LENGTH + + AZTEC_ADDRESS_LENGTH; + +global PUBLIC_ACCUMULATED_DATA_LENGTH: u32 = (MAX_NOTE_HASHES_PER_TX * SCOPED_NOTE_HASH_LENGTH) + + (MAX_NULLIFIERS_PER_TX * NULLIFIER_LENGTH) + + (MAX_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) + + (MAX_NOTE_ENCRYPTED_LOGS_PER_TX * LOG_HASH_LENGTH) + + (MAX_ENCRYPTED_LOGS_PER_TX * SCOPED_LOG_HASH_LENGTH) + + (MAX_UNENCRYPTED_LOGS_PER_TX * SCOPED_LOG_HASH_LENGTH) + + (MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * PUBLIC_DATA_UPDATE_REQUEST_LENGTH) + + (MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX * PUBLIC_CALL_REQUEST_LENGTH) + + GAS_LENGTH; global NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS: u32 = 8; -global PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = COMBINED_CONSTANT_DATA_LENGTH + PUBLIC_VALIDATION_REQUESTS_LENGTH + PUBLIC_ACCUMULATED_DATA_LENGTH + PUBLIC_ACCUMULATED_DATA_LENGTH + 1 /* end_side_effect_counter */ + PUBLIC_CALL_REQUEST_LENGTH + AZTEC_ADDRESS_LENGTH + 1 /* revert_code */; -global VM_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = COMBINED_CONSTANT_DATA_LENGTH + PUBLIC_CALL_REQUEST_LENGTH + PUBLIC_VALIDATION_REQUESTS_LENGTH + NUM_PUBLIC_VALIDATION_REQUEST_ARRAYS + PUBLIC_ACCUMULATED_DATA_LENGTH + NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS + 1 /* start_side_effect_counter */ + 1 /* end_side_effect_counter */ + GAS_LENGTH + 1 + 1 + (PUBLIC_INNER_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); - -global KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = ROLLUP_VALIDATION_REQUESTS_LENGTH + COMBINED_ACCUMULATED_DATA_LENGTH + COMBINED_CONSTANT_DATA_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + 1 + AZTEC_ADDRESS_LENGTH; - -global CONSTANT_ROLLUP_DATA_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 1 /* vk_tree_root */ + 1 /* protocol_contract_tree_root */ + GLOBAL_VARIABLES_LENGTH; +global PUBLIC_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = COMBINED_CONSTANT_DATA_LENGTH + + PUBLIC_VALIDATION_REQUESTS_LENGTH + + PUBLIC_ACCUMULATED_DATA_LENGTH + + PUBLIC_ACCUMULATED_DATA_LENGTH + + 1 /* end_side_effect_counter */ + + PUBLIC_CALL_REQUEST_LENGTH + + AZTEC_ADDRESS_LENGTH + + 1 /* revert_code */; +global VM_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = COMBINED_CONSTANT_DATA_LENGTH + + PUBLIC_CALL_REQUEST_LENGTH + + PUBLIC_VALIDATION_REQUESTS_LENGTH + + NUM_PUBLIC_VALIDATION_REQUEST_ARRAYS + + PUBLIC_ACCUMULATED_DATA_LENGTH + + NUM_PUBLIC_ACCUMULATED_DATA_ARRAYS + + 1 /* start_side_effect_counter */ + + 1 /* end_side_effect_counter */ + + GAS_LENGTH + + 1 + + 1 + + (PUBLIC_INNER_CALL_REQUEST_LENGTH * MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX); + +global KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = ROLLUP_VALIDATION_REQUESTS_LENGTH + + COMBINED_ACCUMULATED_DATA_LENGTH + + COMBINED_CONSTANT_DATA_LENGTH + + PARTIAL_STATE_REFERENCE_LENGTH + + 1 + + AZTEC_ADDRESS_LENGTH; + +global CONSTANT_ROLLUP_DATA_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + + 1 /* vk_tree_root */ + + 1 /* protocol_contract_tree_root */ + + GLOBAL_VARIABLES_LENGTH; // + 5 for rollup_type, height_in_block_tree, txs_effects_hash, out_hash, accumulated_fees -global BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH: u32 = CONSTANT_ROLLUP_DATA_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH + 5; -global BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH: u32 = 2 * APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 1 /* previous_block_hash */ + 1 /* end_block_hash */ + 2 * GLOBAL_VARIABLES_LENGTH + 1 /* out_hash */ + AZTEC_EPOCH_DURATION * FEE_RECIPIENT_LENGTH + 1 /* vk_tree_root */ + 1 /* protocol_contract_tree_root */ + 1 /* prover_id */; -global ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH: u32 = 2 * APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 8 + AZTEC_EPOCH_DURATION * FEE_RECIPIENT_LENGTH; +global BASE_OR_MERGE_PUBLIC_INPUTS_LENGTH: u32 = CONSTANT_ROLLUP_DATA_LENGTH + + PARTIAL_STATE_REFERENCE_LENGTH + + PARTIAL_STATE_REFERENCE_LENGTH + + 5; +global BLOCK_ROOT_OR_BLOCK_MERGE_PUBLIC_INPUTS_LENGTH: u32 = 2 * APPEND_ONLY_TREE_SNAPSHOT_LENGTH + + 1 /* previous_block_hash */ + + 1 /* end_block_hash */ + + 2 * GLOBAL_VARIABLES_LENGTH + + 1 /* out_hash */ + + AZTEC_EPOCH_DURATION * FEE_RECIPIENT_LENGTH + + 1 /* vk_tree_root */ + + 1 /* protocol_contract_tree_root */ + + 1 /* prover_id */; +global ROOT_ROLLUP_PUBLIC_INPUTS_LENGTH: u32 = + 2 * APPEND_ONLY_TREE_SNAPSHOT_LENGTH + 8 + AZTEC_EPOCH_DURATION * FEE_RECIPIENT_LENGTH; global GET_NOTES_ORACLE_RETURN_LENGTH: u32 = 674; global NOTE_HASHES_NUM_BYTES_PER_BASE_ROLLUP: u32 = 32 * MAX_NOTE_HASHES_PER_TX; global NULLIFIERS_NUM_BYTES_PER_BASE_ROLLUP: u32 = 32 * MAX_NULLIFIERS_PER_TX; -global PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: u32 = 64 * MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; // 1 write is 64 bytes +global PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP: u32 = + 64 * MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; // 1 write is 64 bytes global CONTRACTS_NUM_BYTES_PER_BASE_ROLLUP: Field = 32; global CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP: Field = 64; global CONTRACT_DATA_NUM_BYTES_PER_BASE_ROLLUP_UNPADDED: Field = 52; @@ -315,8 +458,8 @@ global NUM_MSGS_PER_BASE_PARITY: u32 = 4; global NUM_BASE_PARITY_PER_ROOT_PARITY: u32 = 4; // Lengths of the different types of proofs in fields -global RECURSIVE_PROOF_LENGTH: u32= 463; -global NESTED_RECURSIVE_PROOF_LENGTH: u32= 463; +global RECURSIVE_PROOF_LENGTH: u32 = 463; +global NESTED_RECURSIVE_PROOF_LENGTH: u32 = 463; global TUBE_PROOF_LENGTH: u32 = RECURSIVE_PROOF_LENGTH; // in the future these can differ global HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS: u32 = 128; @@ -333,8 +476,9 @@ global AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS: u32 = 2 + 21 * 4; // To determine latest value, hover `COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS` // in barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp global AVM_PROOF_LENGTH_IN_FIELDS: u32 = 3949; -global AVM_PUBLIC_COLUMN_MAX_SIZE : u32 = 1024; -global AVM_PUBLIC_INPUTS_FLATTENED_SIZE : u32 = 2 * AVM_PUBLIC_COLUMN_MAX_SIZE + PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH; +global AVM_PUBLIC_COLUMN_MAX_SIZE: u32 = 1024; +global AVM_PUBLIC_INPUTS_FLATTENED_SIZE: u32 = + 2 * AVM_PUBLIC_COLUMN_MAX_SIZE + PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH; /** * Enumerate the hash_indices which are used for pedersen hashing. * We start from 1 to avoid the default generators. The generator indices are listed @@ -437,15 +581,24 @@ global TRANSACTION_FEE_KERNEL_INPUTS_COL_OFFSET: u32 = 14; // AVM CIRCUIT - PUBLIC KERNEL OUTPUTS COLUMN OFFSETS // Side effects global START_NOTE_HASH_EXISTS_WRITE_OFFSET: u32 = 0; -global START_NULLIFIER_EXISTS_OFFSET: u32 = START_NOTE_HASH_EXISTS_WRITE_OFFSET + MAX_NOTE_HASH_READ_REQUESTS_PER_CALL; -global START_NULLIFIER_NON_EXISTS_OFFSET: u32 = START_NULLIFIER_EXISTS_OFFSET + MAX_NULLIFIER_READ_REQUESTS_PER_CALL; -global START_L1_TO_L2_MSG_EXISTS_WRITE_OFFSET: u32 = START_NULLIFIER_NON_EXISTS_OFFSET + MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL; -global START_SSTORE_WRITE_OFFSET: u32 = START_L1_TO_L2_MSG_EXISTS_WRITE_OFFSET + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL; -global START_SLOAD_WRITE_OFFSET: u32 = START_SSTORE_WRITE_OFFSET + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL; -global START_EMIT_NOTE_HASH_WRITE_OFFSET: u32 = START_SLOAD_WRITE_OFFSET + MAX_PUBLIC_DATA_READS_PER_CALL; -global START_EMIT_NULLIFIER_WRITE_OFFSET: u32 = START_EMIT_NOTE_HASH_WRITE_OFFSET + MAX_NOTE_HASHES_PER_CALL; -global START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET: u32 = START_EMIT_NULLIFIER_WRITE_OFFSET + MAX_NULLIFIERS_PER_CALL; -global START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET: u32 = START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET + MAX_L2_TO_L1_MSGS_PER_CALL; +global START_NULLIFIER_EXISTS_OFFSET: u32 = + START_NOTE_HASH_EXISTS_WRITE_OFFSET + MAX_NOTE_HASH_READ_REQUESTS_PER_CALL; +global START_NULLIFIER_NON_EXISTS_OFFSET: u32 = + START_NULLIFIER_EXISTS_OFFSET + MAX_NULLIFIER_READ_REQUESTS_PER_CALL; +global START_L1_TO_L2_MSG_EXISTS_WRITE_OFFSET: u32 = + START_NULLIFIER_NON_EXISTS_OFFSET + MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL; +global START_SSTORE_WRITE_OFFSET: u32 = + START_L1_TO_L2_MSG_EXISTS_WRITE_OFFSET + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL; +global START_SLOAD_WRITE_OFFSET: u32 = + START_SSTORE_WRITE_OFFSET + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL; +global START_EMIT_NOTE_HASH_WRITE_OFFSET: u32 = + START_SLOAD_WRITE_OFFSET + MAX_PUBLIC_DATA_READS_PER_CALL; +global START_EMIT_NULLIFIER_WRITE_OFFSET: u32 = + START_EMIT_NOTE_HASH_WRITE_OFFSET + MAX_NOTE_HASHES_PER_CALL; +global START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET: u32 = + START_EMIT_NULLIFIER_WRITE_OFFSET + MAX_NULLIFIERS_PER_CALL; +global START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET: u32 = + START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET + MAX_L2_TO_L1_MSGS_PER_CALL; /** * GAS COSTS FOR AVM OPCODES @@ -522,8 +675,8 @@ global AVM_EMITUNENCRYPTEDLOG_DYN_DA_GAS: u32 = DA_BYTES_PER_FIELD * DA_GAS_PER_ // Constants related to proof type of a recursive proof verification. // Keep following constants in sync with the enum acir_format::PROOF_TYPE in recursion_constraint.hpp -global PROOF_TYPE_PLONK : u32 = 0; -global PROOF_TYPE_HONK : u32 = 1; -global PROOF_TYPE_OINK : u32 = 2; -global PROOF_TYPE_PG : u32 = 3; -global PROOF_TYPE_AVM : u32 = 4; +global PROOF_TYPE_PLONK: u32 = 0; +global PROOF_TYPE_HONK: u32 = 1; +global PROOF_TYPE_OINK: u32 = 2; +global PROOF_TYPE_PG: u32 = 3; +global PROOF_TYPE_AVM: u32 = 4; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/content_commitment.nr b/noir-projects/noir-protocol-circuits/crates/types/src/content_commitment.nr index 71b160aac52..87471caea59 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/content_commitment.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/content_commitment.nr @@ -1,10 +1,10 @@ use crate::{constants::CONTENT_COMMITMENT_LENGTH, traits::{Deserialize, Empty, Serialize}}; pub struct ContentCommitment { - num_txs: Field, - txs_effects_hash: Field, - in_hash: Field, - out_hash: Field, + num_txs: Field, + txs_effects_hash: Field, + in_hash: Field, + out_hash: Field, } impl Serialize for ContentCommitment { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/contract_class_id.nr b/noir-projects/noir-protocol-circuits/crates/types/src/contract_class_id.nr index fbe77eb62f9..515c840de60 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/contract_class_id.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/contract_class_id.nr @@ -2,7 +2,7 @@ use crate::constants::GENERATOR_INDEX__CONTRACT_LEAF; use crate::traits::{ToField, FromField, Serialize, Deserialize}; pub struct ContractClassId { - inner: Field + inner: Field, } impl Eq for ContractClassId { @@ -39,17 +39,12 @@ impl ContractClassId { pub fn compute( artifact_hash: Field, private_functions_root: Field, - public_bytecode_commitment: Field + public_bytecode_commitment: Field, ) -> Self { let hash = crate::hash::poseidon2_hash_with_separator( - [ - artifact_hash, - private_functions_root, - public_bytecode_commitment - ], - GENERATOR_INDEX__CONTRACT_LEAF + [artifact_hash, private_functions_root, public_bytecode_commitment], + GENERATOR_INDEX__CONTRACT_LEAF, ); // TODO(@spalladino): Update generator index - ContractClassId::from_field(hash) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr b/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr index 95f113ec1c3..dfe75822aba 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/contract_instance.nr @@ -1,15 +1,17 @@ use crate::{ - address::{aztec_address::AztecAddress, partial_address::PartialAddress, public_keys_hash::PublicKeysHash}, - public_keys::PublicKeys, contract_class_id::ContractClassId, constants::CONTRACT_INSTANCE_LENGTH, - traits::{Deserialize, Hash, Serialize} + address::{ + aztec_address::AztecAddress, partial_address::PartialAddress, + public_keys_hash::PublicKeysHash, + }, public_keys::PublicKeys, contract_class_id::ContractClassId, + constants::CONTRACT_INSTANCE_LENGTH, traits::{Deserialize, Hash, Serialize}, }; pub struct ContractInstance { - salt : Field, + salt: Field, deployer: AztecAddress, - contract_class_id : ContractClassId, - initialization_hash : Field, - public_keys : PublicKeys, + contract_class_id: ContractClassId, + initialization_hash: Field, + public_keys: PublicKeys, } impl Eq for ContractInstance { @@ -40,7 +42,7 @@ impl Serialize for ContractInstance { public_keys_serialized[8], public_keys_serialized[9], public_keys_serialized[10], - public_keys_serialized[11] + public_keys_serialized[11], ] } } @@ -52,8 +54,7 @@ impl Deserialize for ContractInstance { deployer: AztecAddress::from_field(serialized[1]), contract_class_id: ContractClassId::from_field(serialized[2]), initialization_hash: serialized[3], - public_keys: PublicKeys::deserialize( - [ + public_keys: PublicKeys::deserialize([ serialized[4], serialized[5], serialized[6], @@ -65,9 +66,8 @@ impl Deserialize for ContractInstance { serialized[12], serialized[13], serialized[14], - serialized[15] - ] - ) + serialized[15], + ]), } } } @@ -86,8 +86,8 @@ impl ContractInstance { self.contract_class_id, self.salt, self.initialization_hash, - self.deployer - ) + self.deployer, + ), ) } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_read.nr b/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_read.nr index b69bc4915e3..c72347be04f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_read.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_read.nr @@ -28,7 +28,11 @@ impl Serialize for StorageRead { impl Deserialize for StorageRead { fn deserialize(serialized: [Field; CONTRACT_STORAGE_READ_LENGTH]) -> Self { - Self { storage_slot: serialized[0], current_value: serialized[1], counter: serialized[2] as u32 } + Self { + storage_slot: serialized[0], + current_value: serialized[1], + counter: serialized[2] as u32, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr index 46efa3d7c5c..37cb287f5d2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/contrakt/storage_update_request.nr @@ -1,9 +1,11 @@ -use crate::{constants::CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH, traits::{Deserialize, Empty, Serialize}}; +use crate::{ + constants::CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH, traits::{Deserialize, Empty, Serialize}, +}; pub struct StorageUpdateRequest { - storage_slot : Field, - new_value : Field, - counter: u32 + storage_slot: Field, + new_value: Field, + counter: u32, } impl Eq for StorageUpdateRequest { @@ -26,7 +28,11 @@ impl Serialize for StorageUpdateRequest impl Deserialize for StorageUpdateRequest { fn deserialize(serialized: [Field; CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH]) -> Self { - StorageUpdateRequest { storage_slot: serialized[0], new_value: serialized[1], counter: serialized[2] as u32 } + StorageUpdateRequest { + storage_slot: serialized[0], + new_value: serialized[1], + counter: serialized[2] as u32, + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/data/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/data/hash.nr index da59417bbc6..76561daabd7 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/data/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/data/hash.nr @@ -1,12 +1,12 @@ use crate::{address::AztecAddress, constants::GENERATOR_INDEX__PUBLIC_LEAF_INDEX}; -pub fn compute_public_data_tree_index(contract_address: AztecAddress, storage_slot: Field) -> Field { +pub fn compute_public_data_tree_index( + contract_address: AztecAddress, + storage_slot: Field, +) -> Field { crate::hash::poseidon2_hash_with_separator( - [ - contract_address.to_field(), - storage_slot - ], - GENERATOR_INDEX__PUBLIC_LEAF_INDEX + [contract_address.to_field(), storage_slot], + GENERATOR_INDEX__PUBLIC_LEAF_INDEX, ) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_hint.nr b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_hint.nr index 7625534119a..75d40b0e754 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_hint.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_hint.nr @@ -1,7 +1,7 @@ use crate::{ data::public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, traits::Empty, merkle_tree::{MembershipWitness, conditionally_assert_check_membership}, - constants::PUBLIC_DATA_TREE_HEIGHT + constants::PUBLIC_DATA_TREE_HEIGHT, }; pub struct PublicDataHint { @@ -20,7 +20,8 @@ impl PublicDataHint { let exists_in_tree = self.leaf_slot == self.leaf_preimage.slot; if exists_in_tree { assert( - self.value == self.leaf_preimage.value, "Hinted public data value does not match the value in leaf preimage" + self.value == self.leaf_preimage.value, + "Hinted public data value does not match the value in leaf preimage", ); } else { assert(self.value == 0, "Value must be 0 for non-existent public data"); @@ -31,7 +32,7 @@ impl PublicDataHint { exists_in_tree, self.leaf_preimage, self.membership_witness, - public_data_tree_root + public_data_tree_root, ); } } @@ -44,7 +45,7 @@ impl Empty for PublicDataHint { value: 0, override_counter: 0, membership_witness: MembershipWitness::empty(), - leaf_preimage: PublicDataTreeLeafPreimage::empty() + leaf_preimage: PublicDataTreeLeafPreimage::empty(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_leaf_hint.nr b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_leaf_hint.nr index f7a544abb4a..a6fb45794a0 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_leaf_hint.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_leaf_hint.nr @@ -1,6 +1,6 @@ use crate::{ data::public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, traits::Empty, - merkle_tree::MembershipWitness, constants::PUBLIC_DATA_TREE_HEIGHT + merkle_tree::MembershipWitness, constants::PUBLIC_DATA_TREE_HEIGHT, }; pub struct PublicDataLeafHint { @@ -10,6 +10,9 @@ pub struct PublicDataLeafHint { impl Empty for PublicDataLeafHint { fn empty() -> Self { - PublicDataLeafHint { preimage: PublicDataTreeLeafPreimage::empty(), membership_witness: MembershipWitness::empty() } + PublicDataLeafHint { + preimage: PublicDataTreeLeafPreimage::empty(), + membership_witness: MembershipWitness::empty(), + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf.nr b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf.nr index 5a0cdb28f58..07c2fd40a6d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf.nr @@ -1,4 +1,6 @@ -use crate::{abis::{public_data_read::PublicDataRead, side_effect::{Overridable, Readable}}, traits::Empty}; +use crate::{ + abis::{public_data_read::PublicDataRead, side_effect::{Overridable, Readable}}, traits::Empty, +}; pub struct PublicDataTreeLeaf { slot: Field, @@ -37,10 +39,14 @@ impl Empty for OverridablePublicDataTreeLeaf { impl Readable for OverridablePublicDataTreeLeaf { fn assert_match_read_request(self, read_request: PublicDataRead) { assert_eq( - self.leaf.slot, read_request.leaf_slot, "leaf_slot in OverridablePublicDataTreeLeaf does not match read request" + self.leaf.slot, + read_request.leaf_slot, + "leaf_slot in OverridablePublicDataTreeLeaf does not match read request", ); assert_eq( - self.leaf.value, read_request.value, "value in OverridablePublicDataTreeLeaf does not match read request" + self.leaf.value, + read_request.value, + "value in OverridablePublicDataTreeLeaf does not match read request", ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf_preimage.nr b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf_preimage.nr index df33169354c..99d9b410412 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf_preimage.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/data/public_data_tree_leaf_preimage.nr @@ -1,10 +1,10 @@ use crate::{merkle_tree::leaf_preimage::IndexedTreeLeafPreimage, traits::{Empty, Hash}}; pub struct PublicDataTreeLeafPreimage { - slot : Field, + slot: Field, value: Field, - next_slot :Field, - next_index : u32, + next_slot: Field, + next_index: u32, } impl Empty for PublicDataTreeLeafPreimage { @@ -18,7 +18,12 @@ impl Hash for PublicDataTreeLeafPreimage { if self.is_empty() { 0 } else { - crate::hash::poseidon2_hash([self.slot, self.value, (self.next_index as Field), self.next_slot]) + crate::hash::poseidon2_hash([ + self.slot, + self.value, + (self.next_index as Field), + self.next_slot, + ]) } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr b/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr index 8bf831ced3f..706139c8409 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr @@ -12,12 +12,13 @@ pub fn debug_log(msg: str) { /// debug_log_format("whole array: {}", [e1, e2, e3, e4]); pub fn debug_log_format(msg: str, args: [Field; N]) { // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. - unsafe { - debug_log_oracle_wrapper(msg, args) - }; + unsafe { debug_log_oracle_wrapper(msg, args) }; } -pub unconstrained fn debug_log_oracle_wrapper(msg: str, args: [Field; N]) { +pub unconstrained fn debug_log_oracle_wrapper( + msg: str, + args: [Field; N], +) { debug_log_oracle(msg, args.as_slice()); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr index a9530bd304b..63c14f6966e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/hash.nr @@ -1,19 +1,18 @@ use crate::{ abis::{ - contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage, - function_selector::FunctionSelector, log_hash::{LogHash, ScopedLogHash, ScopedEncryptedLogHash}, - note_hash::ScopedNoteHash, nullifier::ScopedNullifier -}, - address::{AztecAddress, EthAddress}, + contract_class_function_leaf_preimage::ContractClassFunctionLeafPreimage, + function_selector::FunctionSelector, + log_hash::{LogHash, ScopedLogHash, ScopedEncryptedLogHash}, note_hash::ScopedNoteHash, + nullifier::ScopedNullifier, + }, address::{AztecAddress, EthAddress}, constants::{ - FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__OUTER_NULLIFIER, - GENERATOR_INDEX__VK, GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH, - MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX -}, - merkle_tree::root::root_from_sibling_path, + FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__SILOED_NOTE_HASH, GENERATOR_INDEX__OUTER_NULLIFIER, + GENERATOR_INDEX__VK, GENERATOR_INDEX__NOTE_HASH_NONCE, GENERATOR_INDEX__UNIQUE_NOTE_HASH, + MAX_ENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, + }, merkle_tree::root::root_from_sibling_path, messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message}, recursion::verification_key::VerificationKey, traits::{is_empty, ToField}, - utils::field::field_from_bytes_32_trunc + utils::field::field_from_bytes_32_trunc, }; use super::utils::field::field_from_bytes; @@ -28,21 +27,22 @@ pub fn private_functions_root_from_siblings( selector: FunctionSelector, vk_hash: Field, function_leaf_index: Field, - function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT] + function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT], ) -> Field { let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash }; let function_leaf = function_leaf_preimage.hash(); - root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path) + root_from_sibling_path( + function_leaf, + function_leaf_index, + function_leaf_sibling_path, + ) } fn compute_note_hash_nonce(tx_hash: Field, note_index_in_tx: u32) -> Field { // Hashing tx hash with note index in tx is guaranteed to be unique poseidon2_hash_with_separator( - [ - tx_hash, - note_index_in_tx as Field - ], - GENERATOR_INDEX__NOTE_HASH_NONCE + [tx_hash, note_index_in_tx as Field], + GENERATOR_INDEX__NOTE_HASH_NONCE, ) } @@ -53,11 +53,8 @@ pub fn compute_unique_note_hash(nonce: Field, note_hash: Field) -> Field { pub fn compute_siloed_note_hash(app: AztecAddress, unique_note_hash: Field) -> Field { poseidon2_hash_with_separator( - [ - app.to_field(), - unique_note_hash - ], - GENERATOR_INDEX__SILOED_NOTE_HASH + [app.to_field(), unique_note_hash], + GENERATOR_INDEX__SILOED_NOTE_HASH, ) } @@ -75,11 +72,8 @@ pub fn silo_note_hash(note_hash: ScopedNoteHash, tx_hash: Field, note_index_in_t pub fn compute_siloed_nullifier(app: AztecAddress, nullifier: Field) -> Field { poseidon2_hash_with_separator( - [ - app.to_field(), - nullifier - ], - GENERATOR_INDEX__OUTER_NULLIFIER + [app.to_field(), nullifier], + GENERATOR_INDEX__OUTER_NULLIFIER, ) } @@ -96,7 +90,9 @@ pub fn silo_encrypted_log_hash(log_hash: ScopedLogHash) -> Field { if log_hash.contract_address.is_zero() { 0 } else { - accumulate_sha256([log_hash.contract_address.to_field(), log_hash.log_hash.value]) + accumulate_sha256( + [log_hash.contract_address.to_field(), log_hash.log_hash.value], + ) } } @@ -106,12 +102,10 @@ pub fn mask_encrypted_log_hash(scoped_log: ScopedEncryptedLogHash) -> AztecAddre } else if (scoped_log.log_hash.randomness == 0) { scoped_log.contract_address } else { - AztecAddress::from_field( - poseidon2_hash_with_separator( - [scoped_log.contract_address.to_field(), scoped_log.log_hash.randomness], - 0 - ) - ) + AztecAddress::from_field(poseidon2_hash_with_separator( + [scoped_log.contract_address.to_field(), scoped_log.log_hash.randomness], + 0, + )) } } @@ -131,7 +125,9 @@ pub fn merkle_hash(left: Field, right: Field) -> Field { poseidon2_hash([left, right]) } -pub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field { +pub fn stdlib_recursion_verification_key_compress_native_vk( + _vk: VerificationKey, +) -> Field { // Original cpp code // stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK); // The above cpp method is only ever called on verification key, so it has been special cased here @@ -144,11 +140,12 @@ pub fn compute_l2_to_l1_hash( recipient: EthAddress, content: Field, rollup_version_id: Field, - chain_id: Field + chain_id: Field, ) -> Field { let mut bytes: BoundedVec = BoundedVec::new(); - let inputs = [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content]; + let inputs = + [contract_address.to_field(), rollup_version_id, recipient.to_field(), chain_id, content]; for i in 0..inputs.len() { // TODO are bytes be in fr.to_buffer() ? let item_bytes: [u8; 32] = inputs[i].to_be_bytes(); @@ -160,7 +157,11 @@ pub fn compute_l2_to_l1_hash( sha256_to_field(bytes.storage) } -pub fn silo_l2_to_l1_message(msg: ScopedL2ToL1Message, rollup_version_id: Field, chain_id: Field) -> Field { +pub fn silo_l2_to_l1_message( + msg: ScopedL2ToL1Message, + rollup_version_id: Field, + chain_id: Field, +) -> Field { if msg.contract_address.is_zero() { 0 } else { @@ -169,7 +170,7 @@ pub fn silo_l2_to_l1_message(msg: ScopedL2ToL1Message, rollup_version_id: Field, msg.message.recipient, msg.message.content, rollup_version_id, - chain_id + chain_id, ) } } @@ -191,7 +192,6 @@ pub fn accumulate_sha256(input: [Field; 2]) -> Field { // only occupies 128 bits. // // TODO(David): This does not seem to be getting guaranteed anywhere in the code? - // Concatentate two fields into 32x2 = 64 bytes // accumulate_sha256 assumes that the inputs are pre-truncated 31 byte numbers let mut hash_input_flattened = [0; 64]; @@ -266,14 +266,14 @@ pub fn poseidon2_hash(inputs: [Field; N]) -> Field { } #[no_predicates] -pub fn poseidon2_hash_with_separator( - inputs: [Field; N], - separator: T -) -> Field where T: ToField { +pub fn poseidon2_hash_with_separator(inputs: [Field; N], separator: T) -> Field +where + T: ToField, +{ // We manually hash the inputs here, since we cannot express with the type system a constant size inputs array of N + 1 let in_len = N + 1; let two_pow_64 = 18446744073709551616; - let iv : Field = (in_len as Field) * two_pow_64; + let iv: Field = (in_len as Field) * two_pow_64; let mut sponge = std::hash::poseidon2::Poseidon2::new(iv); sponge.absorb(separator.to_field()); @@ -284,10 +284,13 @@ pub fn poseidon2_hash_with_separator( sponge.squeeze() } -pub fn poseidon2_hash_with_separator_slice(inputs: [Field], separator: T) -> Field where T: ToField { +pub fn poseidon2_hash_with_separator_slice(inputs: [Field], separator: T) -> Field +where + T: ToField, +{ let in_len = inputs.len() + 1; let two_pow_64 = 18446744073709551616; - let iv : Field = (in_len as Field) * two_pow_64; + let iv: Field = (in_len as Field) * two_pow_64; let mut sponge = std::hash::poseidon2::Poseidon2::new(iv); sponge.absorb(separator.to_field()); @@ -309,7 +312,7 @@ pub fn poseidon2_hash_bytes(inputs: [u8; N]) -> Field { } let two_pow_64 = 18446744073709551616; - let iv : Field = (in_len as Field) * two_pow_64; + let iv: Field = (in_len as Field) * two_pow_64; let mut sponge = std::hash::poseidon2::Poseidon2::new(iv); let mut current_field = [0; 31]; @@ -331,14 +334,14 @@ pub fn poseidon2_hash_bytes(inputs: [u8; N]) -> Field { #[test] fn smoke_sha256_to_field() { let full_buffer = [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, ]; let result = sha256_to_field(full_buffer); @@ -355,11 +358,18 @@ fn smoke_sha256_to_field() { #[test] fn compute_l2_l1_hash() { // All zeroes - let hash_result = compute_l2_to_l1_hash(AztecAddress::from_field(0), EthAddress::zero(), 0, 0, 0); + let hash_result = + compute_l2_to_l1_hash(AztecAddress::from_field(0), EthAddress::zero(), 0, 0, 0); assert(hash_result == 0xb393978842a0fa3d3e1470196f098f473f9678e72463cb65ec4ab5581856c2); // Non-zero case - let hash_result = compute_l2_to_l1_hash(AztecAddress::from_field(1), EthAddress::from_field(3), 5, 2, 4); + let hash_result = compute_l2_to_l1_hash( + AztecAddress::from_field(1), + EthAddress::from_field(3), + 5, + 2, + 4, + ); assert(hash_result == 0x3f88c1044a05e5340ed20466276500f6d45ca5603913b9091e957161734e16); } @@ -370,11 +380,11 @@ fn silo_l2_to_l1_message_matches_typescript() { let hash = silo_l2_to_l1_message( ScopedL2ToL1Message { - message: L2ToL1Message { recipient: EthAddress::from_field(1), content: 2, counter: 0 }, - contract_address: AztecAddress::from_field(3) - }, + message: L2ToL1Message { recipient: EthAddress::from_field(1), content: 2, counter: 0 }, + contract_address: AztecAddress::from_field(3), + }, version, - chainId + chainId, ); // The following value was generated by `l2_to_l1_message.test.ts` diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/header.nr b/noir-projects/noir-protocol-circuits/crates/types/src/header.nr index c92dfdbc16d..d56fa590b9f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/header.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/header.nr @@ -1,15 +1,14 @@ use crate::{ abis::{ - append_only_tree_snapshot::{AppendOnlyTreeSnapshot, APPEND_ONLY_TREE_SNAPSHOT_LENGTH}, - global_variables::GlobalVariables -}, + append_only_tree_snapshot::{AppendOnlyTreeSnapshot, APPEND_ONLY_TREE_SNAPSHOT_LENGTH}, + global_variables::GlobalVariables, + }, constants::{ - GENERATOR_INDEX__BLOCK_HASH, GLOBAL_VARIABLES_LENGTH, HEADER_LENGTH, STATE_REFERENCE_LENGTH, - CONTENT_COMMITMENT_LENGTH -}, - hash::poseidon2_hash_with_separator, state_reference::StateReference, + GENERATOR_INDEX__BLOCK_HASH, GLOBAL_VARIABLES_LENGTH, HEADER_LENGTH, STATE_REFERENCE_LENGTH, + CONTENT_COMMITMENT_LENGTH, + }, hash::poseidon2_hash_with_separator, state_reference::StateReference, traits::{Deserialize, Empty, Hash, Serialize}, utils::arr_copy_slice, - content_commitment::ContentCommitment + content_commitment::ContentCommitment, }; // docs:start:header @@ -18,7 +17,7 @@ pub struct Header { content_commitment: ContentCommitment, state: StateReference, global_variables: GlobalVariables, - total_fees: Field + total_fees: Field, } // docs:end:header @@ -50,16 +49,19 @@ impl Deserialize for Header { fn deserialize(serialized: [Field; HEADER_LENGTH]) -> Self { let mut offset = 0; - let last_archive_fields = arr_copy_slice(serialized, [0; APPEND_ONLY_TREE_SNAPSHOT_LENGTH], offset); + let last_archive_fields = + arr_copy_slice(serialized, [0; APPEND_ONLY_TREE_SNAPSHOT_LENGTH], offset); offset = offset + APPEND_ONLY_TREE_SNAPSHOT_LENGTH; - let content_commitment_fields = arr_copy_slice(serialized, [0; CONTENT_COMMITMENT_LENGTH], offset); + let content_commitment_fields = + arr_copy_slice(serialized, [0; CONTENT_COMMITMENT_LENGTH], offset); offset = offset + CONTENT_COMMITMENT_LENGTH; let state_fields = arr_copy_slice(serialized, [0; STATE_REFERENCE_LENGTH], offset); offset = offset + STATE_REFERENCE_LENGTH; - let global_variables_fields = arr_copy_slice(serialized, [0; GLOBAL_VARIABLES_LENGTH], offset); + let global_variables_fields = + arr_copy_slice(serialized, [0; GLOBAL_VARIABLES_LENGTH], offset); offset = offset + GLOBAL_VARIABLES_LENGTH; let total_fees = serialized[offset]; @@ -69,7 +71,7 @@ impl Deserialize for Header { content_commitment: ContentCommitment::deserialize(content_commitment_fields), state: StateReference::deserialize(state_fields), global_variables: GlobalVariables::deserialize(global_variables_fields), - total_fees + total_fees, } } } @@ -81,7 +83,7 @@ impl Empty for Header { content_commitment: ContentCommitment::empty(), state: StateReference::empty(), global_variables: GlobalVariables::empty(), - total_fees: 0 + total_fees: 0, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr index 348b531c597..4fa82de35ff 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr @@ -34,5 +34,5 @@ mod meta; pub use abis::kernel_circuit_public_inputs::{ KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, - VMCircuitPublicInputs + VMCircuitPublicInputs, }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr index f1a1b2bafa1..61f38065ef8 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/append_only_tree.nr @@ -1,6 +1,6 @@ use crate::{ - abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot}, - merkle_tree::{membership::assert_check_membership, root::root_from_sibling_path} + abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, + merkle_tree::{membership::assert_check_membership, root::root_from_sibling_path}, }; pub fn insert_subtree_to_snapshot_tree( @@ -8,7 +8,7 @@ pub fn insert_subtree_to_snapshot_tree( sibling_path: [Field; N], empty_subtree_root: Field, subtree_root_to_insert: Field, - subtree_depth: u8 + subtree_depth: u8, ) -> AppendOnlyTreeSnapshot { // TODO(Lasse): Sanity check len of sibling_path > height of subtree // TODO(Lasse): Ensure height of subtree is correct (eg 3 for commitments, 1 for contracts) @@ -19,18 +19,22 @@ pub fn insert_subtree_to_snapshot_tree( empty_subtree_root, leaf_index_at_depth as Field, sibling_path, - snapshot.root + snapshot.root, ); // if index of leaf is x, index of its parent is x/2 or x >> 1. We need to find the parent `subtree_depth` levels up. let new_root = root_from_sibling_path( subtree_root_to_insert, leaf_index_at_depth as Field, - sibling_path + sibling_path, ); // 2^subtree_depth is the number of leaves added. 2^x = 1 << x - let new_next_available_leaf_index = (snapshot.next_available_leaf_index as u64) + (1 << (subtree_depth as u8)); + let new_next_available_leaf_index = + (snapshot.next_available_leaf_index as u64) + (1 << (subtree_depth as u8)); - AppendOnlyTreeSnapshot { root: new_root, next_available_leaf_index: new_next_available_leaf_index as u32 } + AppendOnlyTreeSnapshot { + root: new_root, + next_available_leaf_index: new_next_available_leaf_index as u32, + } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr index 23d400e0b95..aa44d2c84f5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree.nr @@ -1,22 +1,14 @@ mod check_valid_low_leaf; use crate::{ - abis::{append_only_tree_snapshot::AppendOnlyTreeSnapshot}, + abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, merkle_tree::{ - membership::{assert_check_membership, MembershipWitness}, - root::{calculate_subtree_root, calculate_empty_tree_root, root_from_sibling_path} -}, - traits::{Empty, Hash, is_empty}, utils::arrays::check_permutation + membership::{assert_check_membership, MembershipWitness}, + root::{calculate_subtree_root, calculate_empty_tree_root, root_from_sibling_path}, + }, traits::{Empty, Hash, is_empty}, utils::arrays::check_permutation, }; -pub fn batch_insert< - Value, - Leaf, - let SubtreeWidth: u32, - let SiblingPathLength: u32, - let SubtreeHeight: u32, - let TreeHeight: u32 ->( +pub fn batch_insert( start_snapshot: AppendOnlyTreeSnapshot, values_to_insert: [Value; SubtreeWidth], sorted_values: [Value; SubtreeWidth], @@ -28,8 +20,12 @@ pub fn batch_insert< update_low_leaf: fn(Leaf, Value, u32) -> Leaf, build_insertion_leaf: fn(Value, Leaf) -> Leaf, _subtree_height: [Field; SubtreeHeight], - _tree_height: [Field; TreeHeight] -) -> AppendOnlyTreeSnapshot where Value: Eq + Empty, Leaf: Hash + Empty { + _tree_height: [Field; TreeHeight], +) -> AppendOnlyTreeSnapshot +where + Value: Eq + Empty, + Leaf: Hash + Empty, +{ // A permutation to the values is provided to make the insertion use only one insertion strategy check_permutation(values_to_insert, sorted_values, sorted_values_indexes); @@ -51,7 +47,7 @@ pub fn batch_insert< low_leaf_preimage.hash(), witness.leaf_index, witness.sibling_path, - current_tree_root + current_tree_root, ); let value_index = sorted_values_indexes[i]; @@ -60,11 +56,14 @@ pub fn batch_insert< let updated_low_leaf = update_low_leaf( low_leaf_preimage, value, - start_insertion_index as u32 + value_index + start_insertion_index as u32 + value_index, ); current_tree_root = root_from_sibling_path( - updated_low_leaf.hash(), witness.leaf_index, witness.sibling_path); + updated_low_leaf.hash(), + witness.leaf_index, + witness.sibling_path, + ); insertion_subtree[value_index] = build_insertion_leaf(value, low_leaf_preimage); } @@ -77,7 +76,7 @@ pub fn batch_insert< empty_subtree_root, leaf_index_subtree_depth as Field, new_subtree_sibling_path, - current_tree_root + current_tree_root, ); // Create new subtree to insert into the whole indexed tree @@ -86,7 +85,14 @@ pub fn batch_insert< // Calculate the new root // We are inserting a subtree rather than a full tree here let subtree_index = start_insertion_index >> (SubtreeHeight as u8); - let new_root = root_from_sibling_path(subtree_root, subtree_index as Field, new_subtree_sibling_path); + let new_root = root_from_sibling_path( + subtree_root, + subtree_index as Field, + new_subtree_sibling_path, + ); - AppendOnlyTreeSnapshot { root: new_root, next_available_leaf_index: start_insertion_index + (values_to_insert.len() as u32) } + AppendOnlyTreeSnapshot { + root: new_root, + next_available_leaf_index: start_insertion_index + (values_to_insert.len() as u32), + } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree/check_valid_low_leaf.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree/check_valid_low_leaf.nr index 2f7b252064f..f7f625ce836 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree/check_valid_low_leaf.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/indexed_tree/check_valid_low_leaf.nr @@ -1,9 +1,9 @@ use crate::merkle_tree::leaf_preimage::IndexedTreeLeafPreimage; -pub fn assert_check_valid_low_leaf( - key: Field, - low_leaf_preimage: LEAF_PREIMAGE -) where LEAF_PREIMAGE: IndexedTreeLeafPreimage { +pub fn assert_check_valid_low_leaf(key: Field, low_leaf_preimage: LEAF_PREIMAGE) +where + LEAF_PREIMAGE: IndexedTreeLeafPreimage, +{ let low_key = low_leaf_preimage.get_key(); let next_key = low_leaf_preimage.get_next_key(); @@ -12,11 +12,9 @@ pub fn assert_check_valid_low_leaf( } mod tests { - use crate::{ - merkle_tree::{ + use crate::merkle_tree::{ leaf_preimage::IndexedTreeLeafPreimage, - indexed_tree::check_valid_low_leaf::assert_check_valid_low_leaf - } + indexed_tree::check_valid_low_leaf::assert_check_valid_low_leaf, }; struct TestLeafPreimage { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr index 80aa98c04a6..62a4ac53bc5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/membership.nr @@ -1,14 +1,14 @@ use crate::{ merkle_tree::{ - leaf_preimage::IndexedTreeLeafPreimage, - indexed_tree::check_valid_low_leaf::assert_check_valid_low_leaf, root::root_from_sibling_path -}, - traits::Empty + leaf_preimage::IndexedTreeLeafPreimage, + indexed_tree::check_valid_low_leaf::assert_check_valid_low_leaf, + root::root_from_sibling_path, + }, traits::Empty, }; pub struct MembershipWitness { leaf_index: Field, - sibling_path: [Field; N] + sibling_path: [Field; N], } impl Empty for MembershipWitness { @@ -17,12 +17,22 @@ impl Empty for MembershipWitness { } } -pub fn check_membership(leaf: Field, index: Field, sibling_path: [Field; N], root: Field) -> bool { +pub fn check_membership( + leaf: Field, + index: Field, + sibling_path: [Field; N], + root: Field, +) -> bool { let calculated_root = root_from_sibling_path(leaf, index, sibling_path); calculated_root == root } -pub fn assert_check_membership(leaf: Field, index: Field, sibling_path: [Field; TREE_HEIGHT], root: Field) { +pub fn assert_check_membership( + leaf: Field, + index: Field, + sibling_path: [Field; TREE_HEIGHT], + root: Field, +) { assert(check_membership(leaf, index, sibling_path, root), "membership check failed"); } @@ -30,16 +40,18 @@ pub fn assert_check_non_membership( key: Field, low_leaf_preimage: LEAF_PREIMAGE, low_leaf_membership_witness: MembershipWitness, - tree_root: Field -) where - LEAF_PREIMAGE: IndexedTreeLeafPreimage { + tree_root: Field, +) +where + LEAF_PREIMAGE: IndexedTreeLeafPreimage, +{ assert_check_valid_low_leaf(key, low_leaf_preimage); let low_leaf_exists = check_membership( low_leaf_preimage.as_leaf(), low_leaf_membership_witness.leaf_index, low_leaf_membership_witness.sibling_path, - tree_root + tree_root, ); assert(low_leaf_exists, "Low leaf does not exist"); } @@ -51,9 +63,11 @@ pub fn conditionally_assert_check_membership, - tree_root: Field -) where - LEAF_PREIMAGE: IndexedTreeLeafPreimage { + tree_root: Field, +) +where + LEAF_PREIMAGE: IndexedTreeLeafPreimage, +{ if exists { assert(key == leaf_preimage.get_key(), "Key does not match the key of the leaf preimage"); } else { @@ -64,20 +78,19 @@ pub fn conditionally_assert_check_membership MerkleTree { // hash base layer for i in 0..half_size { - nodes[i] = merkle_hash(leaves[2*i], leaves[2*i+1]); + nodes[i] = merkle_hash(leaves[2 * i], leaves[2 * i + 1]); } // hash the other layers for i in 0..(total_nodes - half_size) { - nodes[half_size+i] = merkle_hash(nodes[2*i], nodes[2*i+1]); + nodes[half_size + i] = merkle_hash(nodes[2 * i], nodes[2 * i + 1]); } MerkleTree { leaves, nodes } @@ -37,7 +37,11 @@ impl MerkleTree { } pub fn sibling_index(index: u32) -> u32 { - if index % 2 == 0 { index + 1 } else { index - 1 } + if index % 2 == 0 { + index + 1 + } else { + index - 1 + } } fn get_sibling_path(self, leaf_index: u32) -> [Field; K] { @@ -69,5 +73,9 @@ impl MerkleTree { } pub fn sibling_index(index: u32) -> u32 { - if index % 2 == 0 { index + 1 } else { index - 1 } + if index % 2 == 0 { + index + 1 + } else { + index - 1 + } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/mod.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/mod.nr index a88c4b01e9a..5c306bbc575 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/mod.nr @@ -9,7 +9,7 @@ mod variable_merkle_tree; pub use leaf_preimage::{IndexedTreeLeafPreimage, LeafPreimage}; pub use membership::{ assert_check_membership, assert_check_non_membership, check_membership, - conditionally_assert_check_membership, MembershipWitness + conditionally_assert_check_membership, MembershipWitness, }; pub use merkle_tree::MerkleTree; pub use variable_merkle_tree::VariableMerkleTree; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/root.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/root.nr index c16bfeac356..79f33ca5c0c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/root.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/root.nr @@ -13,7 +13,7 @@ use crate::{hash::merkle_hash, merkle_tree::merkle_tree::MerkleTree}; pub fn root_from_sibling_path( leaf: Field, leaf_index: Field, - sibling_path: [Field; N] + sibling_path: [Field; N], ) -> Field { let mut node = leaf; let indices: [u1; N] = leaf_index.to_le_bits(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr index b4ffadabeb6..483670f475b 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr @@ -1,4 +1,4 @@ -use crate::{hash::accumulate_sha256}; +use crate::hash::accumulate_sha256; // N = maximum leaves // For now we only care about the root pub struct VariableMerkleTree { @@ -33,15 +33,13 @@ impl VariableMerkleTree { // pub fn new_sha(leaves: [Field; N], num_non_empty_leaves: u32) -> Self { // Find size of tree required - let height = unsafe { - get_height(num_non_empty_leaves, 0) - }; + let height = unsafe { get_height(num_non_empty_leaves, 0) }; let next_power_2 = 2 << height; let prev_power_2 = next_power_2 / 2; assert( (num_non_empty_leaves == 0) - | (num_non_empty_leaves == 1) - | (num_non_empty_leaves > prev_power_2) + | (num_non_empty_leaves == 1) + | (num_non_empty_leaves > prev_power_2), ); assert(num_non_empty_leaves <= next_power_2); // hash base layer @@ -58,26 +56,26 @@ impl VariableMerkleTree { stop = true; } if (!stop) { - nodes[i] = accumulate_sha256([leaves[2*i], leaves[2*i+1]]); + nodes[i] = accumulate_sha256([leaves[2 * i], leaves[2 * i + 1]]); } } // hash the other layers - stop = if prev_power_2 == 1 {true} else {false}; + stop = if prev_power_2 == 1 { true } else { false }; let mut next_layer_end = prev_power_2 / 2; let mut next_layer_size = next_layer_end; let mut root = nodes[0]; for i in 0..(N - 1 - N / 2) { if !stop { - nodes[prev_power_2+i] = accumulate_sha256([nodes[2*i], nodes[2*i+1]]); + nodes[prev_power_2 + i] = accumulate_sha256([nodes[2 * i], nodes[2 * i + 1]]); if i == next_layer_end { // Reached next layer => move up one layer - next_layer_size = next_layer_size/2; + next_layer_size = next_layer_size / 2; next_layer_end += next_layer_size; } if (next_layer_size == 1) { // Reached root - root = nodes[prev_power_2+i]; + root = nodes[prev_power_2 + i]; stop = true; } } @@ -94,7 +92,7 @@ impl VariableMerkleTree { mod tests { use crate::{ merkle_tree::{variable_merkle_tree::VariableMerkleTree, merkle_tree::MerkleTree}, - hash::accumulate_sha256 + hash::accumulate_sha256, }; fn generate_test_array(non_empty_items: u32) -> [Field; 100] { @@ -117,11 +115,11 @@ mod tests { let half_size = N / 2; // hash base layer for i in 0..half_size { - nodes[i] = accumulate_sha256([leaves[2*i], leaves[2*i+1]]); + nodes[i] = accumulate_sha256([leaves[2 * i], leaves[2 * i + 1]]); } // hash the other layers for i in 0..(total_nodes - half_size) { - nodes[half_size+i] = accumulate_sha256([nodes[2*i], nodes[2*i+1]]); + nodes[half_size + i] = accumulate_sha256([nodes[2 * i], nodes[2 * i + 1]]); } MerkleTree { leaves, nodes } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr b/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr index e083d269d50..0ff95b3e140 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/messaging/l2_to_l1_message.nr @@ -2,7 +2,7 @@ use crate::{ address::{AztecAddress, EthAddress}, constants::{L2_TO_L1_MESSAGE_LENGTH, SCOPED_L2_TO_L1_MESSAGE_LENGTH}, abis::side_effect::{Ordered, Scoped}, traits::{Deserialize, Empty, Serialize}, - utils::{arrays::array_concat, reader::Reader} + utils::{arrays::array_concat, reader::Reader}, }; // Note: Not to be confused with L2ToL1Msg in Solidity @@ -40,7 +40,11 @@ impl Serialize for L2ToL1Message { impl Deserialize for L2ToL1Message { fn deserialize(values: [Field; L2_TO_L1_MESSAGE_LENGTH]) -> Self { - Self { recipient: EthAddress::from_field(values[0]), content: values[1], counter: values[2] as u32 } + Self { + recipient: EthAddress::from_field(values[0]), + content: values[1], + counter: values[2] as u32, + } } } @@ -59,8 +63,12 @@ impl ScopedL2ToL1Message { pub fn expose_to_public(self) -> Self { // Hide the counter when exposing to public. Self { - message: L2ToL1Message { recipient: self.message.recipient, content: self.message.content, counter: 0 }, - contract_address: self.contract_address + message: L2ToL1Message { + recipient: self.message.recipient, + content: self.message.content, + counter: 0, + }, + contract_address: self.contract_address, } } } @@ -88,7 +96,10 @@ impl Eq for ScopedL2ToL1Message { impl Empty for ScopedL2ToL1Message { fn empty() -> Self { - ScopedL2ToL1Message { message: L2ToL1Message::empty(), contract_address: AztecAddress::empty() } + ScopedL2ToL1Message { + message: L2ToL1Message::empty(), + contract_address: AztecAddress::empty(), + } } } @@ -103,7 +114,7 @@ impl Deserialize for ScopedL2ToL1Message { let mut reader = Reader::new(values); let res = Self { message: reader.read_struct(L2ToL1Message::deserialize), - contract_address: reader.read_struct(AztecAddress::deserialize) + contract_address: reader.read_struct(AztecAddress::deserialize), }; reader.finish(); res diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/meta/mod.nr b/noir-projects/noir-protocol-circuits/crates/types/src/meta/mod.nr index fa8e70170da..d56ef6d87ee 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/meta/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/meta/mod.nr @@ -5,12 +5,12 @@ pub comptime fn pack_from_fields( typ: Type, buffer: Quoted, already_consumed: u32, - replacements: [(Quoted, Quoted)] + replacements: [(Quoted, Quoted)], ) -> (Quoted, u32) { let mut result = quote {}; let mut consumed: u32 = 0; - let found_replacements = replacements.filter(| (to_omit, _): (Quoted, Quoted) | to_omit == name); + let found_replacements = replacements.filter(|(to_omit, _): (Quoted, Quoted)| to_omit == name); let replacement = if found_replacements.len() == 1 { replacements[0].1 @@ -33,10 +33,11 @@ pub comptime fn pack_from_fields( field_type, quote { $buffer }, consumed + already_consumed, - replacements + replacements, ); consumed += consumed_by_field; - deserialized_fields_list = deserialized_fields_list.push_back(quote { $field_name: $deserialized_field }); + deserialized_fields_list = + deserialized_fields_list.push_back(quote { $field_name: $deserialized_field }); } let deserialized_fields = deserialized_fields_list.join(quote {,}); result = quote { @@ -54,7 +55,7 @@ pub comptime fn pack_from_fields( element_type, quote { $buffer }, consumed + already_consumed, - replacements + replacements, ); array_fields_list = array_fields_list.push_back(deserialized_field); consumed += consumed_by_field; @@ -71,7 +72,7 @@ pub comptime fn pack_from_fields( quote { u8}.as_type(), quote { $buffer }, consumed + already_consumed, - replacements + replacements, ); byte_list = byte_list.push_back(deserialized_field); consumed += consumed_by_field; @@ -79,7 +80,9 @@ pub comptime fn pack_from_fields( let bytes = byte_list.join(quote {,}); result = quote { [ $bytes ].as_str_unchecked() }; } else { - panic(f"Unsupported type for serialization of argument {name} and type {typ}") + panic( + f"Unsupported type for serialization of argument {name} and type {typ}", + ) } } else { result = replacement; @@ -93,7 +96,7 @@ pub comptime fn flatten_to_fields(name: Quoted, typ: Type, omit: [Quoted]) -> ([ let mut fields = &[]; let mut aux_vars = &[]; - if omit.all(| to_omit | to_omit != name) { + if omit.all(|to_omit| to_omit != name) { if typ.is_field() | typ.as_integer().is_some() | typ.is_bool() { // For field, integer and bool we just cast to Field and add the value to fields fields = fields.push_back(quote { $name as Field }); @@ -101,27 +104,25 @@ pub comptime fn flatten_to_fields(name: Quoted, typ: Type, omit: [Quoted]) -> ([ // For struct we pref let nested_struct = typ.as_struct().unwrap(); let params = nested_struct.0.fields(); - let struct_flattened = params.map( - | (param_name, param_type): (Quoted, Type) | { - let maybe_prefixed_name = if name == quote {} { - // Triggered when the param name is of a value available in the current scope (e.g. a function - // argument) --> then we don't prefix the name with anything. - quote { $param_name } - } else { - // Triggered when we want to prefix the param name with the `name` from function input. This - // can typically be `self` when implementing a method on a struct. - quote { $name.$param_name } - }; - flatten_to_fields(quote {$maybe_prefixed_name}, param_type, omit) - } - ); + let struct_flattened = params.map(|(param_name, param_type): (Quoted, Type)| { + let maybe_prefixed_name = if name == quote {} { + // Triggered when the param name is of a value available in the current scope (e.g. a function + // argument) --> then we don't prefix the name with anything. + quote { $param_name } + } else { + // Triggered when we want to prefix the param name with the `name` from function input. This + // can typically be `self` when implementing a method on a struct. + quote { $name.$param_name } + }; + flatten_to_fields(quote {$maybe_prefixed_name}, param_type, omit) + }); let struct_flattened_fields = struct_flattened.fold( &[], - | acc: [Quoted], (fields, _): (_, [Quoted]) | acc.append(fields) + |acc: [Quoted], (fields, _): (_, [Quoted])| acc.append(fields), ); let struct_flattened_aux_vars = struct_flattened.fold( &[], - |acc: [Quoted], (_, aux_vars): ([Quoted], _) | acc.append(aux_vars) + |acc: [Quoted], (_, aux_vars): ([Quoted], _)| acc.append(aux_vars), ); fields = fields.append(struct_flattened_fields); aux_vars = aux_vars.append(struct_flattened_aux_vars); @@ -130,7 +131,8 @@ pub comptime fn flatten_to_fields(name: Quoted, typ: Type, omit: [Quoted]) -> ([ let (element_type, array_len) = typ.as_array().unwrap(); let array_len = array_len.as_constant().unwrap(); for i in 0..array_len { - let (element_fields, element_aux_vars) = flatten_to_fields(quote { $name[$i] }, element_type, omit); + let (element_fields, element_aux_vars) = + flatten_to_fields(quote { $name[$i] }, element_type, omit); fields = fields.append(element_fields); aux_vars = aux_vars.append(element_aux_vars); } @@ -148,11 +150,13 @@ pub comptime fn flatten_to_fields(name: Quoted, typ: Type, omit: [Quoted]) -> ([ let as_bytes_name = f"{var_name}_as_bytes".quoted_contents(); let as_bytes = quote { let $as_bytes_name = $name.as_bytes() }; for i in 0..str_len { - fields = fields.push_back(quote { $as_bytes_name[$i] as Field } ); + fields = fields.push_back(quote { $as_bytes_name[$i] as Field }); } aux_vars = aux_vars.push_back(as_bytes); } else { - panic(f"Unsupported type for serialization of argument {name} and type {typ}") + panic( + f"Unsupported type for serialization of argument {name} and type {typ}", + ) } } (fields, aux_vars) @@ -203,7 +207,7 @@ pub struct Smol { #[derive(Serialize, Deserialize, Eq)] pub struct HasArray { a: [Field; 2], - b: bool + b: bool, } #[derive(Serialize, Deserialize, Eq)] @@ -238,12 +242,16 @@ fn has_array_test() { #[test] fn fancier_test() { - let fancier = Fancier { a: Smol { a: 1, b: 2 }, b: [0, 1], c: [1, 2, 3], d: "metaprogramming!" }; + let fancier = + Fancier { a: Smol { a: 1, b: 2 }, b: [0, 1], c: [1, 2, 3], d: "metaprogramming!" }; let serialized = fancier.serialize(); assert( - serialized == [ - 1, 2, 0, 1, 1, 2, 3, 0x6d, 0x65, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x21 - ], serialized + serialized + == [ + 1, 2, 0, 1, 1, 2, 3, 0x6d, 0x65, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, + 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x21, + ], + serialized, ); let deserialized = Fancier::deserialize(serialized); assert(deserialized == fancier); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/partial_state_reference.nr b/noir-projects/noir-protocol-circuits/crates/types/src/partial_state_reference.nr index 0390c3d8dc3..0384aa58b94 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/partial_state_reference.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/partial_state_reference.nr @@ -1,6 +1,6 @@ use crate::{ - abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, constants::PARTIAL_STATE_REFERENCE_LENGTH, - traits::{Deserialize, Empty, Serialize} + abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, + constants::PARTIAL_STATE_REFERENCE_LENGTH, traits::{Deserialize, Empty, Serialize}, }; pub struct PartialStateReference { @@ -29,7 +29,7 @@ impl Serialize for PartialStateReference { serialized_nullifier_tree[0], serialized_nullifier_tree[1], serialized_public_data_tree[0], - serialized_public_data_tree[1] + serialized_public_data_tree[1], ] } } @@ -39,7 +39,7 @@ impl Deserialize for PartialStateReference { PartialStateReference { note_hash_tree: AppendOnlyTreeSnapshot::deserialize([serialized[0], serialized[1]]), nullifier_tree: AppendOnlyTreeSnapshot::deserialize([serialized[2], serialized[3]]), - public_data_tree: AppendOnlyTreeSnapshot::deserialize([serialized[4], serialized[5]]) + public_data_tree: AppendOnlyTreeSnapshot::deserialize([serialized[4], serialized[5]]), } } } @@ -49,7 +49,7 @@ impl Empty for PartialStateReference { Self { note_hash_tree: AppendOnlyTreeSnapshot::zero(), nullifier_tree: AppendOnlyTreeSnapshot::zero(), - public_data_tree: AppendOnlyTreeSnapshot::zero() + public_data_tree: AppendOnlyTreeSnapshot::zero(), } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr b/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr index 151f7555dd5..c3097bc56b6 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr @@ -1,7 +1,7 @@ use crate::{ address::public_keys_hash::PublicKeysHash, constants::GENERATOR_INDEX__PUBLIC_KEYS_HASH, hash::poseidon2_hash_with_separator, point::POINT_LENGTH, - traits::{Deserialize, Serialize, Empty, is_empty, Hash} + traits::{Deserialize, Serialize, Empty, is_empty, Hash}, }; use dep::std::embedded_curve_ops::EmbeddedCurvePoint as Point; @@ -20,7 +20,7 @@ pub trait ToPoint { } pub struct NpkM { - inner: Point + inner: Point, } impl ToPoint for NpkM { @@ -43,7 +43,7 @@ impl Hash for NpkM { } pub struct IvpkM { - inner: Point + inner: Point, } impl ToPoint for IvpkM { @@ -59,7 +59,7 @@ impl Serialize for IvpkM { } pub struct OvpkM { - inner: Point + inner: Point, } impl Hash for OvpkM { @@ -81,7 +81,7 @@ impl Serialize for OvpkM { } pub struct TpkM { - inner: Point + inner: Point, } impl ToPoint for TpkM { @@ -102,7 +102,7 @@ impl Empty for PublicKeys { npk_m: NpkM { inner: Point::empty() }, ivpk_m: IvpkM { inner: Point::empty() }, ovpk_m: OvpkM { inner: Point::empty() }, - tpk_m: TpkM { inner: Point::empty() } + tpk_m: TpkM { inner: Point::empty() }, } } } @@ -120,10 +120,13 @@ impl PublicKeys { pub fn hash(self) -> PublicKeysHash { PublicKeysHash::from_field( if is_empty(self) { - 0 - } else { - poseidon2_hash_with_separator(self.serialize(), GENERATOR_INDEX__PUBLIC_KEYS_HASH as Field) - } + 0 + } else { + poseidon2_hash_with_separator( + self.serialize(), + GENERATOR_INDEX__PUBLIC_KEYS_HASH as Field, + ) + }, ) } } @@ -142,7 +145,7 @@ impl Serialize for PublicKeys { self.ovpk_m.inner.is_infinite as Field, self.tpk_m.inner.x, self.tpk_m.inner.y, - self.tpk_m.inner.is_infinite as Field + self.tpk_m.inner.is_infinite as Field, ] } } @@ -150,10 +153,34 @@ impl Serialize for PublicKeys { impl Deserialize for PublicKeys { fn deserialize(serialized: [Field; PUBLIC_KEYS_LENGTH]) -> PublicKeys { PublicKeys { - npk_m: NpkM { inner: Point { x: serialized[0], y: serialized[1], is_infinite: serialized[2] as bool } }, - ivpk_m: IvpkM { inner: Point { x: serialized[3], y: serialized[4], is_infinite: serialized[5] as bool } }, - ovpk_m: OvpkM { inner: Point { x: serialized[6], y: serialized[7], is_infinite: serialized[8] as bool } }, - tpk_m: TpkM { inner: Point { x: serialized[9], y: serialized[10], is_infinite: serialized[11] as bool } } + npk_m: NpkM { + inner: Point { + x: serialized[0], + y: serialized[1], + is_infinite: serialized[2] as bool, + }, + }, + ivpk_m: IvpkM { + inner: Point { + x: serialized[3], + y: serialized[4], + is_infinite: serialized[5] as bool, + }, + }, + ovpk_m: OvpkM { + inner: Point { + x: serialized[6], + y: serialized[7], + is_infinite: serialized[8] as bool, + }, + }, + tpk_m: TpkM { + inner: Point { + x: serialized[9], + y: serialized[10], + is_infinite: serialized[11] as bool, + }, + }, } } } @@ -164,11 +191,12 @@ unconstrained fn compute_public_keys_hash() { npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } } + tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, }; let actual = keys.hash(); - let expected_public_keys_hash = 0x0fecd9a32db731fec1fded1b9ff957a1625c069245a3613a2538bd527068b0ad; + let expected_public_keys_hash = + 0x0fecd9a32db731fec1fded1b9ff957a1625c069245a3613a2538bd527068b0ad; assert(actual.to_field() == expected_public_keys_hash); } @@ -189,7 +217,7 @@ unconstrained fn test_public_keys_serialization() { npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } }, ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } }, ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } }, - tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } } + tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } }, }; let serialized = keys.serialize(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/recursion/proof.nr b/noir-projects/noir-protocol-circuits/crates/types/src/recursion/proof.nr index 6dc97c15c9e..4ebd589b4f0 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/recursion/proof.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/recursion/proof.nr @@ -1,6 +1,6 @@ use crate::{ traits::{Serialize, Deserialize, Empty}, - constants::{RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_PROOF_LENGTH} + constants::{RECURSIVE_PROOF_LENGTH, NESTED_RECURSIVE_PROOF_LENGTH}, }; pub struct RecursiveProof { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/recursion/traits.nr b/noir-projects/noir-protocol-circuits/crates/types/src/recursion/traits.nr index 7d0565e7c5c..f575ea27ad9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/recursion/traits.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/recursion/traits.nr @@ -1,3 +1,3 @@ pub trait Verifiable { - fn verify(self); + fn verify(self); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/recursion/verification_key.nr b/noir-projects/noir-protocol-circuits/crates/types/src/recursion/verification_key.nr index 165b576a6a1..20d958d5dc3 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/recursion/verification_key.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/recursion/verification_key.nr @@ -1,6 +1,8 @@ use crate::{ traits::{Serialize, Deserialize, Empty}, - constants::{HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS, CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS} + constants::{ + HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS, CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, + }, }; pub struct VerificationKey { @@ -26,7 +28,7 @@ impl Serialize for VerificationKey { } impl Deserialize for VerificationKey { - fn deserialize(fields: [Field; N+1]) -> Self { + fn deserialize(fields: [Field; N + 1]) -> Self { let mut key = VerificationKey::empty(); for i in 0..N { key.key[i] = fields[i]; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/state_reference.nr b/noir-projects/noir-protocol-circuits/crates/types/src/state_reference.nr index b8f7322e98f..1bc4110d32f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/state_reference.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/state_reference.nr @@ -2,7 +2,7 @@ use crate::{ abis::append_only_tree_snapshot::{AppendOnlyTreeSnapshot, APPEND_ONLY_TREE_SNAPSHOT_LENGTH}, constants::{PARTIAL_STATE_REFERENCE_LENGTH, STATE_REFERENCE_LENGTH}, partial_state_reference::PartialStateReference, traits::{Deserialize, Empty, Serialize}, - utils::arr_copy_slice + utils::arr_copy_slice, }; pub struct StateReference { @@ -31,21 +31,28 @@ impl Deserialize for StateReference { fn deserialize(serialized: [Field; STATE_REFERENCE_LENGTH]) -> StateReference { let mut offset = 0; - let l1_to_l2_message_tree_fields = arr_copy_slice(serialized, [0; APPEND_ONLY_TREE_SNAPSHOT_LENGTH], offset); + let l1_to_l2_message_tree_fields = + arr_copy_slice(serialized, [0; APPEND_ONLY_TREE_SNAPSHOT_LENGTH], offset); offset = offset + APPEND_ONLY_TREE_SNAPSHOT_LENGTH; - let partial_fields = arr_copy_slice(serialized, [0; PARTIAL_STATE_REFERENCE_LENGTH], offset); + let partial_fields = + arr_copy_slice(serialized, [0; PARTIAL_STATE_REFERENCE_LENGTH], offset); StateReference { - l1_to_l2_message_tree: AppendOnlyTreeSnapshot::deserialize(l1_to_l2_message_tree_fields), - partial: PartialStateReference::deserialize(partial_fields) + l1_to_l2_message_tree: AppendOnlyTreeSnapshot::deserialize( + l1_to_l2_message_tree_fields, + ), + partial: PartialStateReference::deserialize(partial_fields), } } } impl Empty for StateReference { fn empty() -> Self { - Self { l1_to_l2_message_tree: AppendOnlyTreeSnapshot::zero(), partial: PartialStateReference::empty() } + Self { + l1_to_l2_message_tree: AppendOnlyTreeSnapshot::zero(), + partial: PartialStateReference::empty(), + } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr b/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr index 3f20295d9bd..849d8a90252 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/storage/map.nr @@ -1,6 +1,9 @@ use crate::{hash::poseidon2_hash, traits::ToField}; -pub fn derive_storage_slot_in_map(storage_slot: Field, key: K) -> Field where K: ToField { +pub fn derive_storage_slot_in_map(storage_slot: Field, key: K) -> Field +where + K: ToField, +{ poseidon2_hash([storage_slot, key.to_field()]) } @@ -10,12 +13,15 @@ mod test { #[test] fn test_derive_storage_slot_in_map_matches_typescript() { let map_slot = 0x132258fb6962c4387ba659d9556521102d227549a386d39f0b22d1890d59c2b5; - let key = AztecAddress::from_field(0x302dbc2f9b50a73283d5fb2f35bc01eae8935615817a0b4219a057b2ba8a5a3f); + let key = AztecAddress::from_field( + 0x302dbc2f9b50a73283d5fb2f35bc01eae8935615817a0b4219a057b2ba8a5a3f, + ); let slot = derive_storage_slot_in_map(map_slot, key); // The following value was generated by `map_slot.test.ts` - let slot_from_typescript = 0x15b9fe39449affd8b377461263e9d2b610b9ad40580553500b4e41d9cbd887ac; + let slot_from_typescript = + 0x15b9fe39449affd8b377461263e9d2b610b9ad40580553500b4e41d9cbd887ac; assert_eq(slot, slot_from_typescript); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr index 70047797421..f1cab7bfdca 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -1,70 +1,67 @@ use crate::{ abis::{ - gas::Gas, gas_settings::GasSettings, call_context::CallContext, - accumulated_data::{ - CombinedAccumulatedData, PrivateAccumulatedData, PrivateAccumulatedDataBuilder, - PublicAccumulatedData, PublicAccumulatedDataArrayLengths, PublicAccumulatedDataBuilder -}, - function_data::FunctionData, function_selector::FunctionSelector, global_variables::GlobalVariables, - combined_constant_data::CombinedConstantData, enqueued_call_data::{EnqueuedCallData, Proof}, - kernel_circuit_public_inputs::{ - KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, - VMCircuitPublicInputs -}, - kernel_data::KernelData, public_kernel_data::PublicKernelData, max_block_number::MaxBlockNumber, - private_kernel_data::PrivateKernelData, note_hash::{NoteHash, ScopedNoteHash}, - nullifier::{Nullifier, ScopedNullifier}, private_call_request::PrivateCallRequest, - private_circuit_public_inputs::PrivateCircuitPublicInputs, - private_kernel::private_call_data::PrivateCallData, - public_call_data::{Proof as PublicCallDataProof, PublicCallData}, - public_call_request::PublicCallRequest, public_circuit_public_inputs::PublicCircuitPublicInputs, - public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, - public_inner_call_request::PublicInnerCallRequest, read_request::{ReadRequest, ScopedReadRequest}, - tree_leaf_read_request::TreeLeafReadRequest, - log_hash::{LogHash, NoteLogHash, ScopedLogHash, EncryptedLogHash, ScopedEncryptedLogHash}, - validation_requests::{ - KeyValidationRequest, KeyValidationRequestAndGenerator, PrivateValidationRequests, - PublicValidationRequests, PublicValidationRequestArrayLengths, RollupValidationRequests, - ScopedKeyValidationRequestAndGenerator -} -}, - address::{AztecAddress, EthAddress, SaltedInitializationHash, PublicKeysHash}, + gas::Gas, gas_settings::GasSettings, call_context::CallContext, + accumulated_data::{ + CombinedAccumulatedData, PrivateAccumulatedData, PrivateAccumulatedDataBuilder, + PublicAccumulatedData, PublicAccumulatedDataArrayLengths, PublicAccumulatedDataBuilder, + }, function_data::FunctionData, function_selector::FunctionSelector, + global_variables::GlobalVariables, combined_constant_data::CombinedConstantData, + enqueued_call_data::{EnqueuedCallData, Proof}, + kernel_circuit_public_inputs::{ + KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, + PublicKernelCircuitPublicInputs, VMCircuitPublicInputs, + }, kernel_data::KernelData, public_kernel_data::PublicKernelData, + max_block_number::MaxBlockNumber, private_kernel_data::PrivateKernelData, + note_hash::{NoteHash, ScopedNoteHash}, nullifier::{Nullifier, ScopedNullifier}, + private_call_request::PrivateCallRequest, + private_circuit_public_inputs::PrivateCircuitPublicInputs, + private_kernel::private_call_data::PrivateCallData, + public_call_data::{Proof as PublicCallDataProof, PublicCallData}, + public_call_request::PublicCallRequest, + public_circuit_public_inputs::PublicCircuitPublicInputs, public_data_read::PublicDataRead, + public_data_update_request::PublicDataUpdateRequest, + public_inner_call_request::PublicInnerCallRequest, + read_request::{ReadRequest, ScopedReadRequest}, tree_leaf_read_request::TreeLeafReadRequest, + log_hash::{LogHash, NoteLogHash, ScopedLogHash, EncryptedLogHash, ScopedEncryptedLogHash}, + validation_requests::{ + KeyValidationRequest, KeyValidationRequestAndGenerator, PrivateValidationRequests, + PublicValidationRequests, PublicValidationRequestArrayLengths, RollupValidationRequests, + ScopedKeyValidationRequestAndGenerator, + }, + }, address::{AztecAddress, EthAddress, SaltedInitializationHash, PublicKeysHash}, public_keys::PublicKeys, constants::{ - FUNCTION_TREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, - MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_READS_PER_CALL, - MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_FIELD_VALUE, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, - MAX_KEY_VALIDATION_REQUESTS_PER_TX, VK_TREE_HEIGHT, MAX_ENCRYPTED_LOGS_PER_TX, - MAX_UNENCRYPTED_LOGS_PER_TX, MAX_NOTE_ENCRYPTED_LOGS_PER_TX, PRIVATE_CALL_REQUEST_LENGTH, - PROTOCOL_CONTRACT_TREE_HEIGHT, PUBLIC_CALL_REQUEST_LENGTH -}, - contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, + FUNCTION_TREE_HEIGHT, MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, + MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_TX, MAX_L2_TO_L1_MSGS_PER_TX, + MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_READS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_FIELD_VALUE, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, + MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, MAX_KEY_VALIDATION_REQUESTS_PER_TX, + VK_TREE_HEIGHT, MAX_ENCRYPTED_LOGS_PER_TX, MAX_UNENCRYPTED_LOGS_PER_TX, + MAX_NOTE_ENCRYPTED_LOGS_PER_TX, PRIVATE_CALL_REQUEST_LENGTH, PROTOCOL_CONTRACT_TREE_HEIGHT, + PUBLIC_CALL_REQUEST_LENGTH, + }, contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest}, hash::{ - compute_l2_to_l1_hash, compute_tx_logs_hash, compute_siloed_nullifier, silo_note_hash, - silo_unencrypted_log_hash, mask_encrypted_log_hash -}, - header::Header, merkle_tree::{membership::MembershipWitness, MerkleTree}, + compute_l2_to_l1_hash, compute_tx_logs_hash, compute_siloed_nullifier, silo_note_hash, + silo_unencrypted_log_hash, mask_encrypted_log_hash, + }, header::Header, merkle_tree::{membership::MembershipWitness, MerkleTree}, messaging::l2_to_l1_message::{L2ToL1Message, ScopedL2ToL1Message}, partial_state_reference::PartialStateReference, tests::{ - fixtures, - fixtures::{ - contracts::ContractData, contract_functions::ContractFunction, - vk_tree::{ - generate_fake_honk_vk_for_index, generate_fake_client_ivc_vk_for_index, get_vk_merkle_tree, - VK_TREE_WIDTH -} -} -}, - transaction::{tx_context::TxContext, tx_request::TxRequest}, traits::Empty, + fixtures, + fixtures::{ + contracts::ContractData, contract_functions::ContractFunction, + vk_tree::{ + generate_fake_honk_vk_for_index, generate_fake_client_ivc_vk_for_index, + get_vk_merkle_tree, VK_TREE_WIDTH, + }, + }, + }, transaction::{tx_context::TxContext, tx_request::TxRequest}, traits::Empty, recursion::{ - verification_key::{HonkVerificationKey, ClientIVCVerificationKey, VerificationKey}, - proof::NestedRecursiveProof -}, - point::Point + verification_key::{HonkVerificationKey, ClientIVCVerificationKey, VerificationKey}, + proof::NestedRecursiveProof, + }, point::Point, }; fn subarray(arr: [T; N]) -> [T; M] { @@ -187,7 +184,11 @@ impl FixtureBuilder { pub fn new_from_counter(counter_start: u32) -> Self { let mut builder = FixtureBuilder::empty(); - builder.tx_context = TxContext { chain_id: fixtures::CHAIN_ID, version: fixtures::VERSION, gas_settings: GasSettings::empty() }; + builder.tx_context = TxContext { + chain_id: fixtures::CHAIN_ID, + version: fixtures::VERSION, + gas_settings: GasSettings::empty(), + }; builder.msg_sender = fixtures::contracts::parent_contract.address; builder.counter_start = counter_start; builder.counter = counter_start + 1; @@ -206,11 +207,10 @@ impl FixtureBuilder { pub fn in_vk_tree(&mut self, vk_index: u32) -> Self { self.vk_index = vk_index; - let vk_tree: MerkleTree = comptime { - fixtures::vk_tree::get_vk_merkle_tree() - }; + let vk_tree: MerkleTree = + comptime { fixtures::vk_tree::get_vk_merkle_tree() }; - self.honk_vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(vk_index) ; + self.honk_vk = fixtures::vk_tree::generate_fake_honk_vk_for_index(vk_index); self.client_ivc_vk = fixtures::vk_tree::generate_fake_client_ivc_vk_for_index(vk_index); self.vk_path = vk_tree.get_sibling_path(vk_index); @@ -233,7 +233,8 @@ impl FixtureBuilder { self.protocol_contract_sibling_path = tree.get_sibling_path(contract_index); let contract_data = fixtures::contracts::get_protocol_contract(contract_index); - let function_data = fixtures::contract_functions::get_protocol_contract_function(contract_index); + let function_data = + fixtures::contract_functions::get_protocol_contract_function(contract_index); let _ = self.use_contract(contract_data); self.contract_address = AztecAddress::from_field(contract_index as Field); @@ -281,7 +282,7 @@ impl FixtureBuilder { tx_context: self.tx_context, vk_tree_root: self.vk_tree_root, protocol_contract_tree_root: self.protocol_contract_tree_root, - global_variables: self.global_variables + global_variables: self.global_variables, } } @@ -290,7 +291,7 @@ impl FixtureBuilder { origin: self.contract_address, args_hash: self.args_hash, tx_context: self.tx_context, - function_data: self.function_data + function_data: self.function_data, } } @@ -299,7 +300,7 @@ impl FixtureBuilder { msg_sender: self.msg_sender, contract_address: self.contract_address, function_selector: self.function_data.selector, - is_static_call: self.is_static_call + is_static_call: self.is_static_call, } } @@ -309,7 +310,7 @@ impl FixtureBuilder { args_hash: self.args_hash, returns_hash: self.returns_hash, start_side_effect_counter: self.counter_start, - end_side_effect_counter: self.counter + end_side_effect_counter: self.counter, } } @@ -321,24 +322,39 @@ impl FixtureBuilder { min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, is_fee_payer: self.is_fee_payer, max_block_number: self.max_block_number, - note_hash_read_requests: subarray(self.note_hash_read_requests.storage.map(|r: ScopedReadRequest| r.read_request)), - nullifier_read_requests: subarray(self.nullifier_read_requests.storage.map(|r: ScopedReadRequest| r.read_request)), - key_validation_requests_and_generators: subarray( - self.scoped_key_validation_requests_and_generators.storage.map(|r: ScopedKeyValidationRequestAndGenerator| r.request) + note_hash_read_requests: subarray(self.note_hash_read_requests.storage.map( + |r: ScopedReadRequest| r.read_request, + )), + nullifier_read_requests: subarray(self.nullifier_read_requests.storage.map( + |r: ScopedReadRequest| r.read_request, + )), + key_validation_requests_and_generators: subarray(self + .scoped_key_validation_requests_and_generators + .storage + .map(|r: ScopedKeyValidationRequestAndGenerator| r.request)), + note_hashes: subarray( + self.note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash), + ), + nullifiers: subarray( + self.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier), ), - note_hashes: subarray(self.note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash)), - nullifiers: subarray(self.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier)), private_call_requests: subarray(self.private_call_requests.storage), public_call_requests: subarray(self.public_call_requests.storage), public_teardown_call_request: self.public_teardown_call_request, - l2_to_l1_msgs: subarray(self.l2_to_l1_msgs.storage.map(|r: ScopedL2ToL1Message| r.message)), + l2_to_l1_msgs: subarray(self.l2_to_l1_msgs.storage.map(|r: ScopedL2ToL1Message| { + r.message + })), start_side_effect_counter: self.counter_start, end_side_effect_counter: self.counter, note_encrypted_logs_hashes: subarray(self.note_encrypted_logs_hashes.storage), - encrypted_logs_hashes: subarray(self.encrypted_logs_hashes.storage.map(|l: ScopedEncryptedLogHash| l.log_hash)), - unencrypted_logs_hashes: subarray(self.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| l.log_hash)), + encrypted_logs_hashes: subarray(self.encrypted_logs_hashes.storage.map( + |l: ScopedEncryptedLogHash| l.log_hash, + )), + unencrypted_logs_hashes: subarray(self.unencrypted_logs_hashes.storage.map( + |l: ScopedLogHash| l.log_hash, + )), historical_header: self.historical_header, - tx_context: self.tx_context + tx_context: self.tx_context, } } @@ -350,9 +366,10 @@ impl FixtureBuilder { salted_initialization_hash: self.salted_initialization_hash, public_keys: self.public_keys, contract_class_artifact_hash: self.contract_class_artifact_hash, - contract_class_public_bytecode_commitment: self.contract_class_public_bytecode_commitment, + contract_class_public_bytecode_commitment: self + .contract_class_public_bytecode_commitment, protocol_contract_sibling_path: self.protocol_contract_sibling_path, - acir_hash: self.acir_hash + acir_hash: self.acir_hash, } } @@ -365,7 +382,7 @@ impl FixtureBuilder { encrypted_logs_hashes: self.encrypted_logs_hashes, unencrypted_logs_hashes: self.unencrypted_logs_hashes, public_call_requests: self.public_call_requests, - private_call_stack: vec_reverse(self.private_call_requests) + private_call_stack: vec_reverse(self.private_call_requests), } } @@ -374,20 +391,36 @@ impl FixtureBuilder { } pub fn to_public_call_request(self) -> PublicCallRequest { - PublicCallRequest { call_context: self.build_call_context(), args_hash: self.args_hash, counter: 0 } + PublicCallRequest { + call_context: self.build_call_context(), + args_hash: self.args_hash, + counter: 0, + } } pub fn to_public_accumulated_data_builder(self) -> PublicAccumulatedDataBuilder { - let nullifiers = BoundedVec { storage: self.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier), len: self.nullifiers.len() }; + let nullifiers = BoundedVec { + storage: self.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier), + len: self.nullifiers.len(), + }; let note_encrypted_logs_hashes = BoundedVec { - storage: self.note_encrypted_logs_hashes.storage.map(|l: NoteLogHash| LogHash { value: l.value, counter: l.counter, length: l.length }), - len: self.note_encrypted_logs_hashes.len() + storage: self.note_encrypted_logs_hashes.storage.map(|l: NoteLogHash| { + LogHash { value: l.value, counter: l.counter, length: l.length } + }), + len: self.note_encrypted_logs_hashes.len(), }; let encrypted_logs_hashes = BoundedVec { - storage: self.encrypted_logs_hashes.storage.map( - |l: ScopedEncryptedLogHash| ScopedLogHash { log_hash: LogHash { value: l.log_hash.value, counter: l.log_hash.counter, length: l.log_hash.length}, contract_address: l.contract_address } - ), - len: self.encrypted_logs_hashes.len() + storage: self.encrypted_logs_hashes.storage.map(|l: ScopedEncryptedLogHash| { + ScopedLogHash { + log_hash: LogHash { + value: l.log_hash.value, + counter: l.log_hash.counter, + length: l.log_hash.length, + }, + contract_address: l.contract_address, + } + }), + len: self.encrypted_logs_hashes.len(), }; PublicAccumulatedDataBuilder { @@ -399,7 +432,7 @@ impl FixtureBuilder { unencrypted_logs_hashes: self.unencrypted_logs_hashes, public_data_update_requests: self.public_data_update_requests, public_call_stack: self.public_call_requests, - gas_used: self.gas_used + gas_used: self.gas_used, } } @@ -411,13 +444,23 @@ impl FixtureBuilder { PublicAccumulatedData { note_hashes: self.note_hashes.storage.map(|n: ScopedNoteHash| n.expose_to_public()), nullifiers: self.nullifiers.storage.map(|n: ScopedNullifier| n.expose_to_public()), - l2_to_l1_msgs: self.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| m.expose_to_public()), - note_encrypted_logs_hashes: self.note_encrypted_logs_hashes.storage.map(|l: NoteLogHash| l.expose_to_public()), - encrypted_logs_hashes: self.encrypted_logs_hashes.storage.map(|l: ScopedEncryptedLogHash| l.expose_to_public()), - unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| l.expose_to_public()), + l2_to_l1_msgs: self.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| { + m.expose_to_public() + }), + note_encrypted_logs_hashes: self.note_encrypted_logs_hashes.storage.map( + |l: NoteLogHash| l.expose_to_public(), + ), + encrypted_logs_hashes: self.encrypted_logs_hashes.storage.map( + |l: ScopedEncryptedLogHash| l.expose_to_public(), + ), + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| { + l.expose_to_public() + }), public_data_update_requests: self.public_data_update_requests.storage, - public_call_stack: self.public_call_requests.storage.map(|cr: PublicCallRequest| cr.expose_to_public()), - gas_used: self.gas_used + public_call_stack: self.public_call_requests.storage.map(|cr: PublicCallRequest| { + cr.expose_to_public() + }), + gas_used: self.gas_used, } } @@ -425,15 +468,23 @@ impl FixtureBuilder { CombinedAccumulatedData { note_hashes: self.note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash.value), nullifiers: self.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier.value), - l2_to_l1_msgs: self.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| m.expose_to_public()), - note_encrypted_logs_hashes: self.note_encrypted_logs_hashes.storage.map(|l: NoteLogHash| l.expose_to_public()), - encrypted_logs_hashes: self.encrypted_logs_hashes.storage.map(|l: ScopedEncryptedLogHash| l.expose_to_public()), - unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| l.expose_to_public()), + l2_to_l1_msgs: self.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| { + m.expose_to_public() + }), + note_encrypted_logs_hashes: self.note_encrypted_logs_hashes.storage.map( + |l: NoteLogHash| l.expose_to_public(), + ), + encrypted_logs_hashes: self.encrypted_logs_hashes.storage.map( + |l: ScopedEncryptedLogHash| l.expose_to_public(), + ), + unencrypted_logs_hashes: self.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| { + l.expose_to_public() + }), note_encrypted_log_preimages_length: self.note_encrypted_log_preimages_length, encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, public_data_update_requests: self.public_data_update_requests.storage, - gas_used: self.gas_used + gas_used: self.gas_used, } } @@ -442,8 +493,10 @@ impl FixtureBuilder { for_rollup: self.to_rollup_validation_requests(), note_hash_read_requests: self.note_hash_read_requests.storage, nullifier_read_requests: self.nullifier_read_requests.storage, - scoped_key_validation_requests_and_generators: self.scoped_key_validation_requests_and_generators.storage, - split_counter: self.validation_requests_split_counter + scoped_key_validation_requests_and_generators: self + .scoped_key_validation_requests_and_generators + .storage, + split_counter: self.validation_requests_split_counter, } } @@ -459,13 +512,18 @@ impl FixtureBuilder { validation_requests, constants, public_teardown_call_request, - fee_payer: self.fee_payer + fee_payer: self.fee_payer, } } pub fn to_private_kernel_data(self) -> PrivateKernelData { let public_inputs = self.to_private_kernel_circuit_public_inputs(); - PrivateKernelData { public_inputs, vk: self.client_ivc_vk, vk_index: self.vk_index, vk_path: self.vk_path } + PrivateKernelData { + public_inputs, + vk: self.client_ivc_vk, + vk_index: self.vk_index, + vk_path: self.vk_path, + } } pub fn to_public_circuit_public_inputs(self) -> PublicCircuitPublicInputs { @@ -474,27 +532,40 @@ impl FixtureBuilder { args_hash: self.args_hash, returns_hash: self.returns_hash, note_hash_read_requests: subarray(self.note_hash_tree_leaf_read_requests.storage), - nullifier_read_requests: subarray(self.nullifier_read_requests.storage.map(|r: ScopedReadRequest| r.read_request)), - nullifier_non_existent_read_requests: subarray( - self.nullifier_non_existent_read_requests.storage.map(|r: ScopedReadRequest| r.read_request) - ), + nullifier_read_requests: subarray(self.nullifier_read_requests.storage.map( + |r: ScopedReadRequest| r.read_request, + )), + nullifier_non_existent_read_requests: subarray(self + .nullifier_non_existent_read_requests + .storage + .map(|r: ScopedReadRequest| r.read_request)), l1_to_l2_msg_read_requests: subarray(self.l1_to_l2_msg_read_requests.storage), - contract_storage_update_requests: subarray(self.contract_storage_update_requests.storage), + contract_storage_update_requests: subarray( + self.contract_storage_update_requests.storage, + ), contract_storage_reads: self.contract_storage_reads.storage, public_call_requests: subarray(self.public_inner_call_requests.storage), - note_hashes: subarray(self.note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash)), - nullifiers: subarray(self.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier)), - l2_to_l1_msgs: subarray(self.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| m.message)), + note_hashes: subarray( + self.note_hashes.storage.map(|n: ScopedNoteHash| n.note_hash), + ), + nullifiers: subarray( + self.nullifiers.storage.map(|n: ScopedNullifier| n.nullifier), + ), + l2_to_l1_msgs: subarray(self.l2_to_l1_msgs.storage.map(|m: ScopedL2ToL1Message| { + m.message + })), start_side_effect_counter: self.counter_start, end_side_effect_counter: self.counter, - unencrypted_logs_hashes: subarray(self.unencrypted_logs_hashes.storage.map(|l: ScopedLogHash| l.log_hash)), + unencrypted_logs_hashes: subarray(self.unencrypted_logs_hashes.storage.map( + |l: ScopedLogHash| l.log_hash, + )), historical_header: self.historical_header, global_variables: self.global_variables, prover_address: self.prover_address, revert_code: self.revert_code, start_gas_left: self.start_gas_left, end_gas_left: self.end_gas_left, - transaction_fee: self.transaction_fee + transaction_fee: self.transaction_fee, } } @@ -502,7 +573,7 @@ impl FixtureBuilder { PublicCallData { public_inputs: self.to_public_circuit_public_inputs(), proof: PublicCallDataProof {}, - bytecode_hash: self.bytecode_hash + bytecode_hash: self.bytecode_hash, } } @@ -513,7 +584,7 @@ impl FixtureBuilder { nullifier_read_requests: self.nullifier_read_requests.storage, nullifier_non_existent_read_requests: self.nullifier_non_existent_read_requests.storage, public_data_reads: self.public_data_reads.storage, - l1_to_l2_msg_read_requests: self.l1_to_l2_msg_read_requests.storage + l1_to_l2_msg_read_requests: self.l1_to_l2_msg_read_requests.storage, } } @@ -530,7 +601,7 @@ impl FixtureBuilder { end_side_effect_counter: self.counter, start_gas_left: self.start_gas_left, transaction_fee: self.transaction_fee, - reverted: self.revert_code != 0 + reverted: self.revert_code != 0, } } @@ -538,7 +609,10 @@ impl FixtureBuilder { EnqueuedCallData { data: self.to_vm_circuit_public_inputs(), proof: Proof {} } } - pub fn to_public_kernel_circuit_public_inputs(self, revertible: bool) -> PublicKernelCircuitPublicInputs { + pub fn to_public_kernel_circuit_public_inputs( + self, + revertible: bool, + ) -> PublicKernelCircuitPublicInputs { // TODO: Split the data using self.min_revertible_side_effect_counter. let accumulated_data = self.to_public_accumulated_data(); let end_non_revertible = if revertible { @@ -560,13 +634,19 @@ impl FixtureBuilder { end_side_effect_counter: self.counter, public_teardown_call_request: self.public_teardown_call_request, fee_payer: self.fee_payer, - revert_code: self.revert_code + revert_code: self.revert_code, } } pub fn to_public_kernel_data(self, revertible: bool) -> PublicKernelData { let public_inputs = self.to_public_kernel_circuit_public_inputs(revertible); - PublicKernelData { public_inputs, proof: self.proof, vk: self.honk_vk, vk_index: self.vk_index, vk_path: self.vk_path } + PublicKernelData { + public_inputs, + proof: self.proof, + vk: self.honk_vk, + vk_index: self.vk_index, + vk_path: self.vk_path, + } } pub fn to_rollup_validation_requests(self) -> RollupValidationRequests { @@ -584,7 +664,7 @@ impl FixtureBuilder { constants, start_state: self.start_state, revert_code: self.revert_code, - fee_payer: self.fee_payer + fee_payer: self.fee_payer, } } @@ -595,12 +675,14 @@ impl FixtureBuilder { proof: NestedRecursiveProof::empty(), vk: self.honk_vk, vk_index: self.vk_index, - vk_path: self.vk_path + vk_path: self.vk_path, } } pub fn add_new_note_hash(&mut self, value: Field) { - self.note_hashes.push(NoteHash { value, counter: self.next_counter() }.scope(self.contract_address)); + self.note_hashes.push(NoteHash { value, counter: self.next_counter() }.scope( + self.contract_address, + )); } pub fn add_siloed_note_hash(&mut self, value: Field) { @@ -609,7 +691,9 @@ impl FixtureBuilder { let index = self.note_hashes.len(); let note_hash_to_silo = NoteHash { value, counter: 0 }.scope(self.contract_address); let siloed_value = silo_note_hash(note_hash_to_silo, tx_hash, index); - self.note_hashes.push(NoteHash { value: siloed_value, counter: self.next_counter() }.scope(AztecAddress::zero())); + self.note_hashes.push(NoteHash { value: siloed_value, counter: self.next_counter() }.scope( + AztecAddress::zero(), + )); } pub fn append_note_hashes(&mut self, num_note_hashes: u32) { @@ -647,7 +731,8 @@ impl FixtureBuilder { pub fn set_first_nullifier(&mut self) { assert_eq(self.nullifiers.len(), 0, "first nullifier already set"); let value = self.mock_nullifier_value(0); - let first_nullifier = Nullifier { value, counter: 0, note_hash: 0 }.scope(AztecAddress::zero()); + let first_nullifier = + Nullifier { value, counter: 0, note_hash: 0 }.scope(AztecAddress::zero()); self.nullifiers.push(first_nullifier); } @@ -657,7 +742,9 @@ impl FixtureBuilder { } pub fn add_nullifier_for_note_hash(&mut self, value: Field, note_hash: Field) { - self.nullifiers.push(Nullifier { value, counter: self.next_counter(), note_hash }.scope(self.contract_address)); + self.nullifiers.push(Nullifier { value, counter: self.next_counter(), note_hash }.scope( + self.contract_address, + )); } pub fn add_siloed_nullifier(&mut self, value: Field) { @@ -667,9 +754,12 @@ impl FixtureBuilder { pub fn add_siloed_nullifier_for_note_hash(&mut self, value: Field, note_hash: Field) { let siloed_value = compute_siloed_nullifier(self.contract_address, value); - self.nullifiers.push( - Nullifier { value: siloed_value, counter: self.next_counter(), note_hash }.scope(AztecAddress::zero()) - ); + self.nullifiers.push(Nullifier { + value: siloed_value, + counter: self.next_counter(), + note_hash, + } + .scope(AztecAddress::zero())); } pub fn append_nullifiers(&mut self, num_extra_nullifier: u32) { @@ -693,13 +783,14 @@ impl FixtureBuilder { } pub fn add_l2_to_l1_message(&mut self, content: Field, recipient: EthAddress) { - self.l2_to_l1_msgs.push( - L2ToL1Message { recipient, content, counter: self.next_counter() }.scope(self.contract_address) - ); + self.l2_to_l1_msgs.push(L2ToL1Message { recipient, content, counter: self.next_counter() } + .scope(self.contract_address)); } pub fn add_exposed_l2_to_l1_message(&mut self, content: Field, recipient: EthAddress) { - self.l2_to_l1_msgs.push(L2ToL1Message { recipient, content, counter: 0 }.scope(self.contract_address)); + self.l2_to_l1_msgs.push(L2ToL1Message { recipient, content, counter: 0 }.scope( + self.contract_address, + )); } pub fn add_siloed_l2_to_l1_message(&mut self, content: Field, recipient: EthAddress) { @@ -708,7 +799,7 @@ impl FixtureBuilder { recipient, content, self.tx_context.version, - self.tx_context.chain_id + self.tx_context.chain_id, ); self.add_l2_to_l1_message(siloed_content, recipient); } @@ -734,7 +825,9 @@ impl FixtureBuilder { } pub fn add_contract_storage_read_request(&mut self, storage_slot: Field, value: Field) { - self.contract_storage_reads.push(StorageRead { storage_slot, current_value: value, counter: self.next_counter() }); + self.contract_storage_reads.push( + StorageRead { storage_slot, current_value: value, counter: self.next_counter() }, + ); } pub fn append_contract_storage_read_requests(&mut self, num: u32) { @@ -748,7 +841,8 @@ impl FixtureBuilder { } pub fn add_contract_storage_update_request(&mut self, storage_slot: Field, value: Field) { - let update_request = StorageUpdateRequest { storage_slot, new_value: value, counter: self.next_counter() }; + let update_request = + StorageUpdateRequest { storage_slot, new_value: value, counter: self.next_counter() }; self.contract_storage_update_requests.push(update_request); } @@ -763,7 +857,8 @@ impl FixtureBuilder { } pub fn add_public_data_update_request(&mut self, leaf_slot: Field, value: Field) { - let update_request = PublicDataUpdateRequest { leaf_slot, new_value: value, counter: self.next_counter() }; + let update_request = + PublicDataUpdateRequest { leaf_slot, new_value: value, counter: self.next_counter() }; self.public_data_update_requests.push(update_request); } @@ -778,7 +873,9 @@ impl FixtureBuilder { } pub fn add_public_data_read_request(&mut self, leaf_slot: Field, value: Field) { - self.public_data_reads.push(PublicDataRead { leaf_slot, value, counter: self.next_counter() }); + self.public_data_reads.push( + PublicDataRead { leaf_slot, value, counter: self.next_counter() }, + ); } pub fn append_public_data_read_requests(&mut self, num_reads: u32) { @@ -794,7 +891,8 @@ impl FixtureBuilder { pub fn add_read_request_for_pending_note_hash(&mut self, note_hash_index: u32) -> u32 { let read_request_index = self.note_hash_read_requests.len(); let value = self.mock_note_hash_value(note_hash_index); - let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.contract_address); + let read_request = + ReadRequest { value, counter: self.next_counter() }.scope(self.contract_address); self.note_hash_read_requests.push(read_request); read_request_index } @@ -804,7 +902,9 @@ impl FixtureBuilder { for i in 0..self.note_hash_read_requests.max_len() { if i < num_reads { let value = self.mock_note_hash_read_value(index_offset + i); - let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.contract_address); + let read_request = ReadRequest { value, counter: self.next_counter() }.scope( + self.contract_address, + ); self.note_hash_read_requests.push(read_request); } } @@ -828,13 +928,17 @@ impl FixtureBuilder { pub fn add_read_request_for_pending_nullifier(&mut self, nullifier_index: u32) -> u32 { let read_request_index = self.nullifier_read_requests.len(); let nullifier = self.mock_nullifier_value(nullifier_index); - let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope(self.contract_address); + let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope( + self.contract_address, + ); self.nullifier_read_requests.push(read_request); read_request_index } pub fn add_non_existent_read_request_for_nullifier(&mut self, nullifier: Field) { - let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope(self.contract_address); + let read_request = ReadRequest { value: nullifier, counter: self.next_counter() }.scope( + self.contract_address, + ); self.nullifier_non_existent_read_requests.push(read_request); } @@ -843,7 +947,9 @@ impl FixtureBuilder { for i in 0..self.nullifier_read_requests.max_len() { if i < num_reads { let value = self.mock_nullifier_read_value(index_offset + i); - let read_request = ReadRequest { value, counter: self.next_counter() }.scope(self.contract_address); + let read_request = ReadRequest { value, counter: self.next_counter() }.scope( + self.contract_address, + ); self.nullifier_read_requests.push(read_request); } } @@ -859,12 +965,20 @@ impl FixtureBuilder { } } - pub fn add_request_for_key_validation(&mut self, pk_m: Point, sk_app: Field, sk_app_generator: Field) -> u32 { + pub fn add_request_for_key_validation( + &mut self, + pk_m: Point, + sk_app: Field, + sk_app_generator: Field, + ) -> u32 { let new_request_index = self.scoped_key_validation_requests_and_generators.len(); let request = KeyValidationRequest { pk_m, sk_app }; let request_and_generator = KeyValidationRequestAndGenerator { request, sk_app_generator }; - let scoped_key_validation_request_and_generator = request_and_generator.scope(self.contract_address); - self.scoped_key_validation_requests_and_generators.push(scoped_key_validation_request_and_generator); + let scoped_key_validation_request_and_generator = + request_and_generator.scope(self.contract_address); + self.scoped_key_validation_requests_and_generators.push( + scoped_key_validation_request_and_generator, + ); new_request_index } @@ -874,13 +988,21 @@ impl FixtureBuilder { for i in 0..self.scoped_key_validation_requests_and_generators.max_len() { if i < num_requests { let request = self.mock_key_validation_request(index_offset + i); - self.scoped_key_validation_requests_and_generators.push(request.scope(self.contract_address)); + self.scoped_key_validation_requests_and_generators.push(request.scope( + self.contract_address, + )); } } } - pub fn add_note_encrypted_log_hash(&mut self, value: Field, length: Field, note_hash_counter: u32) { - let log_hash = NoteLogHash { value, counter: self.next_counter(), length, note_hash_counter }; + pub fn add_note_encrypted_log_hash( + &mut self, + value: Field, + length: Field, + note_hash_counter: u32, + ) { + let log_hash = + NoteLogHash { value, counter: self.next_counter(), length, note_hash_counter }; self.note_encrypted_logs_hashes.push(log_hash); self.encrypted_log_preimages_length += length; } @@ -896,13 +1018,20 @@ impl FixtureBuilder { } pub fn add_encrypted_log_hash(&mut self, hash: Field, length: Field) { - let log_hash = EncryptedLogHash { value: hash, counter: self.next_counter(), length, randomness: 2 }; + let log_hash = + EncryptedLogHash { value: hash, counter: self.next_counter(), length, randomness: 2 }; self.encrypted_logs_hashes.push(log_hash.scope(self.contract_address)); self.encrypted_log_preimages_length += length; } pub fn add_masked_encrypted_log_hash(&mut self, hash: Field, length: Field) { - let mut log_hash = EncryptedLogHash { value: hash, counter: self.next_counter(), length, randomness: 2 }.scope(self.contract_address); + let mut log_hash = EncryptedLogHash { + value: hash, + counter: self.next_counter(), + length, + randomness: 2, + } + .scope(self.contract_address); log_hash.contract_address = mask_encrypted_log_hash(log_hash); log_hash.log_hash.randomness = 0; self.encrypted_logs_hashes.push(log_hash); @@ -921,7 +1050,8 @@ impl FixtureBuilder { pub fn mask_encrypted_log_hashes(&mut self) { for i in 0..self.encrypted_logs_hashes.max_len() { - self.encrypted_logs_hashes.storage[i].contract_address = mask_encrypted_log_hash(self.encrypted_logs_hashes.storage[i]); + self.encrypted_logs_hashes.storage[i].contract_address = + mask_encrypted_log_hash(self.encrypted_logs_hashes.storage[i]); } } @@ -970,12 +1100,12 @@ impl FixtureBuilder { self.private_call_requests.push( PrivateCallRequest { - call_context: public_inputs.call_context, - args_hash: public_inputs.args_hash, - returns_hash: public_inputs.returns_hash, - start_side_effect_counter: start_counter, - end_side_effect_counter: end_counter - } + call_context: public_inputs.call_context, + args_hash: public_inputs.args_hash, + returns_hash: public_inputs.returns_hash, + start_side_effect_counter: start_counter, + end_side_effect_counter: end_counter, + }, ); } @@ -1049,7 +1179,10 @@ impl FixtureBuilder { fn mock_key_validation_request(self, index: u32) -> KeyValidationRequestAndGenerator { let value_offset = 3030 + self.value_offset + index as Field; - let request = KeyValidationRequest { pk_m: Point { x: value_offset, y: 1 + value_offset, is_infinite: false }, sk_app: 2 + value_offset }; + let request = KeyValidationRequest { + pk_m: Point { x: value_offset, y: 1 + value_offset, is_infinite: false }, + sk_app: 2 + value_offset, + }; KeyValidationRequestAndGenerator { request, sk_app_generator: 3 + value_offset } } @@ -1220,7 +1353,7 @@ impl Empty for FixtureBuilder { start_gas_left: Gas::empty(), end_gas_left: Gas::empty(), transaction_fee: 0, - value_offset: 0 + value_offset: 0, } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr index 9da3851f4f5..3ec6eed50a9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contract_functions.nr @@ -11,10 +11,7 @@ pub struct ContractFunction { // sibling_path taken from __snapshots__/noir_test_gen.test.ts.snap global default_private_function = ContractFunction { - data: FunctionData { - selector: FunctionSelector { inner: 1010101 }, - is_private: true, - }, + data: FunctionData { selector: FunctionSelector { inner: 1010101 }, is_private: true }, vk_hash: 0, acir_hash: 1111, membership_witness: MembershipWitness { @@ -30,10 +27,7 @@ global default_private_function = ContractFunction { }; global default_public_function = ContractFunction { - data: FunctionData { - selector: FunctionSelector { inner: 3030303 }, - is_private: false, - }, + data: FunctionData { selector: FunctionSelector { inner: 3030303 }, is_private: false }, vk_hash: 0, acir_hash: 3333, membership_witness: MembershipWitness { @@ -50,7 +44,10 @@ global default_public_function = ContractFunction { pub fn get_protocol_contract_function(contract_index: u32) -> ContractFunction { ContractFunction { - data: FunctionData { selector: FunctionSelector { inner: 98989 + contract_index }, is_private: true }, + data: FunctionData { + selector: FunctionSelector { inner: 98989 + contract_index }, + is_private: true, + }, vk_hash: 0, acir_hash: 5555 + contract_index as Field, membership_witness: MembershipWitness { @@ -60,8 +57,8 @@ pub fn get_protocol_contract_function(contract_index: u32) -> ContractFunction { 0x062d9223c973936f12eacf94db1cfb9499e5aee67c864677e238402006c20d21, 0x26d4cb8f72c0330bbebdb587bf896ce790ec7d091ee6aa3aabcf9bd60b2de307, 0x1d8f5034624cbef3663cf6a73a04bf82d34379e7e65f2b7d29fce4d6987ca7c1, - 0x1758942724d8e39e5a0bc52b58cd80e5b6f26bedcc2a00d4b2f0dc6019fb1bf1 - ] - } + 0x1758942724d8e39e5a0bc52b58cd80e5b6f26bedcc2a00d4b2f0dc6019fb1bf1, + ], + }, } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contracts.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contracts.nr index ea84c6c5ec0..4bf18e15d19 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contracts.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/contracts.nr @@ -1,7 +1,7 @@ use crate::{ address::{AztecAddress, PublicKeysHash, SaltedInitializationHash, PartialAddress}, contract_class_id::ContractClassId, hash::private_functions_root_from_siblings, - tests::fixtures::contract_functions::get_protocol_contract_function, public_keys::PublicKeys + tests::fixtures::contract_functions::get_protocol_contract_function, public_keys::PublicKeys, }; pub struct ContractData { @@ -19,30 +19,50 @@ pub struct ContractData { // taken from __snapshots__/noir_test_gen.test.ts.snap global default_contract = ContractData { - contract_address_salt: 0x000000000000000000000000000000000000000000000000000000000000ddd5, - artifact_hash: 0x0000000000000000000000000000000000000000000000000000000000003039, - public_bytecode_commitment: 0x0000000000000000000000000000000000000000000000000000000000000005, - private_functions_root: 0x25d76df45434ec75a83321daf941cfc667ff3a9027942e17105da4f50d1d13f9, - address: AztecAddress { inner: 0x0e66d7cd9692428c550b93c9ef5f49ca9f02c03e98cb3c922d8c773f78f79fed }, - partial_address: PartialAddress { inner: 0x0cf203c94c91bed28440b00ecd888d88cce1f86ddf2aa8d33acbb9b6fc06d382 }, - contract_class_id: ContractClassId { inner: 0x28e91aaf764bc6083e2796ff884079ad895d4b948d6ce8f37f01b29d0bc95a21 }, - public_keys: PublicKeys::empty(), - salted_initialization_hash: SaltedInitializationHash { inner: 0x13a939daa511233e5446905ed2cadbee14948fa75df183b53b5c14b612bffe88 }, - deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 } + contract_address_salt: 0x000000000000000000000000000000000000000000000000000000000000ddd5, + artifact_hash: 0x0000000000000000000000000000000000000000000000000000000000003039, + public_bytecode_commitment: 0x0000000000000000000000000000000000000000000000000000000000000005, + private_functions_root: 0x25d76df45434ec75a83321daf941cfc667ff3a9027942e17105da4f50d1d13f9, + address: AztecAddress { + inner: 0x0e66d7cd9692428c550b93c9ef5f49ca9f02c03e98cb3c922d8c773f78f79fed, + }, + partial_address: PartialAddress { + inner: 0x0cf203c94c91bed28440b00ecd888d88cce1f86ddf2aa8d33acbb9b6fc06d382, + }, + contract_class_id: ContractClassId { + inner: 0x28e91aaf764bc6083e2796ff884079ad895d4b948d6ce8f37f01b29d0bc95a21, + }, + public_keys: PublicKeys::empty(), + salted_initialization_hash: SaltedInitializationHash { + inner: 0x13a939daa511233e5446905ed2cadbee14948fa75df183b53b5c14b612bffe88, + }, + deployer: AztecAddress { + inner: 0x0000000000000000000000000000000000000000000000000000000000000000, + }, }; // taken from __snapshots__/noir_test_gen.test.ts.snap global parent_contract = ContractData { - contract_address_salt: 0x0000000000000000000000000000000000000000000000000000000000001618, - artifact_hash: 0x00000000000000000000000000000000000000000000000000000000000004bc, - public_bytecode_commitment: 0x0000000000000000000000000000000000000000000000000000000000000005, - private_functions_root: 0x1228b39ba6702af03e595300e8484c6373f00790d0148cc3d4ff0fd1c778a83a, - address: AztecAddress { inner: 0x24415b2e716d6c7099580ab8e383fd5b16dc9fb441aa308571d8e24a2257da24 }, - partial_address: PartialAddress { inner: 0x245df9f519d616473880260dd64b19a838081bb44dc17cd6ea5d870a63d2bf57 }, - contract_class_id: ContractClassId { inner: 0x00236b0dc6c537d5106543053c5b85c4cbe95b0474f8238b094bae63f1cbcfee }, - public_keys: PublicKeys::empty(), - salted_initialization_hash: SaltedInitializationHash { inner: 0x24bd6ac7a182e2cf25e437c72f53544ef81dfd97d9afee23abb07a638e7be749 }, - deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 } + contract_address_salt: 0x0000000000000000000000000000000000000000000000000000000000001618, + artifact_hash: 0x00000000000000000000000000000000000000000000000000000000000004bc, + public_bytecode_commitment: 0x0000000000000000000000000000000000000000000000000000000000000005, + private_functions_root: 0x1228b39ba6702af03e595300e8484c6373f00790d0148cc3d4ff0fd1c778a83a, + address: AztecAddress { + inner: 0x24415b2e716d6c7099580ab8e383fd5b16dc9fb441aa308571d8e24a2257da24, + }, + partial_address: PartialAddress { + inner: 0x245df9f519d616473880260dd64b19a838081bb44dc17cd6ea5d870a63d2bf57, + }, + contract_class_id: ContractClassId { + inner: 0x00236b0dc6c537d5106543053c5b85c4cbe95b0474f8238b094bae63f1cbcfee, + }, + public_keys: PublicKeys::empty(), + salted_initialization_hash: SaltedInitializationHash { + inner: 0x24bd6ac7a182e2cf25e437c72f53544ef81dfd97d9afee23abb07a638e7be749, + }, + deployer: AztecAddress { + inner: 0x0000000000000000000000000000000000000000000000000000000000000000, + }, }; pub fn get_protocol_contract(index: u32) -> ContractData { @@ -57,16 +77,19 @@ pub fn get_protocol_contract(index: u32) -> ContractData { function.data.selector, function.vk_hash, function.membership_witness.leaf_index, - function.membership_witness.sibling_path + function.membership_witness.sibling_path, ); let contract_class_id = ContractClassId::compute( artifact_hash, private_functions_root, - public_bytecode_commitment + public_bytecode_commitment, ); - let partial_address = PartialAddress::compute_from_salted_initialization_hash(contract_class_id, salted_initialization_hash); + let partial_address = PartialAddress::compute_from_salted_initialization_hash( + contract_class_id, + salted_initialization_hash, + ); let address = AztecAddress::compute(public_keys.hash(), partial_address); @@ -80,6 +103,6 @@ pub fn get_protocol_contract(index: u32) -> ContractData { contract_class_id, public_keys, salted_initialization_hash, - deployer: AztecAddress { inner: 0 } + deployer: AztecAddress { inner: 0 }, } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/protocol_contract_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/protocol_contract_tree.nr index 8dd35497597..2a35812fb5f 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/protocol_contract_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/protocol_contract_tree.nr @@ -1,6 +1,6 @@ use crate::{ constants::PROTOCOL_CONTRACT_TREE_HEIGHT, merkle_tree::merkle_tree::MerkleTree, - tests::fixtures::contracts::get_protocol_contract + tests::fixtures::contracts::get_protocol_contract, }; global PROTOCOL_CONTRACT_TREE_WIDTH: u32 = 1 << PROTOCOL_CONTRACT_TREE_HEIGHT as u8; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/vk_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/vk_tree.nr index 83de6523bd8..e3a9a8b6d62 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/vk_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixtures/vk_tree.nr @@ -1,11 +1,11 @@ use crate::constants::{ - VK_TREE_HEIGHT, PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, PRIVATE_KERNEL_RESET_INDEX, - PRIVATE_KERNEL_TAIL_INDEX, PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX, EMPTY_NESTED_INDEX, - PRIVATE_KERNEL_EMPTY_INDEX, PUBLIC_KERNEL_INNER_INDEX, PUBLIC_KERNEL_MERGE_INDEX, - PUBLIC_KERNEL_TAIL_INDEX, BASE_PARITY_INDEX, ROOT_PARITY_INDEX, BASE_ROLLUP_INDEX, - MERGE_ROLLUP_INDEX, BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX, ROOT_ROLLUP_INDEX, - BLOCK_ROOT_ROLLUP_EMPTY_INDEX, HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS, - CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS + VK_TREE_HEIGHT, PRIVATE_KERNEL_INIT_INDEX, PRIVATE_KERNEL_INNER_INDEX, + PRIVATE_KERNEL_RESET_INDEX, PRIVATE_KERNEL_TAIL_INDEX, PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX, + EMPTY_NESTED_INDEX, PRIVATE_KERNEL_EMPTY_INDEX, PUBLIC_KERNEL_INNER_INDEX, + PUBLIC_KERNEL_MERGE_INDEX, PUBLIC_KERNEL_TAIL_INDEX, BASE_PARITY_INDEX, ROOT_PARITY_INDEX, + BASE_ROLLUP_INDEX, MERGE_ROLLUP_INDEX, BLOCK_ROOT_ROLLUP_INDEX, BLOCK_MERGE_ROLLUP_INDEX, + ROOT_ROLLUP_INDEX, BLOCK_ROOT_ROLLUP_EMPTY_INDEX, HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS, + CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, }; use crate::merkle_tree::merkle_tree::MerkleTree; use crate::recursion::verification_key::VerificationKey; @@ -19,12 +19,16 @@ fn generate_fake_vk_for_index(index: u32) -> [Field; N] { vk } -pub fn generate_fake_honk_vk_for_index(index: u32) -> VerificationKey { +pub fn generate_fake_honk_vk_for_index( + index: u32, +) -> VerificationKey { let key = generate_fake_vk_for_index(index); VerificationKey { key, hash: verification_key_hash(key) } } -pub fn generate_fake_client_ivc_vk_for_index(index: u32) -> VerificationKey { +pub fn generate_fake_client_ivc_vk_for_index( + index: u32, +) -> VerificationKey { let key = generate_fake_vk_for_index(index); VerificationKey { key, hash: verification_key_hash(key) } } @@ -33,25 +37,36 @@ pub fn get_vk_merkle_tree() -> MerkleTree { let mut leaves = [0; VK_TREE_WIDTH]; // Fake VK hashes for testing purposes - leaves[PRIVATE_KERNEL_INIT_INDEX] = generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_INIT_INDEX).hash; - leaves[PRIVATE_KERNEL_INNER_INDEX] = generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_INNER_INDEX).hash; - leaves[PRIVATE_KERNEL_TAIL_INDEX] = generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_TAIL_INDEX).hash; - leaves[PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX] = generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX).hash; - leaves[PRIVATE_KERNEL_RESET_INDEX] = generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_RESET_INDEX).hash; + leaves[PRIVATE_KERNEL_INIT_INDEX] = + generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_INIT_INDEX).hash; + leaves[PRIVATE_KERNEL_INNER_INDEX] = + generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_INNER_INDEX).hash; + leaves[PRIVATE_KERNEL_TAIL_INDEX] = + generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_TAIL_INDEX).hash; + leaves[PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX] = + generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_TAIL_TO_PUBLIC_INDEX).hash; + leaves[PRIVATE_KERNEL_RESET_INDEX] = + generate_fake_client_ivc_vk_for_index(PRIVATE_KERNEL_RESET_INDEX).hash; leaves[EMPTY_NESTED_INDEX] = generate_fake_honk_vk_for_index(EMPTY_NESTED_INDEX).hash; - leaves[PRIVATE_KERNEL_EMPTY_INDEX] = generate_fake_honk_vk_for_index(PRIVATE_KERNEL_EMPTY_INDEX).hash; - leaves[PUBLIC_KERNEL_INNER_INDEX] = generate_fake_honk_vk_for_index(PUBLIC_KERNEL_INNER_INDEX).hash; - leaves[PUBLIC_KERNEL_MERGE_INDEX] = generate_fake_honk_vk_for_index(PUBLIC_KERNEL_MERGE_INDEX).hash; - leaves[PUBLIC_KERNEL_TAIL_INDEX] = generate_fake_honk_vk_for_index(PUBLIC_KERNEL_TAIL_INDEX).hash; + leaves[PRIVATE_KERNEL_EMPTY_INDEX] = + generate_fake_honk_vk_for_index(PRIVATE_KERNEL_EMPTY_INDEX).hash; + leaves[PUBLIC_KERNEL_INNER_INDEX] = + generate_fake_honk_vk_for_index(PUBLIC_KERNEL_INNER_INDEX).hash; + leaves[PUBLIC_KERNEL_MERGE_INDEX] = + generate_fake_honk_vk_for_index(PUBLIC_KERNEL_MERGE_INDEX).hash; + leaves[PUBLIC_KERNEL_TAIL_INDEX] = + generate_fake_honk_vk_for_index(PUBLIC_KERNEL_TAIL_INDEX).hash; leaves[BASE_PARITY_INDEX] = generate_fake_honk_vk_for_index(BASE_PARITY_INDEX).hash; leaves[ROOT_PARITY_INDEX] = generate_fake_honk_vk_for_index(ROOT_PARITY_INDEX).hash; leaves[BASE_ROLLUP_INDEX] = generate_fake_honk_vk_for_index(BASE_ROLLUP_INDEX).hash; leaves[MERGE_ROLLUP_INDEX] = generate_fake_honk_vk_for_index(MERGE_ROLLUP_INDEX).hash; leaves[BLOCK_ROOT_ROLLUP_INDEX] = generate_fake_honk_vk_for_index(BLOCK_ROOT_ROLLUP_INDEX).hash; - leaves[BLOCK_MERGE_ROLLUP_INDEX] = generate_fake_honk_vk_for_index(BLOCK_MERGE_ROLLUP_INDEX).hash; + leaves[BLOCK_MERGE_ROLLUP_INDEX] = + generate_fake_honk_vk_for_index(BLOCK_MERGE_ROLLUP_INDEX).hash; leaves[ROOT_ROLLUP_INDEX] = generate_fake_honk_vk_for_index(ROOT_ROLLUP_INDEX).hash; - leaves[BLOCK_ROOT_ROLLUP_EMPTY_INDEX] = generate_fake_honk_vk_for_index(BLOCK_ROOT_ROLLUP_EMPTY_INDEX).hash; + leaves[BLOCK_ROOT_ROLLUP_EMPTY_INDEX] = + generate_fake_honk_vk_for_index(BLOCK_ROOT_ROLLUP_EMPTY_INDEX).hash; MerkleTree::new(leaves) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/merkle_tree_utils.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/merkle_tree_utils.nr index 842b28247b2..e7cfbd7566d 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/merkle_tree_utils.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/merkle_tree_utils.nr @@ -1,10 +1,13 @@ -use crate::{merkle_tree::{merkle_tree, MerkleTree, calculate_empty_tree_root}, traits::Empty, hash::merkle_hash}; +use crate::{ + merkle_tree::{merkle_tree, MerkleTree, calculate_empty_tree_root}, traits::Empty, + hash::merkle_hash, +}; pub fn compute_zero_hashes(mut hashes: [Field; N]) -> [Field; N] { - hashes[0] = merkle_hash(0, 0); + hashes[0] = merkle_hash(0, 0); for i in 1..N { - hashes[i] = merkle_hash(hashes[i-1], hashes[i-1]); + hashes[i] = merkle_hash(hashes[i - 1], hashes[i - 1]); } hashes @@ -25,7 +28,7 @@ impl MerkleTree { let mut layer_offset: u32 = 0; let mut node_index: u32 = index / 2 + layer_offset; for _ in 0..K { - self.nodes[node_index] = merkle_hash(left_node, right_node); + self.nodes[node_index] = merkle_hash(left_node, right_node); sibling_index = merkle_tree::sibling_index(node_index); let nodes = if node_index % 2 == 0 { (self.nodes[node_index], self.nodes[sibling_index]) @@ -78,7 +81,7 @@ impl Self { // Hack to get around us converting a u32 to a u8. // TODO: improve this. (SUBTREE_HEIGHT as Field).assert_max_bit_size::<8>(); assert_eq( - TREE_HEIGHT, SUPERTREE_HEIGHT + SUBTREE_HEIGHT, "tree height must be the sum of supertree and subtree height" + TREE_HEIGHT, + SUPERTREE_HEIGHT + SUBTREE_HEIGHT, + "tree height must be the sum of supertree and subtree height", ); assert_eq( - U128::from_integer(SUBTREE_ITEMS), U128::from_integer(1 << SUBTREE_HEIGHT as u8), "subtree items must be 2^subtree height" + U128::from_integer(SUBTREE_ITEMS), + U128::from_integer(1 << SUBTREE_HEIGHT as u8), + "subtree items must be 2^subtree height", ); let subtree = MerkleTree::new(non_zero_leaves); let zero_hashes = compute_zero_hashes(_tree_height); let mut left_supertree_branch = [0; SUPERTREE_HEIGHT]; - left_supertree_branch[0] = merkle_hash(subtree.get_root(), zero_hashes[SUBTREE_HEIGHT-1]); + left_supertree_branch[0] = merkle_hash(subtree.get_root(), zero_hashes[SUBTREE_HEIGHT - 1]); for i in 1..left_supertree_branch.len() { // TODO(md): far right of this yuck - left_supertree_branch[i] = merkle_hash(left_supertree_branch[i-1], zero_hashes[(SUBTREE_HEIGHT as u8) -1 + (i as u8)]); + left_supertree_branch[i] = merkle_hash( + left_supertree_branch[i - 1], + zero_hashes[(SUBTREE_HEIGHT as u8) - 1 + (i as u8)], + ); } - NonEmptyMerkleTree { subtree, zero_hashes, left_supertree_branch, _phantom_subtree_height: _subtree_height } + NonEmptyMerkleTree { + subtree, + zero_hashes, + left_supertree_branch, + _phantom_subtree_height: _subtree_height, + } } pub fn get_sibling_path(self, leaf_index: u32) -> [Field; TREE_HEIGHT] { @@ -138,9 +153,9 @@ impl(array: [T; N], expected: [T; S]) where T: Empty + Eq { +pub fn assert_array_eq(array: [T; N], expected: [T; S]) +where + T: Empty + Eq, +{ assert(expected.all(|elem: T| !is_empty(elem)), "cannot expect empty element in the result"); assert_eq(validate_array(array), S, "mismatch array lengths"); for i in 0..S { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr b/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr index 60a3c6031b3..614388f5259 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/traits.nr @@ -48,11 +48,17 @@ impl Empty for U128 { } } -pub fn is_empty(item: T) -> bool where T: Empty + Eq { +pub fn is_empty(item: T) -> bool +where + T: Empty + Eq, +{ item.eq(T::empty()) } -pub fn is_empty_array(array: [T; N]) -> bool where T: Empty + Eq { +pub fn is_empty_array(array: [T; N]) -> bool +where + T: Empty + Eq, +{ array.all(|elem| is_empty(elem)) } @@ -173,7 +179,7 @@ pub trait Deserialize { } // docs:end:deserialize -impl Deserialize for str { +impl Deserialize for str { fn deserialize(fields: [Field; N]) -> Self { str::from(fields.map(|value| value as u8)) } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_context.nr b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_context.nr index 0393c23652d..f7cf4faef7a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_context.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_context.nr @@ -1,12 +1,12 @@ use crate::{ constants::TX_CONTEXT_LENGTH, traits::{Deserialize, Serialize, Empty}, utils::reader::Reader, - abis::gas_settings::GasSettings + abis::gas_settings::GasSettings, }; // docs:start:tx-context pub struct TxContext { - chain_id : Field, - version : Field, + chain_id: Field, + version: Field, gas_settings: GasSettings, } // docs:end:tx-context @@ -53,7 +53,7 @@ impl Deserialize for TxContext { let context = Self { chain_id: reader.read(), version: reader.read(), - gas_settings: reader.read_struct(GasSettings::deserialize) + gas_settings: reader.read_struct(GasSettings::deserialize), }; reader.finish(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr index 8bc221c8d3c..fb367b28111 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/transaction/tx_request.nr @@ -1,8 +1,8 @@ use crate::{ address::AztecAddress, abis::function_data::FunctionData, - constants::{GENERATOR_INDEX__TX_REQUEST, TX_REQUEST_LENGTH}, hash::poseidon2_hash_with_separator, - traits::{Hash, Serialize, Deserialize, Empty}, transaction::tx_context::TxContext, - utils::reader::Reader + constants::{GENERATOR_INDEX__TX_REQUEST, TX_REQUEST_LENGTH}, + hash::poseidon2_hash_with_separator, traits::{Hash, Serialize, Deserialize, Empty}, + transaction::tx_context::TxContext, utils::reader::Reader, }; pub struct TxRequest { @@ -18,7 +18,7 @@ impl Empty for TxRequest { origin: AztecAddress::empty(), args_hash: 0, tx_context: TxContext::empty(), - function_data: FunctionData::empty() + function_data: FunctionData::empty(), } } } @@ -62,7 +62,7 @@ impl Deserialize for TxRequest { origin: reader.read_struct(AztecAddress::deserialize), args_hash: reader.read(), tx_context: reader.read_struct(TxContext::deserialize), - function_data: reader.read_struct(FunctionData::deserialize) + function_data: reader.read_struct(FunctionData::deserialize), }; reader.finish(); @@ -73,10 +73,9 @@ impl Deserialize for TxRequest { mod tests { use crate::{ abis::{ - function_selector::FunctionSelector, function_data::FunctionData, gas_settings::GasSettings, - gas::Gas, gas_fees::GasFees - }, - address::AztecAddress, transaction::{tx_request::TxRequest, tx_context::TxContext} + function_selector::FunctionSelector, function_data::FunctionData, + gas_settings::GasSettings, gas::Gas, gas_fees::GasFees, + }, address::AztecAddress, transaction::{tx_request::TxRequest, tx_context::TxContext}, }; #[test] @@ -94,10 +93,14 @@ mod tests { origin: AztecAddress::from_field(1), args_hash: 3, tx_context: TxContext { chain_id: 0, version: 0, gas_settings }, - function_data: FunctionData { selector: FunctionSelector::from_u32(2), is_private: true } + function_data: FunctionData { + selector: FunctionSelector::from_u32(2), + is_private: true, + }, }; // Value from tx_request.test.ts "compute hash" test - let test_data_tx_request_hash = 0x289d3f85f463f3449e2204433b860574d351e9fbd97a01a722239fdd9ce3ce9b; + let test_data_tx_request_hash = + 0x289d3f85f463f3449e2204433b860574d351e9fbd97a01a722239fdd9ce3ce9b; assert(tx_request.hash() == test_data_tx_request_hash); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr index 59d9fad5628..829da563338 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/type_serialization.nr @@ -79,7 +79,10 @@ impl Deserialize for Field { } } -impl Serialize for [T; N] where T: Serialize { +impl Serialize for [T; N] +where + T: Serialize, +{ fn serialize(self) -> [Field; N * M] { let mut result: [Field; N * M] = std::mem::zeroed(); let mut serialized: [Field; M] = std::mem::zeroed(); @@ -93,7 +96,10 @@ impl Serialize for [T; N] where T: Serialize< } } -impl Deserialize for [T; N] where T: Deserialize { +impl Deserialize for [T; N] +where + T: Deserialize, +{ fn deserialize(fields: [Field; N * M]) -> Self { let mut reader = crate::utils::reader::Reader::new(fields); let mut result: [T; N] = std::mem::zeroed(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr index f8ee3ffd248..52456a02286 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr @@ -15,32 +15,42 @@ mod sort_by; mod sort_by_counter; // Re-exports. -pub use assert_array_appended::{assert_array_appended, assert_array_appended_reversed, assert_array_appended_scoped}; +pub use assert_array_appended::{ + assert_array_appended, assert_array_appended_reversed, assert_array_appended_scoped, +}; pub use assert_array_prepended::assert_array_prepended; pub use assert_combined_array::{assert_combined_array, combine_arrays}; pub use assert_combined_sorted_transformed_value_array::{ assert_combined_sorted_transformed_value_array_asc, - get_combined_order_hints::{CombinedOrderHint, get_combined_order_hints_asc} + get_combined_order_hints::{CombinedOrderHint, get_combined_order_hints_asc}, +}; +pub use assert_combined_transformed_array::{ + assert_combined_transformed_array, combine_and_transform_arrays, }; -pub use assert_combined_transformed_array::{assert_combined_transformed_array, combine_and_transform_arrays}; pub use assert_exposed_sorted_transformed_value_array::{ assert_exposed_sorted_transformed_value_array, - get_order_hints::{get_order_hints_asc, get_order_hints_desc, OrderHint} + get_order_hints::{get_order_hints_asc, get_order_hints_desc, OrderHint}, }; pub use assert_deduped_array::{assert_deduped_array, dedupe_array}; pub use assert_sorted_array::assert_sorted_array; pub use assert_split_sorted_transformed_value_arrays::{ - assert_split_sorted_transformed_value_arrays_asc, assert_split_sorted_transformed_value_arrays_desc, - get_split_order_hints::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints} + assert_split_sorted_transformed_value_arrays_asc, + assert_split_sorted_transformed_value_arrays_desc, + get_split_order_hints::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints}, +}; +pub use assert_sorted_transformed_value_array::{ + assert_sorted_transformed_value_array, assert_sorted_transformed_value_array_capped_size, }; -pub use assert_sorted_transformed_value_array::{assert_sorted_transformed_value_array, assert_sorted_transformed_value_array_capped_size}; pub use assert_split_transformed_value_arrays::assert_split_transformed_value_arrays; pub use get_sorted_result::{get_sorted_result, SortedResult}; pub use sort_by_counter::{sort_by_counter_asc, sort_by_counter_desc}; use crate::traits::{Empty, is_empty}; -pub fn array_to_bounded_vec(array: [T; N]) -> BoundedVec where T: Empty + Eq { +pub fn array_to_bounded_vec(array: [T; N]) -> BoundedVec +where + T: Empty + Eq, +{ let mut len = 0; for elem in array { if !is_empty(elem) { @@ -51,7 +61,10 @@ pub fn array_to_bounded_vec(array: [T; N]) -> BoundedVec wh BoundedVec { storage: array, len } } -pub unconstrained fn find_index_hint(array: [T; N], find: fn[Env](T) -> bool) -> u32 { +pub unconstrained fn find_index_hint( + array: [T; N], + find: fn[Env](T) -> bool, +) -> u32 { let mut index = N; for i in 0..N { if (index == N) & find(array[i]) { @@ -64,7 +77,10 @@ pub unconstrained fn find_index_hint(array: [T; N], find: fn // Routine which validates that all zero values of an array form a contiguous region at the end, i.e., // of the form: [*,*,*...,0,0,0,0] where any * is non-zero. Note that a full array of non-zero values is // valid. -pub fn validate_array(array: [T; N]) -> u32 where T: Empty + Eq { +pub fn validate_array(array: [T; N]) -> u32 +where + T: Empty + Eq, +{ let mut seen_empty = false; let mut length = 0; for i in 0..N { @@ -80,10 +96,11 @@ pub fn validate_array(array: [T; N]) -> u32 where T: Empty + Eq { // Helper function to count the number of non-empty elements in a validated array. // Important: Only use it for validated arrays: validate_array(array) should be true. -pub fn array_length(array: [T; N]) -> u32 where T: Empty + Eq { - let length = unsafe { - find_index_hint(array, |elem: T| is_empty(elem)) - }; +pub fn array_length(array: [T; N]) -> u32 +where + T: Empty + Eq, +{ + let length = unsafe { find_index_hint(array, |elem: T| is_empty(elem)) }; if length != 0 { assert(!is_empty(array[length - 1])); } @@ -104,7 +121,10 @@ pub fn array_concat(array1: [T; N], array2: [T; M]) - result } -pub fn array_merge(array1: [T; N], array2: [T; N]) -> [T; N] where T: Empty + Eq { +pub fn array_merge(array1: [T; N], array2: [T; N]) -> [T; N] +where + T: Empty + Eq, +{ let mut result: [T; N] = [T::empty(); N]; let mut i = 0; for elem in array1 { @@ -125,8 +145,11 @@ pub fn array_merge(array1: [T; N], array2: [T; N]) -> [T; N] wher pub fn check_permutation( original_array: [T; N], permuted_array: [T; N], - original_indexes: [u32; N] -) where T: Eq + Empty { + original_indexes: [u32; N], +) +where + T: Eq + Empty, +{ let mut seen_value = [false; N]; for i in 0..N { let index = original_indexes[i]; @@ -203,9 +226,7 @@ fn test_array_length_invalid_arrays() { fn find_index_greater_than_min() { let values = [10, 20, 30, 40]; let min = 22; - let index = unsafe { - find_index_hint(values, |v: Field| min.lt(v)) - }; + let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) }; assert_eq(index, 2); } @@ -213,9 +234,7 @@ fn find_index_greater_than_min() { fn find_index_not_found() { let values = [10, 20, 30, 40]; let min = 100; - let index = unsafe { - find_index_hint(values, |v: Field| min.lt(v)) - }; + let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) }; assert_eq(index, 4); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_appended.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_appended.nr index ab433566d37..1377ada4486 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_appended.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_appended.nr @@ -1,21 +1,31 @@ -use crate::{abis::side_effect::Scoped, address::aztec_address::AztecAddress, traits::{Empty, is_empty}}; +use crate::{ + abis::side_effect::Scoped, address::aztec_address::AztecAddress, traits::{Empty, is_empty}, +}; pub fn assert_array_appended( dest: [T; N], source: [T; M], num_source_items: u32, - num_prepended_items: u32 -) where T: Empty + Eq { + num_prepended_items: u32, +) +where + T: Empty + Eq, +{ let items_propagated = num_prepended_items + num_source_items; assert(items_propagated <= N, "number of total items exceeds limit"); let mut should_check = false; let mut is_non_empty_item = true; - for i in 0..dest.len() { // Loop through dest instead of source because we also need to check that dest is appended with empty items. + for i in 0..dest.len() { + // Loop through dest instead of source because we also need to check that dest is appended with empty items. should_check |= i == num_prepended_items; // Prepended items have been checked in validate_array_prepended() and can be skipped here. is_non_empty_item &= i != items_propagated; if should_check { if is_non_empty_item { - assert_eq(dest[i], source[i - num_prepended_items], "source item does not append to dest"); + assert_eq( + dest[i], + source[i - num_prepended_items], + "source item does not append to dest", + ); } else { assert(is_empty(dest[i]), "output should be appended with empty items"); } @@ -28,8 +38,11 @@ pub fn assert_array_appended_reversed( dest: [T; N], source: [T; M], num_source_items: u32, - num_prepended_items: u32 -) where T: Empty + Eq { + num_prepended_items: u32, +) +where + T: Empty + Eq, +{ let items_propagated = num_prepended_items + num_source_items; assert(items_propagated <= N, "number of total items exceeds limit"); let mut should_check = false; @@ -40,7 +53,9 @@ pub fn assert_array_appended_reversed( if should_check { if is_non_empty_item { assert_eq( - dest[i], source[items_propagated - i - 1], "source item does not reversed append to dest" + dest[i], + source[items_propagated - i - 1], + "source item does not reversed append to dest", ); } else { assert(is_empty(dest[i]), "output should be appended with empty items"); @@ -55,8 +70,12 @@ pub fn assert_array_appended_scoped( source: [T; M], num_source_items: u32, num_prepended_items: u32, - contract_address: AztecAddress -) where ST: Scoped + Empty + Eq, T: Eq { + contract_address: AztecAddress, +) +where + ST: Scoped + Empty + Eq, + T: Eq, +{ let items_propagated = num_prepended_items + num_source_items; assert(items_propagated <= N, "number of total items exceeds limit"); let mut should_check = false; @@ -67,10 +86,14 @@ pub fn assert_array_appended_scoped( if should_check { if is_non_empty_item { assert_eq( - dest[i].inner(), source[i - num_prepended_items], "source item does not append to dest" + dest[i].inner(), + source[i - num_prepended_items], + "source item does not append to dest", ); assert_eq( - dest[i].contract_address(), contract_address, "propagated contract address does not match" + dest[i].contract_address(), + contract_address, + "propagated contract address does not match", ); } else { assert(is_empty(dest[i]), "output should be appended with empty items"); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_prepended.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_prepended.nr index 57323410bea..c1b12e9ee59 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_prepended.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_array_prepended.nr @@ -1,8 +1,7 @@ -pub fn assert_array_prepended( - dest: [T; N], - source: [T; N], - num_source_items: u32 -) where T: Eq { +pub fn assert_array_prepended(dest: [T; N], source: [T; N], num_source_items: u32) +where + T: Eq, +{ let mut proceed = true; for i in 0..source.len() { proceed &= i != num_source_items; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr index 99889e586bd..f2ad12fd38e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr @@ -1,6 +1,8 @@ use crate::{ traits::Empty, - utils::arrays::assert_combined_transformed_array::{assert_combined_transformed_array, combine_and_transform_arrays} + utils::arrays::assert_combined_transformed_array::{ + assert_combined_transformed_array, combine_and_transform_arrays, + }, }; // original_array(_lt/_gte) must be valid, i.e. validate_array(original_array) == true @@ -8,27 +10,33 @@ use crate::{ pub fn assert_combined_array( original_array_lt: [T; N], original_array_gte: [T; N], - combined_array: [T; N] -) where T: Empty + Eq { + combined_array: [T; N], +) +where + T: Empty + Eq, +{ assert_combined_transformed_array( original_array_lt, original_array_gte, combined_array, - |from: T, to: T| from == to + |from: T, to: T| from == to, ) } pub unconstrained fn combine_arrays( original_array_lt: [T; N], - original_array_gte: [T; N] -) -> [T; N] where T: Empty + Eq { + original_array_gte: [T; N], +) -> [T; N] +where + T: Empty + Eq, +{ combine_and_transform_arrays(original_array_lt, original_array_gte, |from: T| from) } mod tests { use crate::{ tests::{types::TestValue, utils::pad_end}, - utils::arrays::assert_combined_array::{assert_combined_array, combine_arrays} + utils::arrays::assert_combined_array::{assert_combined_array, combine_arrays}, }; struct TestBuilder { @@ -48,30 +56,27 @@ mod tests { pub fn new() -> Self { let original_array_lt = pad_end( [ - TestValue { value: 11, counter: 2 }, - TestValue { value: 22, counter: 5 }, - TestValue { value: 33, counter: 3 } - ], - TestValue::empty() + TestValue { value: 11, counter: 2 }, + TestValue { value: 22, counter: 5 }, + TestValue { value: 33, counter: 3 }, + ], + TestValue::empty(), ); let original_array_gte = pad_end( - [ - TestValue { value: 44, counter: 1 }, - TestValue { value: 55, counter: 4 } - ], - TestValue::empty() + [TestValue { value: 44, counter: 1 }, TestValue { value: 55, counter: 4 }], + TestValue::empty(), ); let combined_array = pad_end( [ - TestValue { value: 11, counter: 2 }, - TestValue { value: 22, counter: 5 }, - TestValue { value: 33, counter: 3 }, - TestValue { value: 44, counter: 1 }, - TestValue { value: 55, counter: 4 } - ], - TestValue::empty() + TestValue { value: 11, counter: 2 }, + TestValue { value: 22, counter: 5 }, + TestValue { value: 33, counter: 3 }, + TestValue { value: 44, counter: 1 }, + TestValue { value: 55, counter: 4 }, + ], + TestValue::empty(), ); TestBuilder { original_array_lt, original_array_gte, combined_array } @@ -81,14 +86,13 @@ mod tests { assert_combined_array( self.original_array_lt, self.original_array_gte, - self.combined_array + self.combined_array, ); } pub fn check_and_execute(self) { - let combined = unsafe { - combine_arrays(self.original_array_lt, self.original_array_gte) - }; + let combined = + unsafe { combine_arrays(self.original_array_lt, self.original_array_gte) }; assert_eq(combined, self.combined_array); self.execute(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array.nr index dcfbff7070e..a79a826af90 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array.nr @@ -3,15 +3,18 @@ mod get_combined_order_hints; use crate::{ abis::side_effect::Ordered, traits::{Empty, is_empty}, utils::arrays::{ - array_length, - assert_combined_sorted_transformed_value_array::get_combined_order_hints::{CombinedOrderHint, count_private_items} -} + array_length, + assert_combined_sorted_transformed_value_array::get_combined_order_hints::{ + CombinedOrderHint, count_private_items, + }, + }, }; -fn get_num_private_items(array: [T; N]) -> u32 where T: Ordered + Empty + Eq { - let length = unsafe { - count_private_items(array) - }; +fn get_num_private_items(array: [T; N]) -> u32 +where + T: Ordered + Empty + Eq, +{ + let length = unsafe { count_private_items(array) }; if length != 0 { let last_private_item = array[length - 1]; assert(!is_empty(last_private_item) & (last_private_item.counter() == 0)); @@ -32,8 +35,12 @@ pub fn assert_combined_sorted_transformed_value_array_asc original_array_gte: [T; N], sorted_transformed_value_array: [S; N], is_transformed: fn[Env](T, S) -> bool, - hints: [CombinedOrderHint; N] -) where T: Ordered + Empty + Eq, S: Empty + Eq { + hints: [CombinedOrderHint; N], +) +where + T: Ordered + Empty + Eq, + S: Empty + Eq, +{ let num_private_lt = get_num_private_items(original_array_lt); let num_private_gte = get_num_private_items(original_array_gte); let total_private = num_private_lt + num_private_gte; @@ -59,7 +66,11 @@ pub fn assert_combined_sorted_transformed_value_array_asc assert_eq(hint.original_index, i, "items with a counter of 0 should be prepended"); from_lt } else if should_be_private { - assert_eq(hint.original_index, i - num_private_lt, "items with a counter of 0 should be prepended"); + assert_eq( + hint.original_index, + i - num_private_lt, + "items with a counter of 0 should be prepended", + ); from_gte } else if should_be_public_gte { from_gte @@ -73,7 +84,8 @@ pub fn assert_combined_sorted_transformed_value_array_asc if !should_be_empty { if !should_be_private { assert( - dest_counter > prev_counter, "value array must be sorted by counter in ascending order" + dest_counter > prev_counter, + "value array must be sorted by counter in ascending order", ); } } else { @@ -86,15 +98,16 @@ pub fn assert_combined_sorted_transformed_value_array_asc mod tests { use crate::{ tests::utils::pad_end, - tests::types::{combine_two_values, is_combined_from_two_values, TestCombinedValue, TestTwoValues}, + tests::types::{ + combine_two_values, is_combined_from_two_values, TestCombinedValue, TestTwoValues, + }, utils::arrays::{ - array_merge, - assert_combined_sorted_transformed_value_array::{ - assert_combined_sorted_transformed_value_array_asc, - get_combined_order_hints::{CombinedOrderHint, get_combined_order_hints_asc} - }, - sort_by_counter::sort_by_counter_asc - } + array_merge, + assert_combined_sorted_transformed_value_array::{ + assert_combined_sorted_transformed_value_array_asc, + get_combined_order_hints::{CombinedOrderHint, get_combined_order_hints_asc}, + }, sort_by_counter::sort_by_counter_asc, + }, }; struct TestDataBuilder { @@ -108,38 +121,38 @@ mod tests { pub fn new() -> Self { let original_array_lt = pad_end( [ - TestTwoValues { value_1: 40, value_2: 7, counter: 0 }, - TestTwoValues { value_1: 70, value_2: 6, counter: 0 }, - TestTwoValues { value_1: 80, value_2: 1, counter: 22 }, - TestTwoValues { value_1: 30, value_2: 4, counter: 11 } - ], - TestTwoValues::empty() + TestTwoValues { value_1: 40, value_2: 7, counter: 0 }, + TestTwoValues { value_1: 70, value_2: 6, counter: 0 }, + TestTwoValues { value_1: 80, value_2: 1, counter: 22 }, + TestTwoValues { value_1: 30, value_2: 4, counter: 11 }, + ], + TestTwoValues::empty(), ); let original_array_gte = pad_end( [ - TestTwoValues { value_1: 20, value_2: 2, counter: 0 }, - TestTwoValues { value_1: 90, value_2: 3, counter: 0 }, - TestTwoValues { value_1: 50, value_2: 9, counter: 55 }, - TestTwoValues { value_1: 60, value_2: 8, counter: 33 }, - TestTwoValues { value_1: 10, value_2: 5, counter: 44 } - ], - TestTwoValues::empty() + TestTwoValues { value_1: 20, value_2: 2, counter: 0 }, + TestTwoValues { value_1: 90, value_2: 3, counter: 0 }, + TestTwoValues { value_1: 50, value_2: 9, counter: 55 }, + TestTwoValues { value_1: 60, value_2: 8, counter: 33 }, + TestTwoValues { value_1: 10, value_2: 5, counter: 44 }, + ], + TestTwoValues::empty(), ); let sorted_transformed_value_array = pad_end( [ - TestCombinedValue { value: 47 }, - TestCombinedValue { value: 76 }, - TestCombinedValue { value: 22 }, - TestCombinedValue { value: 93 }, - TestCombinedValue { value: 34 }, - TestCombinedValue { value: 81 }, - TestCombinedValue { value: 68 }, - TestCombinedValue { value: 15 }, - TestCombinedValue { value: 59 } - ], - TestCombinedValue::empty() + TestCombinedValue { value: 47 }, + TestCombinedValue { value: 76 }, + TestCombinedValue { value: 22 }, + TestCombinedValue { value: 93 }, + TestCombinedValue { value: 34 }, + TestCombinedValue { value: 81 }, + TestCombinedValue { value: 68 }, + TestCombinedValue { value: 15 }, + TestCombinedValue { value: 59 }, + ], + TestCombinedValue::empty(), ); let hints = [ @@ -154,10 +167,15 @@ mod tests { CombinedOrderHint { counter: 55, original_index: 2 }, CombinedOrderHint { counter: 0, original_index: 5 }, CombinedOrderHint { counter: 0, original_index: 6 }, - CombinedOrderHint { counter: 0, original_index: 7 } + CombinedOrderHint { counter: 0, original_index: 7 }, ]; - TestDataBuilder { original_array_lt, original_array_gte, sorted_transformed_value_array, hints } + TestDataBuilder { + original_array_lt, + original_array_gte, + sorted_transformed_value_array, + hints, + } } } @@ -165,30 +183,30 @@ mod tests { pub fn new_without_prepended() -> Self { let original_array_lt = pad_end( [ - TestTwoValues { value_1: 80, value_2: 1, counter: 22 }, - TestTwoValues { value_1: 30, value_2: 4, counter: 11 } - ], - TestTwoValues::empty() + TestTwoValues { value_1: 80, value_2: 1, counter: 22 }, + TestTwoValues { value_1: 30, value_2: 4, counter: 11 }, + ], + TestTwoValues::empty(), ); let original_array_gte = pad_end( [ - TestTwoValues { value_1: 50, value_2: 9, counter: 55 }, - TestTwoValues { value_1: 60, value_2: 8, counter: 33 }, - TestTwoValues { value_1: 10, value_2: 5, counter: 44 } - ], - TestTwoValues::empty() + TestTwoValues { value_1: 50, value_2: 9, counter: 55 }, + TestTwoValues { value_1: 60, value_2: 8, counter: 33 }, + TestTwoValues { value_1: 10, value_2: 5, counter: 44 }, + ], + TestTwoValues::empty(), ); let sorted_transformed_value_array = pad_end( [ - TestCombinedValue { value: 34 }, - TestCombinedValue { value: 81 }, - TestCombinedValue { value: 68 }, - TestCombinedValue { value: 15 }, - TestCombinedValue { value: 59 } - ], - TestCombinedValue::empty() + TestCombinedValue { value: 34 }, + TestCombinedValue { value: 81 }, + TestCombinedValue { value: 68 }, + TestCombinedValue { value: 15 }, + TestCombinedValue { value: 59 }, + ], + TestCombinedValue::empty(), ); let hints = [ @@ -199,10 +217,15 @@ mod tests { CombinedOrderHint { counter: 55, original_index: 0 }, CombinedOrderHint { counter: 0, original_index: 3 }, CombinedOrderHint { counter: 0, original_index: 4 }, - CombinedOrderHint { counter: 0, original_index: 5 } + CombinedOrderHint { counter: 0, original_index: 5 }, ]; - TestDataBuilder { original_array_lt, original_array_gte, sorted_transformed_value_array, hints } + TestDataBuilder { + original_array_lt, + original_array_gte, + sorted_transformed_value_array, + hints, + } } } @@ -225,7 +248,7 @@ mod tests { self.original_array_gte, self.sorted_transformed_value_array, is_combined_from_two_values, - self.hints + self.hints, ); } @@ -236,7 +259,8 @@ mod tests { assert_eq(hints, self.hints); let sorted = unsafe { - sort_by_counter_asc(array_merge(self.original_array_lt, self.original_array_gte)).map(combine_two_values) + sort_by_counter_asc(array_merge(self.original_array_lt, self.original_array_gte)) + .map(combine_two_values) }; assert_eq(sorted, self.sorted_transformed_value_array); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array/get_combined_order_hints.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array/get_combined_order_hints.nr index 3d0899b2c59..548362fb9df 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array/get_combined_order_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_sorted_transformed_value_array/get_combined_order_hints.nr @@ -1,6 +1,9 @@ use crate::{ abis::side_effect::Ordered, traits::{Empty, is_empty}, - utils::arrays::{array_length, sort_by_counter::compare_by_counter_empty_padded_asc, get_sorted_tuple::get_sorted_tuple} + utils::arrays::{ + array_length, sort_by_counter::compare_by_counter_empty_padded_asc, + get_sorted_tuple::get_sorted_tuple, + }, }; pub struct CombinedOrderHint { @@ -20,7 +23,10 @@ impl Eq for CombinedOrderHint { } } -pub unconstrained fn count_private_items(array: [T; N]) -> u32 where T: Ordered + Empty + Eq { +pub unconstrained fn count_private_items(array: [T; N]) -> u32 +where + T: Ordered + Empty + Eq, +{ let mut length = 0; for item in array { if !is_empty(item) & (item.counter() == 0) { @@ -32,8 +38,11 @@ pub unconstrained fn count_private_items(array: [T; N]) -> u32 wh pub unconstrained fn get_combined_order_hints_asc( array_lt: [T; N], - array_gte: [T; N] -) -> [CombinedOrderHint; N] where T: Ordered + Eq + Empty { + array_gte: [T; N], +) -> [CombinedOrderHint; N] +where + T: Ordered + Eq + Empty, +{ let mut hints = [CombinedOrderHint::empty(); N]; let sorted_lt = get_sorted_tuple(array_lt, compare_by_counter_empty_padded_asc); let sorted_gte = get_sorted_tuple(array_gte, compare_by_counter_empty_padded_asc); @@ -61,17 +70,17 @@ pub unconstrained fn get_combined_order_hints_asc( mod tests { use crate::{ tests::{types::TestValue, utils::pad_end}, - utils::arrays::assert_combined_sorted_transformed_value_array::get_combined_order_hints::{CombinedOrderHint, get_combined_order_hints_asc} + utils::arrays::assert_combined_sorted_transformed_value_array::get_combined_order_hints::{ + CombinedOrderHint, get_combined_order_hints_asc, + }, }; fn asc_to_equal( array_lt: [TestValue; N], array_gte: [TestValue; N], - expected: [CombinedOrderHint; N] + expected: [CombinedOrderHint; N], ) { - let hints = unsafe { - get_combined_order_hints_asc(array_lt, array_gte) - }; + let hints = unsafe { get_combined_order_hints_asc(array_lt, array_gte) }; assert_eq(hints, expected); } @@ -79,19 +88,19 @@ mod tests { fn get_combined_order_hints_asc_full_non_empty() { let array_lt = pad_end( [ - TestValue { value: 600, counter: 9 }, - TestValue { value: 400, counter: 3 }, - TestValue { value: 500, counter: 6 } - ], - TestValue::empty() + TestValue { value: 600, counter: 9 }, + TestValue { value: 400, counter: 3 }, + TestValue { value: 500, counter: 6 }, + ], + TestValue::empty(), ); let array_gte = pad_end( [ - TestValue { value: 200, counter: 13 }, - TestValue { value: 100, counter: 19 }, - TestValue { value: 300, counter: 16 } - ], - TestValue::empty() + TestValue { value: 200, counter: 13 }, + TestValue { value: 100, counter: 19 }, + TestValue { value: 300, counter: 16 }, + ], + TestValue::empty(), ); let expected_hints = [ CombinedOrderHint { counter: 3, original_index: 1 }, @@ -99,7 +108,7 @@ mod tests { CombinedOrderHint { counter: 9, original_index: 0 }, CombinedOrderHint { counter: 13, original_index: 0 }, CombinedOrderHint { counter: 16, original_index: 2 }, - CombinedOrderHint { counter: 19, original_index: 1 } + CombinedOrderHint { counter: 19, original_index: 1 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } @@ -107,11 +116,8 @@ mod tests { #[test] fn get_combined_order_hints_asc_padded_empty() { let array_lt = pad_end( - [ - TestValue { value: 500, counter: 6 }, - TestValue { value: 400, counter: 3 } - ], - TestValue::empty() + [TestValue { value: 500, counter: 6 }, TestValue { value: 400, counter: 3 }], + TestValue::empty(), ); let array_gte = pad_end([TestValue { value: 100, counter: 19 }], TestValue::empty()); let expected_hints = [ @@ -119,7 +125,7 @@ mod tests { CombinedOrderHint { counter: 6, original_index: 0 }, CombinedOrderHint { counter: 19, original_index: 0 }, CombinedOrderHint { counter: 0, original_index: 1 }, - CombinedOrderHint { counter: 0, original_index: 2 } + CombinedOrderHint { counter: 0, original_index: 2 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } @@ -128,17 +134,14 @@ mod tests { fn get_combined_order_hints_asc_lt_empty() { let array_lt = [TestValue::empty(); 4]; let array_gte = pad_end( - [ - TestValue { value: 200, counter: 13 }, - TestValue { value: 100, counter: 19 } - ], - TestValue::empty() + [TestValue { value: 200, counter: 13 }, TestValue { value: 100, counter: 19 }], + TestValue::empty(), ); let expected_hints = [ CombinedOrderHint { counter: 13, original_index: 0 }, CombinedOrderHint { counter: 19, original_index: 1 }, CombinedOrderHint { counter: 0, original_index: 2 }, - CombinedOrderHint { counter: 0, original_index: 3 } + CombinedOrderHint { counter: 0, original_index: 3 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } @@ -146,18 +149,15 @@ mod tests { #[test] fn get_combined_order_hints_asc_gte_empty() { let array_lt = pad_end( - [ - TestValue { value: 400, counter: 3 }, - TestValue { value: 500, counter: 6 } - ], - TestValue::empty() + [TestValue { value: 400, counter: 3 }, TestValue { value: 500, counter: 6 }], + TestValue::empty(), ); let array_gte = [TestValue::empty(); 4]; let expected_hints = [ CombinedOrderHint { counter: 3, original_index: 0 }, CombinedOrderHint { counter: 6, original_index: 1 }, CombinedOrderHint { counter: 0, original_index: 0 }, - CombinedOrderHint { counter: 0, original_index: 1 } + CombinedOrderHint { counter: 0, original_index: 1 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } @@ -169,7 +169,7 @@ mod tests { let expected_hints = [ CombinedOrderHint { counter: 0, original_index: 0 }, CombinedOrderHint { counter: 0, original_index: 1 }, - CombinedOrderHint { counter: 0, original_index: 2 } + CombinedOrderHint { counter: 0, original_index: 2 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } @@ -178,20 +178,20 @@ mod tests { fn get_combined_order_hints_asc_prepended_zero_counters() { let array_lt = pad_end( [ - TestValue { value: 700, counter: 0 }, - TestValue { value: 500, counter: 0 }, - TestValue { value: 100, counter: 16 }, - TestValue { value: 400, counter: 13 } - ], - TestValue::empty() + TestValue { value: 700, counter: 0 }, + TestValue { value: 500, counter: 0 }, + TestValue { value: 100, counter: 16 }, + TestValue { value: 400, counter: 13 }, + ], + TestValue::empty(), ); let array_gte = pad_end( [ - TestValue { value: 300, counter: 0 }, - TestValue { value: 600, counter: 0 }, - TestValue { value: 200, counter: 19 } - ], - TestValue::empty() + TestValue { value: 300, counter: 0 }, + TestValue { value: 600, counter: 0 }, + TestValue { value: 200, counter: 19 }, + ], + TestValue::empty(), ); let expected_hints = [ CombinedOrderHint { counter: 0, original_index: 0 }, @@ -203,7 +203,7 @@ mod tests { CombinedOrderHint { counter: 19, original_index: 2 }, CombinedOrderHint { counter: 0, original_index: 3 }, CombinedOrderHint { counter: 0, original_index: 4 }, - CombinedOrderHint { counter: 0, original_index: 5 } + CombinedOrderHint { counter: 0, original_index: 5 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } @@ -213,12 +213,12 @@ mod tests { let array_lt = [TestValue::empty(); 6]; let array_gte = pad_end( [ - TestValue { value: 300, counter: 0 }, - TestValue { value: 600, counter: 0 }, - TestValue { value: 200, counter: 19 }, - TestValue { value: 400, counter: 13 } - ], - TestValue::empty() + TestValue { value: 300, counter: 0 }, + TestValue { value: 600, counter: 0 }, + TestValue { value: 200, counter: 19 }, + TestValue { value: 400, counter: 13 }, + ], + TestValue::empty(), ); let expected_hints = [ CombinedOrderHint { counter: 0, original_index: 0 }, @@ -226,7 +226,7 @@ mod tests { CombinedOrderHint { counter: 13, original_index: 3 }, CombinedOrderHint { counter: 19, original_index: 2 }, CombinedOrderHint { counter: 0, original_index: 4 }, - CombinedOrderHint { counter: 0, original_index: 5 } + CombinedOrderHint { counter: 0, original_index: 5 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } @@ -235,12 +235,12 @@ mod tests { fn get_combined_order_hints_asc_prepended_zero_counters_gte_empty() { let array_lt = pad_end( [ - TestValue { value: 300, counter: 0 }, - TestValue { value: 600, counter: 0 }, - TestValue { value: 200, counter: 19 }, - TestValue { value: 400, counter: 13 } - ], - TestValue::empty() + TestValue { value: 300, counter: 0 }, + TestValue { value: 600, counter: 0 }, + TestValue { value: 200, counter: 19 }, + TestValue { value: 400, counter: 13 }, + ], + TestValue::empty(), ); let array_gte = [TestValue::empty(); 6]; let expected_hints = [ @@ -249,7 +249,7 @@ mod tests { CombinedOrderHint { counter: 13, original_index: 3 }, CombinedOrderHint { counter: 19, original_index: 2 }, CombinedOrderHint { counter: 0, original_index: 0 }, - CombinedOrderHint { counter: 0, original_index: 1 } + CombinedOrderHint { counter: 0, original_index: 1 }, ]; asc_to_equal(array_lt, array_gte, expected_hints); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr index d621a1f0546..082f33ebdd6 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr @@ -6,8 +6,11 @@ pub fn assert_combined_transformed_array( original_array_lt: [T; N], original_array_gte: [T; N], combined_array: [S; N], - is_transformed: fn[Env](T, S) -> bool -) where T: Empty + Eq { + is_transformed: fn[Env](T, S) -> bool, +) +where + T: Empty + Eq, +{ let num_lt = array_length(original_array_lt); let mut is_lt = true; for i in 0..N { @@ -28,8 +31,11 @@ pub fn assert_combined_transformed_array( pub unconstrained fn combine_and_transform_arrays( original_array_lt: [T; N], original_array_gte: [T; N], - transform: fn[Env](T) -> S -) -> [S; N] where T: Empty + Eq { + transform: fn[Env](T) -> S, +) -> [S; N] +where + T: Empty + Eq, +{ let mut combined = original_array_lt.map(transform); let num_lt = array_length(original_array_lt); @@ -45,8 +51,13 @@ pub unconstrained fn combine_and_transform_arrays( mod tests { use crate::{ - tests::{types::{is_summed_from_two_values, sum_two_values, TestTwoValues, TestValue}, utils::pad_end}, - utils::arrays::assert_combined_transformed_array::{assert_combined_transformed_array, combine_and_transform_arrays} + tests::{ + types::{is_summed_from_two_values, sum_two_values, TestTwoValues, TestValue}, + utils::pad_end, + }, + utils::arrays::assert_combined_transformed_array::{ + assert_combined_transformed_array, combine_and_transform_arrays, + }, }; struct TestBuilder { @@ -66,30 +77,30 @@ mod tests { pub fn new() -> Self { let original_array_lt = pad_end( [ - TestTwoValues { value_1: 10, value_2: 1, counter: 2 }, - TestTwoValues { value_1: 20, value_2: 2, counter: 5 }, - TestTwoValues { value_1: 30, value_2: 3, counter: 3 } - ], - TestTwoValues::empty() + TestTwoValues { value_1: 10, value_2: 1, counter: 2 }, + TestTwoValues { value_1: 20, value_2: 2, counter: 5 }, + TestTwoValues { value_1: 30, value_2: 3, counter: 3 }, + ], + TestTwoValues::empty(), ); let original_array_gte = pad_end( [ - TestTwoValues { value_1: 40, value_2: 4, counter: 1 }, - TestTwoValues { value_1: 50, value_2: 5, counter: 4 } - ], - TestTwoValues::empty() + TestTwoValues { value_1: 40, value_2: 4, counter: 1 }, + TestTwoValues { value_1: 50, value_2: 5, counter: 4 }, + ], + TestTwoValues::empty(), ); let combined_array = pad_end( [ - TestValue { value: 11, counter: 2 }, - TestValue { value: 22, counter: 5 }, - TestValue { value: 33, counter: 3 }, - TestValue { value: 44, counter: 1 }, - TestValue { value: 55, counter: 4 } - ], - TestValue::empty() + TestValue { value: 11, counter: 2 }, + TestValue { value: 22, counter: 5 }, + TestValue { value: 33, counter: 3 }, + TestValue { value: 44, counter: 1 }, + TestValue { value: 55, counter: 4 }, + ], + TestValue::empty(), ); TestBuilder { original_array_lt, original_array_gte, combined_array } @@ -100,7 +111,7 @@ mod tests { self.original_array_lt, self.original_array_gte, self.combined_array, - is_summed_from_two_values + is_summed_from_two_values, ); } @@ -109,7 +120,7 @@ mod tests { combine_and_transform_arrays( self.original_array_lt, self.original_array_gte, - sum_two_values + sum_two_values, ) }; assert_eq(combined, self.combined_array); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_deduped_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_deduped_array.nr index 2afcd75b7c3..17460434e88 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_deduped_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_deduped_array.nr @@ -1,10 +1,11 @@ use crate::{abis::side_effect::{Inner, Overridable}, traits::{Empty, is_empty}}; // Check that deduped_array contains values that are not being overriden, i.e. override_counter == 0. -pub fn assert_deduped_array( - original_array: [S; N], - deduped_array: [T; N] -) where S: Overridable + Inner, T: Eq + Empty { +pub fn assert_deduped_array(original_array: [S; N], deduped_array: [T; N]) +where + S: Overridable + Inner, + T: Eq + Empty, +{ let mut num_added = 0; for i in 0..original_array.len() { let original = original_array[i]; @@ -22,7 +23,10 @@ pub fn assert_deduped_array( } } -pub unconstrained fn dedupe_array(original_array: [S; N]) -> [T; N] where S: Overridable + Inner { +pub unconstrained fn dedupe_array(original_array: [S; N]) -> [T; N] +where + S: Overridable + Inner, +{ let mut deduped = BoundedVec::new(); for i in 0..original_array.len() { let original = original_array[i]; @@ -36,7 +40,7 @@ pub unconstrained fn dedupe_array(original_array: [S; N]) -> [ mod tests { use crate::{ abis::side_effect::{Inner, Overridable}, tests::{types::TestValue, utils::pad_end}, - traits::Empty, utils::arrays::assert_deduped_array::{assert_deduped_array, dedupe_array} + traits::Empty, utils::arrays::assert_deduped_array::{assert_deduped_array, dedupe_array}, }; struct TestItem { @@ -89,23 +93,18 @@ mod tests { TestValue { value: 44, counter: 4 }, TestValue { value: 11, counter: 6 }, TestValue { value: 11, counter: 3 }, - TestValue { value: 33, counter: 5 } + TestValue { value: 33, counter: 5 }, ]; let mut original_array = pad_end( values.map(|value: TestValue| TestItem { value, override_by: TestValue::empty() }), - TestItem::empty() + TestItem::empty(), ); original_array[1].override_by = values[4]; original_array[4].override_by = values[3]; let deduped_array = pad_end( - [ - values[0], - values[2], - values[3], - values[5] - ], - TestValue::empty() + [values[0], values[2], values[3], values[5]], + TestValue::empty(), ); TestBuilder { original_array, deduped_array } @@ -116,9 +115,7 @@ mod tests { } pub fn check_and_execute(self) { - let deduped = unsafe { - dedupe_array(self.original_array) - }; + let deduped = unsafe { dedupe_array(self.original_array) }; assert_eq(self.deduped_array, deduped); self.execute(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array.nr index 72b320cedf6..40f0072676e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array.nr @@ -2,7 +2,9 @@ mod get_order_hints; use crate::{ abis::side_effect::Ordered, traits::{Empty, is_empty}, - utils::arrays::{array_length, assert_exposed_sorted_transformed_value_array::get_order_hints::OrderHint} + utils::arrays::{ + array_length, assert_exposed_sorted_transformed_value_array::get_order_hints::OrderHint, + }, }; // original_array must be valid, i.e. validate_array(original_array) == true @@ -11,15 +13,20 @@ pub fn assert_exposed_sorted_transformed_value_array( original_array: [T; N], exposed_sorted_transformed_value_array: [S; N], is_transformed: fn[Env](T, S) -> bool, - hints: [OrderHint; N] -) where T: Ordered + Empty + Eq, S: Empty + Eq { + hints: [OrderHint; N], +) +where + T: Ordered + Empty + Eq, + S: Empty + Eq, +{ let num_non_empty_items = array_length(original_array); let mut should_be_empty = false; for i in 0..N { should_be_empty |= i == num_non_empty_items; if should_be_empty { assert( - is_empty(exposed_sorted_transformed_value_array[i]), "array must be padded with empty items" + is_empty(exposed_sorted_transformed_value_array[i]), + "array must be padded with empty items", ); } else { let original = original_array[i]; @@ -29,7 +36,8 @@ pub fn assert_exposed_sorted_transformed_value_array( assert_eq(original.counter(), hints[sorted_index].counter, "incorrect hinted counter"); if i != 0 { assert( - hints[i].counter > hints[i - 1].counter, "value array must be sorted by counter in ascending order" + hints[i].counter > hints[i - 1].counter, + "value array must be sorted by counter in ascending order", ); } } @@ -39,7 +47,9 @@ pub fn assert_exposed_sorted_transformed_value_array( mod tests { use crate::{ tests::types::{is_combined_from_two_values, TestCombinedValue, TestTwoValues}, - utils::arrays::{assert_exposed_sorted_transformed_value_array::{assert_exposed_sorted_transformed_value_array, get_order_hints::OrderHint}} + utils::arrays::assert_exposed_sorted_transformed_value_array::{ + assert_exposed_sorted_transformed_value_array, get_order_hints::OrderHint, + }, }; struct TestDataBuilder { @@ -56,7 +66,7 @@ mod tests { TestTwoValues { value_1: 30, value_2: 7, counter: 11 }, TestTwoValues { value_1: 40, value_2: 8, counter: 33 }, TestTwoValues::empty(), - TestTwoValues::empty() + TestTwoValues::empty(), ]; let exposed_sorted_transformed_value_array = [ @@ -65,7 +75,7 @@ mod tests { TestCombinedValue { value: 48 }, TestCombinedValue { value: 15 }, TestCombinedValue::empty(), - TestCombinedValue::empty() + TestCombinedValue::empty(), ]; let hints = [ @@ -74,7 +84,7 @@ mod tests { OrderHint { counter: 33, sorted_index: 0 }, OrderHint { counter: 44, sorted_index: 2 }, OrderHint { counter: 0, sorted_index: 4 }, - OrderHint { counter: 0, sorted_index: 5 } + OrderHint { counter: 0, sorted_index: 5 }, ]; TestDataBuilder { original_array, exposed_sorted_transformed_value_array, hints } @@ -85,7 +95,7 @@ mod tests { self.original_array, self.exposed_sorted_transformed_value_array, is_combined_from_two_values, - self.hints + self.hints, ); } } @@ -112,7 +122,8 @@ mod tests { // Swap the values at index 1 and 2. let tmp = builder.exposed_sorted_transformed_value_array[1]; - builder.exposed_sorted_transformed_value_array[1] = builder.exposed_sorted_transformed_value_array[2]; + builder.exposed_sorted_transformed_value_array[1] = + builder.exposed_sorted_transformed_value_array[2]; builder.exposed_sorted_transformed_value_array[2] = tmp; // Update counters in hints. @@ -137,7 +148,8 @@ mod tests { // Swap the values at index 1 and 2. let tmp = builder.exposed_sorted_transformed_value_array[1]; - builder.exposed_sorted_transformed_value_array[1] = builder.exposed_sorted_transformed_value_array[2]; + builder.exposed_sorted_transformed_value_array[1] = + builder.exposed_sorted_transformed_value_array[2]; builder.exposed_sorted_transformed_value_array[2] = tmp; // Update sorted indexes. @@ -156,7 +168,7 @@ mod tests { let mut builder = TestDataBuilder::new(); // Add a random item. - builder.exposed_sorted_transformed_value_array[4] = TestCombinedValue { value: 10 }; + builder.exposed_sorted_transformed_value_array[4] = TestCombinedValue { value: 10 }; builder.execute(); } @@ -166,7 +178,7 @@ mod tests { let mut builder = TestDataBuilder::new(); // Add a random item. - builder.exposed_sorted_transformed_value_array[4] = TestCombinedValue { value: 10 }; + builder.exposed_sorted_transformed_value_array[4] = TestCombinedValue { value: 10 }; // Change the hint to point to an empty item. builder.hints[4].sorted_index = 5; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr index 3122a29fd58..eb2f3c4827c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr @@ -1,9 +1,10 @@ use crate::{ abis::side_effect::Ordered, traits::Empty, utils::arrays::{ - sort_by_counter::{compare_by_counter_empty_padded_asc, compare_by_counter_empty_padded_desc}, - get_sorted_tuple::get_sorted_tuple -} + sort_by_counter::{ + compare_by_counter_empty_padded_asc, compare_by_counter_empty_padded_desc, + }, get_sorted_tuple::get_sorted_tuple, + }, }; pub struct OrderHint { @@ -25,8 +26,11 @@ impl Eq for OrderHint { pub unconstrained fn get_order_hints( array: [T; N], - ordering: fn(T, T) -> bool -) -> [OrderHint; N] where T: Ordered { + ordering: fn(T, T) -> bool, +) -> [OrderHint; N] +where + T: Ordered, +{ let sorted_tuples = get_sorted_tuple(array, ordering); let mut hints = [OrderHint::empty(); N]; @@ -40,18 +44,26 @@ pub unconstrained fn get_order_hints( hints } -pub unconstrained fn get_order_hints_asc(array: [T; N]) -> [OrderHint; N] where T: Ordered + Eq + Empty { +pub unconstrained fn get_order_hints_asc(array: [T; N]) -> [OrderHint; N] +where + T: Ordered + Eq + Empty, +{ get_order_hints(array, compare_by_counter_empty_padded_asc) } -pub unconstrained fn get_order_hints_desc(array: [T; N]) -> [OrderHint; N] where T: Ordered + Eq + Empty { +pub unconstrained fn get_order_hints_desc(array: [T; N]) -> [OrderHint; N] +where + T: Ordered + Eq + Empty, +{ get_order_hints(array, compare_by_counter_empty_padded_desc) } mod tests { use crate::{ tests::{types::TestValue, utils::pad_end}, - utils::arrays::assert_exposed_sorted_transformed_value_array::get_order_hints::{get_order_hints_asc, get_order_hints_desc, OrderHint} + utils::arrays::assert_exposed_sorted_transformed_value_array::get_order_hints::{ + get_order_hints_asc, get_order_hints_desc, OrderHint, + }, }; struct TestBuilder { @@ -63,7 +75,7 @@ mod tests { let array = [ TestValue { value: 100, counter: 9 }, TestValue { value: 200, counter: 3 }, - TestValue { value: 300, counter: 6 } + TestValue { value: 300, counter: 6 }, ]; TestBuilder { array } } @@ -73,11 +85,11 @@ mod tests { pub fn new_padded() -> Self { let array = pad_end( [ - TestValue { value: 100, counter: 9 }, - TestValue { value: 200, counter: 3 }, - TestValue { value: 300, counter: 6 } - ], - TestValue::empty() + TestValue { value: 100, counter: 9 }, + TestValue { value: 200, counter: 3 }, + TestValue { value: 300, counter: 6 }, + ], + TestValue::empty(), ); TestBuilder { array } } @@ -85,16 +97,12 @@ mod tests { impl TestBuilder { pub fn asc_to_equal(self, expected: [OrderHint; N]) { - let hints = unsafe { - get_order_hints_asc(self.array) - }; + let hints = unsafe { get_order_hints_asc(self.array) }; assert_eq(hints, expected); } pub fn desc_to_equal(self, expected: [OrderHint; N]) { - let hints = unsafe { - get_order_hints_desc(self.array) - }; + let hints = unsafe { get_order_hints_desc(self.array) }; assert_eq(hints, expected); } } @@ -105,7 +113,7 @@ mod tests { let expected_hints = [ OrderHint { counter: 3, sorted_index: 2 }, OrderHint { counter: 6, sorted_index: 0 }, - OrderHint { counter: 9, sorted_index: 1 } + OrderHint { counter: 9, sorted_index: 1 }, ]; builder.asc_to_equal(expected_hints); } @@ -118,7 +126,7 @@ mod tests { OrderHint { counter: 6, sorted_index: 0 }, OrderHint { counter: 9, sorted_index: 1 }, OrderHint { counter: 0, sorted_index: 3 }, - OrderHint { counter: 0, sorted_index: 4 } + OrderHint { counter: 0, sorted_index: 4 }, ]; builder.asc_to_equal(expected_hints); } @@ -129,7 +137,7 @@ mod tests { let expected_hints = [ OrderHint { counter: 9, sorted_index: 0 }, OrderHint { counter: 6, sorted_index: 2 }, - OrderHint { counter: 3, sorted_index: 1 } + OrderHint { counter: 3, sorted_index: 1 }, ]; builder.desc_to_equal(expected_hints); } @@ -142,7 +150,7 @@ mod tests { OrderHint { counter: 6, sorted_index: 2 }, OrderHint { counter: 3, sorted_index: 1 }, OrderHint { counter: 0, sorted_index: 3 }, - OrderHint { counter: 0, sorted_index: 4 } + OrderHint { counter: 0, sorted_index: 4 }, ]; builder.desc_to_equal(expected_hints); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_array.nr index 61f07521842..9877e53be36 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_array.nr @@ -4,8 +4,11 @@ pub fn assert_sorted_array( original_array: [T; N], sorted_array: [T; N], sorted_indexes: [u32; N], - ordering: fn[Env](T, T) -> bool -) where T: Eq + Empty { + ordering: fn[Env](T, T) -> bool, +) +where + T: Eq + Empty, +{ let mut seen_empty = false; for i in 0..N { let original_value = original_array[i]; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_transformed_value_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_transformed_value_array.nr index 39a7ec4576b..ec64f29f818 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_transformed_value_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_sorted_transformed_value_array.nr @@ -4,14 +4,18 @@ pub fn assert_sorted_transformed_value_array( original_array: [T; N], sorted_transformed_value_array: [S; N], is_transformed: fn[Env](T, S) -> bool, - sorted_indexes: [u32; N] -) where T: Eq + Empty, S: Ordered + Eq + Empty { + sorted_indexes: [u32; N], +) +where + T: Eq + Empty, + S: Ordered + Eq + Empty, +{ assert_sorted_transformed_value_array_capped_size( original_array, sorted_transformed_value_array, is_transformed, sorted_indexes, - N + N, ); } @@ -22,8 +26,12 @@ pub fn assert_sorted_transformed_value_array_capped_size( sorted_transformed_value_array: [S; N], is_transformed: fn[Env](T, S) -> bool, sorted_indexes: [u32; N], - capped_size: u32 -) where T: Eq + Empty, S: Ordered + Eq + Empty { + capped_size: u32, +) +where + T: Eq + Empty, + S: Ordered + Eq + Empty, +{ let num_non_empty_items = array_length(original_array); let mut should_be_empty = false; for i in 0..N { @@ -42,7 +50,8 @@ pub fn assert_sorted_transformed_value_array_capped_size( assert(is_mapped_item_empty, "unexpected non-empty item"); } else if i != 0 { assert( - mapped_item.counter() > sorted_transformed_value_array[i - 1].counter(), "value array must be sorted by counter in ascending order" + mapped_item.counter() > sorted_transformed_value_array[i - 1].counter(), + "value array must be sorted by counter in ascending order", ); } } else { @@ -54,7 +63,10 @@ pub fn assert_sorted_transformed_value_array_capped_size( mod tests { use crate::{ tests::types::{is_summed_from_two_values, TestTwoValues, TestValue}, - utils::arrays::{assert_sorted_transformed_value_array::{assert_sorted_transformed_value_array, assert_sorted_transformed_value_array_capped_size}} + utils::arrays::assert_sorted_transformed_value_array::{ + assert_sorted_transformed_value_array, + assert_sorted_transformed_value_array_capped_size, + }, }; struct TestDataBuilder { @@ -71,7 +83,7 @@ mod tests { TestTwoValues { value_1: 30, value_2: 7, counter: 11 }, TestTwoValues { value_1: 40, value_2: 8, counter: 33 }, TestTwoValues::empty(), - TestTwoValues::empty() + TestTwoValues::empty(), ]; let sorted_transformed_value_array = [ @@ -80,7 +92,7 @@ mod tests { TestValue { value: 48, counter: 33 }, TestValue { value: 15, counter: 44 }, TestValue::empty(), - TestValue::empty() + TestValue::empty(), ]; let sorted_indexes = [3, 1, 0, 2, 4, 5]; @@ -93,7 +105,7 @@ mod tests { self.original_array, self.sorted_transformed_value_array, is_summed_from_two_values, - self.sorted_indexes + self.sorted_indexes, ); } @@ -103,7 +115,7 @@ mod tests { self.sorted_transformed_value_array, is_summed_from_two_values, self.sorted_indexes, - capped_size + capped_size, ); } } @@ -149,7 +161,7 @@ mod tests { let mut builder = TestDataBuilder::new(); // Add a random item. - builder.sorted_transformed_value_array[4] = TestValue { value: 10, counter: 55 }; + builder.sorted_transformed_value_array[4] = TestValue { value: 10, counter: 55 }; builder.execute(); } @@ -159,7 +171,7 @@ mod tests { let mut builder = TestDataBuilder::new(); // Add a random item. - builder.sorted_transformed_value_array[4] = TestValue { value: 10, counter: 55 }; + builder.sorted_transformed_value_array[4] = TestValue { value: 10, counter: 55 }; // Change the hint to point to an empty item. builder.sorted_indexes[4] = 5; @@ -193,7 +205,7 @@ mod tests { let mut builder = TestDataBuilder::new(); // Add a random item outside of capped_size. - builder.sorted_transformed_value_array[4] = TestValue { value: 10, counter: 55 }; + builder.sorted_transformed_value_array[4] = TestValue { value: 10, counter: 55 }; builder.execute_capped(4); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays.nr index 038c51cc493..d5d058e54ea 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays.nr @@ -3,9 +3,10 @@ mod get_split_order_hints; use crate::{ abis::side_effect::Ordered, traits::Empty, utils::arrays::{ - array_length, assert_split_sorted_transformed_value_arrays::get_split_order_hints::SplitOrderHints, - validate_array -} + array_length, + assert_split_sorted_transformed_value_arrays::get_split_order_hints::SplitOrderHints, + validate_array, + }, }; // original_array must be valid, i.e. validate_array(original_array) == true @@ -19,8 +20,12 @@ fn assert_split_sorted_transformed_value_arrays( sorted_counters_lt: [u32; N], // Counters of the values in sorted_transformed_value_array_lt. sorted_counters_gte: [u32; N], // Counters of the values in sorted_transformed_value_array_gte. index_hints: [u32; N], // The index of the item in the correspinding sorted_transformed_value_array_(lt/gte) for each item in the original_array. - ascending: bool // Whether the items in sorted_transformed_value_array_(lt/gte) is in ascending order. -) where T: Ordered + Empty + Eq, S: Empty + Eq { + ascending: bool, // Whether the items in sorted_transformed_value_array_(lt/gte) is in ascending order. +) +where + T: Ordered + Empty + Eq, + S: Empty + Eq, +{ // Can use array_length instead of validate_array for the original_array because it's taken from the previous kernel and guaranteed to be valid. let total_num = array_length(original_array); @@ -37,7 +42,10 @@ fn assert_split_sorted_transformed_value_arrays( let (sorted_value, sorted_counter) = if is_lt { (sorted_transformed_value_array_lt[sorted_index], sorted_counters_lt[sorted_index]) } else { - (sorted_transformed_value_array_gte[sorted_index], sorted_counters_gte[sorted_index]) + ( + sorted_transformed_value_array_gte[sorted_index], + sorted_counters_gte[sorted_index], + ) }; assert_eq(value, sorted_value, "mismatch sorted values"); assert_eq(original.counter(), sorted_counter, "mismatch counters"); @@ -77,8 +85,12 @@ pub fn assert_split_sorted_transformed_value_arrays_asc( split_counter: u32, sorted_transformed_value_array_lt: [S; N], sorted_transformed_value_array_gte: [S; N], - hints: SplitOrderHints -) where T: Ordered + Empty + Eq, S: Empty + Eq { + hints: SplitOrderHints, +) +where + T: Ordered + Empty + Eq, + S: Empty + Eq, +{ assert_split_sorted_transformed_value_arrays( original_array, transformed_value_array, @@ -88,7 +100,7 @@ pub fn assert_split_sorted_transformed_value_arrays_asc( hints.sorted_counters_lt, hints.sorted_counters_gte, hints.sorted_indexes, - true + true, ); } @@ -98,8 +110,12 @@ pub fn assert_split_sorted_transformed_value_arrays_desc( split_counter: u32, sorted_transformed_value_array_lt: [S; N], sorted_transformed_value_array_gte: [S; N], - hints: SplitOrderHints -) where T: Ordered + Empty + Eq, S: Empty + Eq { + hints: SplitOrderHints, +) +where + T: Ordered + Empty + Eq, + S: Empty + Eq, +{ assert_split_sorted_transformed_value_arrays( original_array, transformed_value_array, @@ -109,30 +125,29 @@ pub fn assert_split_sorted_transformed_value_arrays_desc( hints.sorted_counters_lt, hints.sorted_counters_gte, hints.sorted_indexes, - false + false, ); } mod tests { use crate::{ tests::types::{combine_two_values, TestCombinedValue, TestTwoValues}, - utils::arrays::{ - assert_split_sorted_transformed_value_arrays::{ - assert_split_sorted_transformed_value_arrays_asc, - assert_split_sorted_transformed_value_arrays_desc, get_split_order_hints::SplitOrderHints - } - } + utils::arrays::assert_split_sorted_transformed_value_arrays::{ + assert_split_sorted_transformed_value_arrays_asc, + assert_split_sorted_transformed_value_arrays_desc, + get_split_order_hints::SplitOrderHints, + }, }; global original_array = [ - TestTwoValues { value_1: 1, value_2: 0, counter: 33 }, - TestTwoValues { value_1: 10, value_2: 6, counter: 44 }, - TestTwoValues { value_1: 20, value_2: 7, counter: 11 }, - TestTwoValues { value_1: 30, value_2: 8, counter: 0 }, - TestTwoValues { value_1: 40, value_2: 9, counter: 22 }, + TestTwoValues { value_1: 1, value_2: 0, counter: 33 }, + TestTwoValues { value_1: 10, value_2: 6, counter: 44 }, + TestTwoValues { value_1: 20, value_2: 7, counter: 11 }, + TestTwoValues { value_1: 30, value_2: 8, counter: 0 }, + TestTwoValues { value_1: 40, value_2: 9, counter: 22 }, + TestTwoValues::empty(), TestTwoValues::empty(), TestTwoValues::empty(), - TestTwoValues::empty() ]; struct TestDataBuilder { @@ -154,12 +169,13 @@ mod tests { sorted_transformed_value_array_gte: [TestCombinedValue::empty(); 8], split_counter: 0, hints: SplitOrderHints::empty(), - ascending: false + ascending: false, } } pub fn new() -> Self { - let transformed_value_array = original_array.map(|item: TestTwoValues| combine_two_values(item)); + let transformed_value_array = + original_array.map(|item: TestTwoValues| combine_two_values(item)); let split_counter = 15; let sorted_transformed_value_array_lt = [ @@ -170,7 +186,7 @@ mod tests { TestCombinedValue::empty(), TestCombinedValue::empty(), TestCombinedValue::empty(), - TestCombinedValue::empty() + TestCombinedValue::empty(), ]; let sorted_transformed_value_array_gte = [ TestCombinedValue { value: 49 }, @@ -180,12 +196,12 @@ mod tests { TestCombinedValue::empty(), TestCombinedValue::empty(), TestCombinedValue::empty(), - TestCombinedValue::empty() + TestCombinedValue::empty(), ]; let hints = SplitOrderHints { sorted_counters_lt: [0, 11, 0, 0, 0, 0, 0, 0], sorted_counters_gte: [22, 33, 44, 0, 0, 0, 0, 0], - sorted_indexes: [1, 2, 1, 0, 0, 0, 0, 0] + sorted_indexes: [1, 2, 1, 0, 0, 0, 0, 0], }; TestDataBuilder { @@ -195,12 +211,13 @@ mod tests { sorted_transformed_value_array_gte, split_counter, hints, - ascending: true + ascending: true, } } pub fn new_desc() -> Self { - let transformed_value_array = original_array.map(|item: TestTwoValues| combine_two_values(item)); + let transformed_value_array = + original_array.map(|item: TestTwoValues| combine_two_values(item)); let split_counter = 15; let sorted_transformed_value_array_lt = [ @@ -211,7 +228,7 @@ mod tests { TestCombinedValue::empty(), TestCombinedValue::empty(), TestCombinedValue::empty(), - TestCombinedValue::empty() + TestCombinedValue::empty(), ]; let sorted_transformed_value_array_gte = [ TestCombinedValue { value: 16 }, @@ -221,12 +238,12 @@ mod tests { TestCombinedValue::empty(), TestCombinedValue::empty(), TestCombinedValue::empty(), - TestCombinedValue::empty() + TestCombinedValue::empty(), ]; let hints = SplitOrderHints { sorted_counters_lt: [11, 0, 0, 0, 0, 0, 0, 0], sorted_counters_gte: [44, 33, 22, 0, 0, 0, 0, 0], - sorted_indexes: [1, 0, 0, 1, 2, 0, 0, 0] + sorted_indexes: [1, 0, 0, 1, 2, 0, 0, 0], }; TestDataBuilder { @@ -236,19 +253,20 @@ mod tests { sorted_transformed_value_array_gte, split_counter, hints, - ascending: false + ascending: false, } } pub fn update_sorted_index(&mut self, counter: u32, new_index: u32) { let mut original_index = original_array.len(); for i in 0..original_array.len() { - if (original_index == original_array.len()) & (original_array[i].counter == counter) { - original_index = i; + if (original_index == original_array.len()) & (original_array[i].counter == counter) + { + original_index = i; + } } + self.hints.sorted_indexes[original_index] = new_index; } - self.hints.sorted_indexes[original_index] = new_index; - } pub fn execute(self) { if self.ascending { @@ -258,7 +276,7 @@ mod tests { self.split_counter, self.sorted_transformed_value_array_lt, self.sorted_transformed_value_array_gte, - self.hints + self.hints, ); } else { assert_split_sorted_transformed_value_arrays_desc( @@ -267,7 +285,7 @@ mod tests { self.split_counter, self.sorted_transformed_value_array_lt, self.sorted_transformed_value_array_gte, - self.hints + self.hints, ); } } @@ -324,7 +342,8 @@ mod tests { // Swap two values in the sorted array. let tmp = builder.sorted_transformed_value_array_gte[0]; - builder.sorted_transformed_value_array_gte[0] = builder.sorted_transformed_value_array_gte[1]; + builder.sorted_transformed_value_array_gte[0] = + builder.sorted_transformed_value_array_gte[1]; builder.sorted_transformed_value_array_gte[1] = tmp; builder.execute(); @@ -336,13 +355,13 @@ mod tests { // Swap two values in the sorted array, also update their hints. let tmp = builder.sorted_transformed_value_array_gte[0]; - builder.sorted_transformed_value_array_gte[0] = builder.sorted_transformed_value_array_gte[1]; + builder.sorted_transformed_value_array_gte[0] = + builder.sorted_transformed_value_array_gte[1]; builder.sorted_transformed_value_array_gte[1] = tmp; builder.hints.sorted_counters_gte[0] = 33; builder.hints.sorted_counters_gte[1] = 22; builder.update_sorted_index(33, 0); // Item of counter 33 is now at index 0 of the sorted array. builder.update_sorted_index(22, 1); // Item of counter 22 is now at index 1 of the sorted array. - builder.execute(); } @@ -352,11 +371,11 @@ mod tests { // Swap two values in the sorted array, but keep their counters in the correct order. let tmp = builder.sorted_transformed_value_array_gte[0]; - builder.sorted_transformed_value_array_gte[0] = builder.sorted_transformed_value_array_gte[1]; + builder.sorted_transformed_value_array_gte[0] = + builder.sorted_transformed_value_array_gte[1]; builder.sorted_transformed_value_array_gte[1] = tmp; builder.update_sorted_index(33, 0); // Item of counter 33 is now at index 0 of the sorted array. builder.update_sorted_index(22, 1); // Item of counter 22 is now at index 1 of the sorted array. - builder.execute(); } @@ -365,12 +384,12 @@ mod tests { let mut builder = TestDataBuilder::new(); // Move the item with counter 44 from _gte to _lt. - builder.sorted_transformed_value_array_lt[2] = builder.sorted_transformed_value_array_gte[2]; + builder.sorted_transformed_value_array_lt[2] = + builder.sorted_transformed_value_array_gte[2]; builder.hints.sorted_counters_lt[2] = 44; builder.sorted_transformed_value_array_gte[2] = TestCombinedValue::empty(); builder.hints.sorted_counters_lt[2] = 0; builder.update_sorted_index(44, 2); // Item of counter 44 is now at index 2 of the sorted array. - builder.execute(); } @@ -379,7 +398,8 @@ mod tests { let mut builder = TestDataBuilder::new(); // Copy the item with counter 44 to _lt. - builder.sorted_transformed_value_array_lt[2] = builder.sorted_transformed_value_array_gte[2]; + builder.sorted_transformed_value_array_lt[2] = + builder.sorted_transformed_value_array_gte[2]; builder.hints.sorted_counters_lt[2] = 44; builder.execute(); @@ -390,7 +410,8 @@ mod tests { let mut builder = TestDataBuilder::new(); // Duplicate the item with counter 44. - builder.sorted_transformed_value_array_gte[3] = builder.sorted_transformed_value_array_gte[2]; + builder.sorted_transformed_value_array_gte[3] = + builder.sorted_transformed_value_array_gte[2]; builder.hints.sorted_counters_gte[3] = 44; builder.execute(); @@ -427,7 +448,8 @@ mod tests { for i in 0..num_items { let from_index = num_items - 1 - i; let to_index = num_items - i; - builder.sorted_transformed_value_array_lt[to_index] = builder.sorted_transformed_value_array_lt[from_index]; + builder.sorted_transformed_value_array_lt[to_index] = + builder.sorted_transformed_value_array_lt[from_index]; let counter = builder.hints.sorted_counters_lt[from_index]; builder.hints.sorted_counters_lt[to_index] = counter; builder.update_sorted_index(counter, to_index); @@ -447,7 +469,8 @@ mod tests { for i in 0..num_items { let from_index = num_items - 1 - i; let to_index = num_items - i; - builder.sorted_transformed_value_array_gte[to_index] = builder.sorted_transformed_value_array_gte[from_index]; + builder.sorted_transformed_value_array_gte[to_index] = + builder.sorted_transformed_value_array_gte[from_index]; let counter = builder.hints.sorted_counters_gte[from_index]; builder.hints.sorted_counters_gte[to_index] = counter; builder.update_sorted_index(counter, to_index); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr index 5a2b95333f4..ebb47835188 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr @@ -1,9 +1,10 @@ use crate::{ abis::side_effect::Ordered, traits::{Empty, is_empty}, utils::arrays::{ - sort_by_counter::{compare_by_counter_empty_padded_asc, compare_by_counter_empty_padded_desc}, - get_sorted_tuple::get_sorted_tuple -} + sort_by_counter::{ + compare_by_counter_empty_padded_asc, compare_by_counter_empty_padded_desc, + }, get_sorted_tuple::get_sorted_tuple, + }, }; pub struct SplitOrderHints { @@ -14,7 +15,11 @@ pub struct SplitOrderHints { impl SplitOrderHints { pub fn empty() -> SplitOrderHints { - SplitOrderHints { sorted_counters_lt: [0; N], sorted_counters_gte: [0; N], sorted_indexes: [0; N] } + SplitOrderHints { + sorted_counters_lt: [0; N], + sorted_counters_gte: [0; N], + sorted_indexes: [0; N], + } } } @@ -29,8 +34,11 @@ impl Eq for SplitOrderHints { unconstrained fn get_split_order_hints( array: [T; N], split_counter: u32, - ascending: bool -) -> SplitOrderHints where T: Ordered + Eq + Empty { + ascending: bool, +) -> SplitOrderHints +where + T: Ordered + Eq + Empty, +{ let ordering = if ascending { compare_by_counter_empty_padded_asc } else { @@ -69,35 +77,43 @@ unconstrained fn get_split_order_hints( pub unconstrained fn get_split_order_hints_asc( array: [T; N], - split_counter: u32 -) -> SplitOrderHints where T: Ordered + Eq + Empty { + split_counter: u32, +) -> SplitOrderHints +where + T: Ordered + Eq + Empty, +{ get_split_order_hints(array, split_counter, true) } pub unconstrained fn get_split_order_hints_desc( array: [T; N], - split_counter: u32 -) -> SplitOrderHints where T: Ordered + Eq + Empty { + split_counter: u32, +) -> SplitOrderHints +where + T: Ordered + Eq + Empty, +{ get_split_order_hints(array, split_counter, false) } mod tests { use crate::{ tests::{types::TestValue, utils::pad_end}, - utils::arrays::assert_split_sorted_transformed_value_arrays::get_split_order_hints::{get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints} + utils::arrays::assert_split_sorted_transformed_value_arrays::get_split_order_hints::{ + get_split_order_hints_asc, get_split_order_hints_desc, SplitOrderHints, + }, }; global full_array = [ - TestValue { value: 100, counter: 11 }, - TestValue { value: 200, counter: 17 }, - TestValue { value: 300, counter: 7 }, - TestValue { value: 400, counter: 5 }, - TestValue { value: 500, counter: 13 } - ]; + TestValue { value: 100, counter: 11 }, + TestValue { value: 200, counter: 17 }, + TestValue { value: 300, counter: 7 }, + TestValue { value: 400, counter: 5 }, + TestValue { value: 500, counter: 13 }, + ]; struct TestBuilder { array: [TestValue; N], - split_counter: u32 + split_counter: u32, } impl TestBuilder<5> { @@ -114,16 +130,12 @@ mod tests { impl TestBuilder { pub fn asc_to_equal(self, expected: SplitOrderHints) { - let hints = unsafe { - get_split_order_hints_asc(self.array, self.split_counter) - }; + let hints = unsafe { get_split_order_hints_asc(self.array, self.split_counter) }; assert_eq(hints, expected); } pub fn desc_to_equal(self, expected: SplitOrderHints) { - let hints = unsafe { - get_split_order_hints_desc(self.array, self.split_counter) - }; + let hints = unsafe { get_split_order_hints_desc(self.array, self.split_counter) }; assert_eq(hints, expected); } } @@ -136,7 +148,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [0, 0, 0, 0, 0], sorted_counters_gte: [5, 7, 11, 13, 17], - sorted_indexes: [2, 4, 1, 0, 3] + sorted_indexes: [2, 4, 1, 0, 3], }; builder.asc_to_equal(expected_hints); } @@ -149,7 +161,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [5, 7, 0, 0, 0], sorted_counters_gte: [11, 13, 17, 0, 0], - sorted_indexes: [0, 2, 1, 0, 1] + sorted_indexes: [0, 2, 1, 0, 1], }; builder.asc_to_equal(expected_hints); } @@ -162,7 +174,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [5, 7, 0, 0, 0], sorted_counters_gte: [11, 13, 17, 0, 0], - sorted_indexes: [0, 2, 1, 0, 1] + sorted_indexes: [0, 2, 1, 0, 1], }; builder.asc_to_equal(expected_hints); } @@ -174,7 +186,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [0, 0, 0, 0, 0, 0, 0], sorted_counters_gte: [5, 7, 11, 13, 17, 0, 0], - sorted_indexes: [2, 4, 1, 0, 3, 0, 0] + sorted_indexes: [2, 4, 1, 0, 3, 0, 0], }; builder.asc_to_equal(expected_hints); } @@ -187,7 +199,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [5, 7, 0, 0, 0, 0, 0], sorted_counters_gte: [11, 13, 17, 0, 0, 0, 0], - sorted_indexes: [0, 2, 1, 0, 1, 0, 0] + sorted_indexes: [0, 2, 1, 0, 1, 0, 0], }; builder.asc_to_equal(expected_hints); } @@ -200,7 +212,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [5, 7, 0, 0, 0, 0, 0], sorted_counters_gte: [11, 13, 17, 0, 0, 0, 0], - sorted_indexes: [0, 2, 1, 0, 1, 0, 0] + sorted_indexes: [0, 2, 1, 0, 1, 0, 0], }; builder.asc_to_equal(expected_hints); } @@ -213,7 +225,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [0, 0, 0, 0, 0], sorted_counters_gte: [17, 13, 11, 7, 5], - sorted_indexes: [2, 0, 3, 4, 1] + sorted_indexes: [2, 0, 3, 4, 1], }; builder.desc_to_equal(expected_hints); } @@ -226,7 +238,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [7, 5, 0, 0, 0], sorted_counters_gte: [17, 13, 11, 0, 0], - sorted_indexes: [2, 0, 0, 1, 1] + sorted_indexes: [2, 0, 0, 1, 1], }; builder.desc_to_equal(expected_hints); } @@ -239,7 +251,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [7, 5, 0, 0, 0], sorted_counters_gte: [17, 13, 11, 0, 0], - sorted_indexes: [2, 0, 0, 1, 1] + sorted_indexes: [2, 0, 0, 1, 1], }; builder.desc_to_equal(expected_hints); } @@ -250,7 +262,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [0, 0, 0, 0, 0, 0, 0], sorted_counters_gte: [17, 13, 11, 7, 5, 0, 0], - sorted_indexes: [2, 0, 3, 4, 1, 0, 0] + sorted_indexes: [2, 0, 3, 4, 1, 0, 0], }; builder.desc_to_equal(expected_hints); } @@ -263,7 +275,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [7, 5, 0, 0, 0, 0, 0], sorted_counters_gte: [17, 13, 11, 0, 0, 0, 0], - sorted_indexes: [2, 0, 0, 1, 1, 0, 0] + sorted_indexes: [2, 0, 0, 1, 1, 0, 0], }; builder.desc_to_equal(expected_hints); } @@ -276,7 +288,7 @@ mod tests { let expected_hints = SplitOrderHints { sorted_counters_lt: [7, 5, 0, 0, 0, 0, 0], sorted_counters_gte: [17, 13, 11, 0, 0, 0, 0], - sorted_indexes: [2, 0, 0, 1, 1, 0, 0] + sorted_indexes: [2, 0, 0, 1, 1, 0, 0], }; builder.desc_to_equal(expected_hints); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr index eb5418a644f..105ce5372b6 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr @@ -6,18 +6,24 @@ pub fn assert_split_transformed_value_arrays_with_hint( transformed_value_array_gte: [S; N], // Values whose counters are greater than or equal to the split counter. is_transformed: fn[Env](T, S) -> bool, split_counter: u32, - num_non_revertibles: u32 // Hint. Should check in this function. -) where T: Ordered + Empty + Eq, S: Empty + Eq { + num_non_revertibles: u32, // Hint. Should check in this function. +) +where + T: Ordered + Empty + Eq, + S: Empty + Eq, +{ if num_non_revertibles != 0 { assert( - sorted_array[num_non_revertibles - 1].counter() < split_counter, "counter of last non-revertible item is not less than the split counter" + sorted_array[num_non_revertibles - 1].counter() < split_counter, + "counter of last non-revertible item is not less than the split counter", ); } if num_non_revertibles != N { let first_revertible_counter = sorted_array[num_non_revertibles].counter(); assert( - (first_revertible_counter == 0) | (first_revertible_counter >= split_counter), "counter of first revertible item is not greater than or equal to the split counter" + (first_revertible_counter == 0) | (first_revertible_counter >= split_counter), + "counter of first revertible item is not greater than or equal to the split counter", ); } @@ -47,11 +53,14 @@ pub fn assert_split_transformed_value_arrays( transformed_value_array_lt: [S; N], // Values whose counters are less than the split counter. transformed_value_array_gte: [S; N], // Values whose counters are greater than or equal to the split counter. is_transformed: fn[Env](T, S) -> bool, - split_counter: u32 -) where T: Ordered + Empty + Eq, S: Empty + Eq { - let num_non_revertibles = unsafe { - find_index_hint(sorted_array, |n: T| n.counter() >= split_counter) - }; + split_counter: u32, +) +where + T: Ordered + Empty + Eq, + S: Empty + Eq, +{ + let num_non_revertibles = + unsafe { find_index_hint(sorted_array, |n: T| n.counter() >= split_counter) }; assert_split_transformed_value_arrays_with_hint( sorted_array, @@ -59,14 +68,16 @@ pub fn assert_split_transformed_value_arrays( transformed_value_array_gte, is_transformed, split_counter, - num_non_revertibles + num_non_revertibles, ); } mod tests { use crate::{ tests::{types::TestValue, utils::pad_end}, - utils::arrays::assert_split_transformed_value_arrays::{assert_split_transformed_value_arrays, assert_split_transformed_value_arrays_with_hint} + utils::arrays::assert_split_transformed_value_arrays::{ + assert_split_transformed_value_arrays, assert_split_transformed_value_arrays_with_hint, + }, }; global NUM_TEST_ITEMS: u32 = 5; @@ -79,7 +90,7 @@ mod tests { sorted_array: [TestValue; NUM_TEST_ITEMS], transformed_value_array_lt: [Field; NUM_TEST_ITEMS], transformed_value_array_gte: [Field; NUM_TEST_ITEMS], - split_counter: u32 + split_counter: u32, } impl TestBuilder { @@ -89,14 +100,19 @@ mod tests { TestValue { value: 30, counter: 7 }, TestValue { value: 80, counter: 11 }, TestValue { value: 10, counter: 13 }, - TestValue { value: 50, counter: 29 } + TestValue { value: 50, counter: 29 }, ]; let transformed_value_array_lt = pad_end([40, 30, 80], 0); let transformed_value_array_gte = pad_end([10, 50], 0); - TestBuilder { sorted_array, transformed_value_array_lt, transformed_value_array_gte, split_counter: 12 } + TestBuilder { + sorted_array, + transformed_value_array_lt, + transformed_value_array_gte, + split_counter: 12, + } } pub fn execute(self) { @@ -105,7 +121,7 @@ mod tests { self.transformed_value_array_lt, self.transformed_value_array_gte, is_transformed, - self.split_counter + self.split_counter, ); } @@ -116,7 +132,7 @@ mod tests { self.transformed_value_array_gte, is_transformed, self.split_counter, - num_non_revertibles + num_non_revertibles, ); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr index 928f4520833..6d0a31443b5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr @@ -1,4 +1,4 @@ -use crate::{utils::arrays::{get_sorted_tuple::{get_sorted_tuple, SortedTuple}}}; +use crate::utils::arrays::get_sorted_tuple::{get_sorted_tuple, SortedTuple}; pub struct SortedResult { sorted_array: [T; N], @@ -8,7 +8,7 @@ pub struct SortedResult { pub unconstrained fn get_sorted_result( values: [T; N], - ordering: fn(T, T) -> bool + ordering: fn(T, T) -> bool, ) -> SortedResult { let sorted = get_sorted_tuple(values, ordering); @@ -26,9 +26,7 @@ pub unconstrained fn get_sorted_result( #[test] fn get_sorted_hints_asc_non_padded() { let values = [40, 60, 20, 50]; - let res = unsafe { - get_sorted_result(values, |a: u32, b: u32| a < b) - }; + let res = unsafe { get_sorted_result(values, |a: u32, b: u32| a < b) }; assert_eq(res.sorted_array, [20, 40, 50, 60]); assert_eq(res.sorted_index_hints, [1, 3, 0, 2]); assert_eq(res.original_index_hints, [2, 0, 3, 1]); @@ -37,9 +35,7 @@ fn get_sorted_hints_asc_non_padded() { #[test] fn get_sorted_hints_desc_non_padded() { let values = [40, 20, 60, 50]; - let res = unsafe { - get_sorted_result(values, |a: u32, b: u32| b < a) - }; + let res = unsafe { get_sorted_result(values, |a: u32, b: u32| b < a) }; assert_eq(res.sorted_array, [60, 50, 40, 20]); assert_eq(res.sorted_index_hints, [2, 3, 0, 1]); } @@ -47,9 +43,8 @@ fn get_sorted_hints_desc_non_padded() { #[test] fn get_sorted_hints_asc_padded() { let values = [40, 60, 20, 50, 0, 0]; - let res = unsafe { - get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (a < b))) - }; + let res = + unsafe { get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (a < b))) }; assert_eq(res.sorted_array, [20, 40, 50, 60, 0, 0]); assert_eq(res.sorted_index_hints, [1, 3, 0, 2, 4, 5]); assert_eq(res.original_index_hints, [2, 0, 3, 1, 4, 5]); @@ -58,9 +53,8 @@ fn get_sorted_hints_asc_padded() { #[test] fn get_sorted_hints_desc_padded() { let values = [40, 60, 20, 50, 0, 0]; - let res = unsafe { - get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (b < a))) - }; + let res = + unsafe { get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (b < a))) }; assert_eq(res.sorted_array, [60, 50, 40, 20, 0, 0]); assert_eq(res.sorted_index_hints, [2, 0, 3, 1, 4, 5]); assert_eq(res.original_index_hints, [1, 3, 0, 2, 4, 5]); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr index 4dce601f563..d638e5cf279 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr @@ -5,17 +5,17 @@ pub struct SortedTuple { original_index: u32, } -pub unconstrained fn get_sorted_tuple(array: [T; N], ordering: fn[Env](T, T) -> bool) -> [SortedTuple; N] { +pub unconstrained fn get_sorted_tuple( + array: [T; N], + ordering: fn[Env](T, T) -> bool, +) -> [SortedTuple; N] { let mut tuples = [SortedTuple { elem: array[0], original_index: 0 }; N]; for i in 0..N { - tuples[i] = SortedTuple { - elem: array[i], - original_index: i, - }; + tuples[i] = SortedTuple { elem: array[i], original_index: i }; } sort_by( tuples, - |a: SortedTuple, b: SortedTuple| ordering(a.elem, b.elem) + |a: SortedTuple, b: SortedTuple| ordering(a.elem, b.elem), ) } @@ -26,11 +26,9 @@ fn get_sorted_tuple_asc() { SortedTuple { elem: 2, original_index: 1 }, SortedTuple { elem: 3, original_index: 0 }, SortedTuple { elem: 5, original_index: 3 }, - SortedTuple { elem: 9, original_index: 2 } + SortedTuple { elem: 9, original_index: 2 }, ]; - let sorted = unsafe { - get_sorted_tuple(original, |a: u64, b: u64| a < b) - }; + let sorted = unsafe { get_sorted_tuple(original, |a: u64, b: u64| a < b) }; for i in 0..4 { assert_eq(sorted[i].elem, expected[i].elem); assert_eq(sorted[i].original_index, expected[i].original_index); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr index 99f2b25d1af..f8eaddc7a23 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr @@ -3,16 +3,15 @@ use crate::utils::arrays::find_index_hint; // Copied from the stdlib Array.sort_via. // But this one doesn't use `ordering` to check that the array is sorted. // This is to allow preserving the order of equal values. -pub unconstrained fn sort_by(array: [T; N], ordering: fn[Env](T, T) -> bool) -> [T; N] { +pub unconstrained fn sort_by( + array: [T; N], + ordering: fn[Env](T, T) -> bool, +) -> [T; N] { let mut result = array; - let sorted_index = unsafe { - get_sorting_index(array, ordering) - }; + let sorted_index = unsafe { get_sorting_index(array, ordering) }; // Ensure the indexes are correct for i in 0..N { - let pos = unsafe { - find_index_hint(sorted_index, |index: u32| index == i) - }; + let pos = unsafe { find_index_hint(sorted_index, |index: u32| index == i) }; assert(sorted_index[pos] == i); } // Sort the array using the indexes @@ -24,12 +23,14 @@ pub unconstrained fn sort_by(array: [T; N], ordering: fn[Env // for i in 0..N - 1 { // assert(ordering(result[i], result[i + 1])); // } - result } /// Returns the index of the elements in the array that would sort it, using the provided custom sorting function. -unconstrained fn get_sorting_index(array: [T; N], ordering: fn[Env](T, T) -> bool) -> [u32; N] { +unconstrained fn get_sorting_index( + array: [T; N], + ordering: fn[Env](T, T) -> bool, +) -> [u32; N] { let mut result = [0; N]; let mut a = array; for i in 0..N { diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr index edb5279f50e..d4cd7176d87 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr @@ -1,18 +1,30 @@ use crate::{abis::side_effect::Ordered, traits::{Empty, is_empty}, utils::arrays::sort_by::sort_by}; -pub fn compare_by_counter_empty_padded_asc(a: T, b: T) -> bool where T: Ordered + Empty + Eq { +pub fn compare_by_counter_empty_padded_asc(a: T, b: T) -> bool +where + T: Ordered + Empty + Eq, +{ !is_empty(a) & (is_empty(b) | (a.counter() < b.counter())) } -pub fn compare_by_counter_empty_padded_desc(a: T, b: T) -> bool where T: Ordered + Empty + Eq { +pub fn compare_by_counter_empty_padded_desc(a: T, b: T) -> bool +where + T: Ordered + Empty + Eq, +{ !is_empty(a) & (is_empty(b) | (a.counter() >= b.counter())) } -pub unconstrained fn sort_by_counter_asc(array: [T; N]) -> [T; N] where T: Ordered + Empty + Eq { +pub unconstrained fn sort_by_counter_asc(array: [T; N]) -> [T; N] +where + T: Ordered + Empty + Eq, +{ sort_by(array, compare_by_counter_empty_padded_asc) } -pub unconstrained fn sort_by_counter_desc(array: [T; N]) -> [T; N] where T: Ordered + Empty + Eq { +pub unconstrained fn sort_by_counter_desc(array: [T; N]) -> [T; N] +where + T: Ordered + Empty + Eq, +{ sort_by(array, compare_by_counter_empty_padded_desc) } @@ -20,38 +32,34 @@ mod tests { use crate::{ tests::types::TestValue, utils::arrays::sort_by_counter::{ - compare_by_counter_empty_padded_asc, compare_by_counter_empty_padded_desc, sort_by_counter_asc, - sort_by_counter_desc - } + compare_by_counter_empty_padded_asc, compare_by_counter_empty_padded_desc, + sort_by_counter_asc, sort_by_counter_desc, + }, }; fn asc_values_to_equal(values: [u32; N], expected: [u32; N]) { let items = values.map(|value| TestValue { value: value as Field, counter: value }); - let sorted = unsafe { - sort_by_counter_asc(items).map(|item: TestValue| item.counter) - }; + let sorted = unsafe { sort_by_counter_asc(items).map(|item: TestValue| item.counter) }; assert_eq(sorted, expected); } fn desc_values_to_equal(values: [u32; N], expected: [u32; N]) { let items = values.map(|value| TestValue { value: value as Field, counter: value }); - let sorted = unsafe { - sort_by_counter_desc(items).map(|item: TestValue| item.counter) - }; + let sorted = unsafe { sort_by_counter_desc(items).map(|item: TestValue| item.counter) }; assert_eq(sorted, expected); } fn compare_test_items_asc(value_1: u32, value_2: u32) -> bool { compare_by_counter_empty_padded_asc( TestValue { value: value_1 as Field, counter: value_1 }, - TestValue { value: value_2 as Field, counter: value_2 } + TestValue { value: value_2 as Field, counter: value_2 }, ) } fn compare_test_items_desc(value_1: u32, value_2: u32) -> bool { compare_by_counter_empty_padded_desc( TestValue { value: value_1 as Field, counter: value_1 }, - TestValue { value: value_2 as Field, counter: value_2 } + TestValue { value: value_2 as Field, counter: value_2 }, ) } @@ -100,7 +108,7 @@ mod tests { TestValue { value: 44, counter: 0 }, TestValue { value: 22, counter: 0 }, TestValue::empty(), - TestValue::empty() + TestValue::empty(), ]; let expected = [ TestValue { value: 11, counter: 0 }, @@ -109,11 +117,9 @@ mod tests { TestValue { value: 55, counter: 1 }, TestValue { value: 33, counter: 2 }, TestValue::empty(), - TestValue::empty() + TestValue::empty(), ]; - let sorted = unsafe { - sort_by_counter_asc(original) - }; + let sorted = unsafe { sort_by_counter_asc(original) }; assert_eq(sorted, expected); } @@ -126,7 +132,7 @@ mod tests { TestValue { value: 44, counter: 0 }, TestValue { value: 22, counter: 0 }, TestValue::empty(), - TestValue::empty() + TestValue::empty(), ]; let expected = [ TestValue { value: 33, counter: 2 }, @@ -135,11 +141,9 @@ mod tests { TestValue { value: 44, counter: 0 }, TestValue { value: 11, counter: 0 }, TestValue::empty(), - TestValue::empty() + TestValue::empty(), ]; - let sorted = unsafe { - sort_by_counter_desc(original) - }; + let sorted = unsafe { sort_by_counter_desc(original) }; assert_eq(sorted, expected); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr index d4115e5743d..796d0906e77 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/field.nr @@ -48,14 +48,16 @@ unconstrained fn bytes_field_test() { // Tests correctness of field_from_bytes_32_trunc against existing methods // Bytes representing 0x543e0a6642ffeb8039296861765a53407bba62bd1c97ca43374de950bbe0a7 let inputs = [ - 84, 62, 10, 102, 66, 255, 235, 128, 57, 41, 104, 97, 118, 90, 83, 64, 123, 186, 98, 189, 28, 151, 202, 67, 55, 77, 233, 80, 187, 224, 167 + 84, 62, 10, 102, 66, 255, 235, 128, 57, 41, 104, 97, 118, 90, 83, 64, 123, 186, 98, 189, 28, + 151, 202, 67, 55, 77, 233, 80, 187, 224, 167, ]; let field = field_from_bytes(inputs, true); let return_bytes: [u8; 31] = field.to_be_bytes(); assert_eq(inputs, return_bytes); // 32 bytes - we remove the final byte, and check it matches the field let inputs2 = [ - 84, 62, 10, 102, 66, 255, 235, 128, 57, 41, 104, 97, 118, 90, 83, 64, 123, 186, 98, 189, 28, 151, 202, 67, 55, 77, 233, 80, 187, 224, 167, 158 + 84, 62, 10, 102, 66, 255, 235, 128, 57, 41, 104, 97, 118, 90, 83, 64, 123, 186, 98, 189, 28, + 151, 202, 67, 55, 77, 233, 80, 187, 224, 167, 158, ]; let field2 = field_from_bytes_32_trunc(inputs2); let return_bytes2: [u8; 31] = field.to_be_bytes(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/mod.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/mod.nr index f81cbafdf32..8c30a510f83 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/mod.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/mod.nr @@ -9,10 +9,18 @@ mod uint256; // if predicate == true then return lhs, else return rhs pub fn conditional_assign(predicate: bool, lhs: Field, rhs: Field) -> Field { - if predicate { lhs } else { rhs } + if predicate { + lhs + } else { + rhs + } } -pub fn arr_copy_slice(src: [T; N], mut dst: [T; M], offset: u32) -> [T; M] { +pub fn arr_copy_slice( + src: [T; N], + mut dst: [T; M], + offset: u32, +) -> [T; M] { let iterator_len = if N > M { M } else { N }; for i in 0..iterator_len { dst[i] = src[i + offset]; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr index 3d8ace278ef..bde3ed335be 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/reader.nr @@ -36,7 +36,11 @@ impl Reader { result } - pub fn read_struct_array(&mut self, deserialise: fn([Field; K]) -> T, mut result: [T; C]) -> [T; C] { + pub fn read_struct_array( + &mut self, + deserialise: fn([Field; K]) -> T, + mut result: [T; C], + ) -> [T; C] { for i in 0..C { result[i] = self.read_struct(deserialise); } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/uint256.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/uint256.nr index b54b7cc3b88..bf0fbaf2844 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/uint256.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/uint256.nr @@ -9,7 +9,7 @@ pub struct U256 { // This is in big-endian order, typically because // sha256 is usually in big endian order. // Note: this means that inner[0] has the most significant 64 bits. - inner : [u64; 4] + inner: [u64; 4], } impl U256 { @@ -65,7 +65,7 @@ impl U256 { let two_pow_64 = 2.pow_32(64); let high = (self.inner[0] as Field) * two_pow_64 + self.inner[1] as Field; - let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field; + let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field; [high, low] } @@ -85,10 +85,8 @@ fn smoke_u256_from_bytes32_all_zeroes() { fn smoke_u256_from_bytes32_one_zero_zero_zero() { // We want to output [1,0,0,0] let input = [ - 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, ]; let result = U256::from_bytes32(input); @@ -115,15 +113,10 @@ fn smoke_u256_from_bytes32_test() { inner[2]: 0x1122334455667788 inner[3]: 0x99AABBCCDDEEFF00 */ - let input : [u8;32] = [ - 0xAA, 0xBB, 0xCC, 0xDD, - 0xEE, 0xFF, 0x00, 0x11, - 0x22, 0x33, 0x44, 0x55, - 0x66, 0x77, 0x88, 0x99, - 0x11, 0x22, 0x33, 0x44, - 0x55, 0x66, 0x77, 0x88, - 0x99, 0xAA, 0xBB, 0xCC, - 0xDD, 0xEE, 0xFF, 0x00 + let input: [u8; 32] = [ + 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + 0x99, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, + 0xFF, 0x00, ]; let result = U256::from_bytes32(input); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/validate.nr b/noir-projects/noir-protocol-circuits/crates/types/src/validate.nr index 3698d80926e..cbc01d66269 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/validate.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/validate.nr @@ -1,7 +1,7 @@ // Returns whether to validate the output of the circuit. Eventually we'll want to change this // to `!dep::std::runtime::is_unconstrained`, so we skip unneeded validations when we // do not need to generate a proof. But for now, we always validate to make sure we catch -// errors earlier, as most of our tests run with real proofs disabled, which means validation +// errors earlier, as most of our tests run with real proofs disabled, which means validation // checks get skipped. pub fn should_validate_output() -> bool { true diff --git a/noir/bb-version b/noir/bb-version index 2f4c74eb2dd..a60476bfe1c 100644 --- a/noir/bb-version +++ b/noir/bb-version @@ -1 +1 @@ -0.56.0 +0.58.0 diff --git a/noir/noir-repo/.github/workflows/docs-pr.yml b/noir/noir-repo/.github/workflows/docs-pr.yml index 9cb6775bfb7..78abb8252b3 100644 --- a/noir/noir-repo/.github/workflows/docs-pr.yml +++ b/noir/noir-repo/.github/workflows/docs-pr.yml @@ -80,7 +80,7 @@ jobs: - name: Build docs env: - MATOMO_ENV: staging # not really a secret, it will show in the footer anyway + ENV: staging # not really a secret, it will show in the footer anyway run: yarn workspaces foreach -Rpt --from docs run build - name: Upload artifact diff --git a/noir/noir-repo/.github/workflows/test-js-packages.yml b/noir/noir-repo/.github/workflows/test-js-packages.yml index 0aa971a21f0..152d8b1653e 100644 --- a/noir/noir-repo/.github/workflows/test-js-packages.yml +++ b/noir/noir-repo/.github/workflows/test-js-packages.yml @@ -521,7 +521,7 @@ jobs: - { repo: AztecProtocol/aztec-packages, path: ./noir-projects/noir-contracts } # Disabled as aztec-packages requires a setup-step in order to generate a `Nargo.toml` #- { repo: AztecProtocol/aztec-packages, path: ./noir-projects/noir-protocol-circuits } - - { repo: zac-williamson/noir-edwards, path: ./, ref: 037e44b2ee8557c51f6aef9bb9d63ea9e32722d1 } + - { repo: noir-lang/noir-edwards, path: ./, ref: 3188ea74fe3b059219a2ea87899589c266256d74 } name: Check external repo - ${{ matrix.project.repo }} steps: - name: Checkout diff --git a/noir/noir-repo/.release-please-manifest.json b/noir/noir-repo/.release-please-manifest.json index cbf7bdda17c..663401247bf 100644 --- a/noir/noir-repo/.release-please-manifest.json +++ b/noir/noir-repo/.release-please-manifest.json @@ -1,4 +1,4 @@ { - ".": "0.35.0", - "acvm-repo": "0.51.0" + ".": "0.36.0", + "acvm-repo": "0.52.0" } diff --git a/noir/noir-repo/CHANGELOG.md b/noir/noir-repo/CHANGELOG.md index 6aa552ce90e..28b38e32dae 100644 --- a/noir/noir-repo/CHANGELOG.md +++ b/noir/noir-repo/CHANGELOG.md @@ -1,5 +1,94 @@ # Changelog +## [0.36.0](https://github.com/noir-lang/noir/compare/v0.35.0...v0.36.0) (2024-10-22) + + +### ⚠ BREAKING CHANGES + +* remove pedersen commitment (https://github.com/AztecProtocol/aztec-packages/pull/9107) +* remove pedersen hash opcode (https://github.com/AztecProtocol/aztec-packages/pull/9245) +* Brillig and AVM default all uninitialized memory cells to Field 0 (https://github.com/AztecProtocol/aztec-packages/pull/9057) +* remove keccak256 opcode from ACIR/Brillig (https://github.com/AztecProtocol/aztec-packages/pull/9104) +* Brillig with a stack and conditional inlining (https://github.com/AztecProtocol/aztec-packages/pull/8989) +* **avm:** remove CMOV opcode (https://github.com/AztecProtocol/aztec-packages/pull/9030) +* Integer division is not the inverse of integer multiplication ([#6243](https://github.com/noir-lang/noir/issues/6243)) +* kind size checks ([#6137](https://github.com/noir-lang/noir/issues/6137)) +* Change tag attributes to require a ' prefix ([#6235](https://github.com/noir-lang/noir/issues/6235)) + +### Features + +* Add `checked_transmute` ([#6262](https://github.com/noir-lang/noir/issues/6262)) ([2618061](https://github.com/noir-lang/noir/commit/2618061ee88e47fb063904d50af7a4eea26d3db9)) +* Add more `Type` and `UnresolvedType` methods ([#5994](https://github.com/noir-lang/noir/issues/5994)) ([8236cbd](https://github.com/noir-lang/noir/commit/8236cbdff60c1aaf41fc53142b6f0f9ea2fc2fa8)) +* Allow `unconstrained` after visibility ([#6246](https://github.com/noir-lang/noir/issues/6246)) ([f6dfbcf](https://github.com/noir-lang/noir/commit/f6dfbcf057efc95141b36499152dbd0b919a31b3)) +* Brillig and AVM default all uninitialized memory cells to Field 0 (https://github.com/AztecProtocol/aztec-packages/pull/9057) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Brillig with a stack and conditional inlining (https://github.com/AztecProtocol/aztec-packages/pull/8989) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Don't crash LSP when there are errors resolving the workspace ([#6257](https://github.com/noir-lang/noir/issues/6257)) ([7cc7197](https://github.com/noir-lang/noir/commit/7cc7197bf7b2e41c07e8d1979f7e9d45c676d11b)) +* Don't suggest private struct fields in LSP ([#6256](https://github.com/noir-lang/noir/issues/6256)) ([2a727b3](https://github.com/noir-lang/noir/commit/2a727b3f7f7fb84ab88b0d08e1ab29ae012a8c4f)) +* Handwritten parser ([#6180](https://github.com/noir-lang/noir/issues/6180)) ([c4273a0](https://github.com/noir-lang/noir/commit/c4273a0c8f8b751a3dbe097e070e4e7b2c8ec438)) +* **improve:** Remove scan through globals ([#6282](https://github.com/noir-lang/noir/issues/6282)) ([fd91913](https://github.com/noir-lang/noir/commit/fd91913806a49255ba721012c2e302959a82c4f6)) +* Inclusive for loop ([#6200](https://github.com/noir-lang/noir/issues/6200)) ([bd861f2](https://github.com/noir-lang/noir/commit/bd861f282144056ecb52954fa9f6fd8db918e093)) +* Integrate databus in the private kernels (https://github.com/AztecProtocol/aztec-packages/pull/9028) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* **interpreter:** Comptime derive generators ([#6303](https://github.com/noir-lang/noir/issues/6303)) ([d8767b3](https://github.com/noir-lang/noir/commit/d8767b364f4db9a52c823e7f39f36feac3c90fcd)) +* Kind size checks ([#6137](https://github.com/noir-lang/noir/issues/6137)) ([6e40f62](https://github.com/noir-lang/noir/commit/6e40f628a87ab4b5e9e817b7b3a790920dc01683)) +* New formatter ([#6300](https://github.com/noir-lang/noir/issues/6300)) ([62404d7](https://github.com/noir-lang/noir/commit/62404d7ff349ddf7551f2efd865adafc5213a742)) +* Optimize `Quoted::as_expr` by parsing just once ([#6237](https://github.com/noir-lang/noir/issues/6237)) ([a4fcd00](https://github.com/noir-lang/noir/commit/a4fcd0017e019f05b5a4d6b97c50b75f9e560210)) +* Optimize reading a workspace's files ([#6281](https://github.com/noir-lang/noir/issues/6281)) ([b54ed26](https://github.com/noir-lang/noir/commit/b54ed2671c8bc0e198e262883598936b9e49d69e)) +* **perf:** Flamegraphs for test program execution benchmarks ([#6253](https://github.com/noir-lang/noir/issues/6253)) ([c186791](https://github.com/noir-lang/noir/commit/c186791636c2afb2d3763bccee956298039feed2)) +* **perf:** Follow array sets backwards in array set from get optimization ([#6208](https://github.com/noir-lang/noir/issues/6208)) ([999071b](https://github.com/noir-lang/noir/commit/999071b80e61a37cb994a4e359eabbac27cd53f1)) +* Recover from '=' instead of ':' in struct constructor/pattern ([#6236](https://github.com/noir-lang/noir/issues/6236)) ([9a12f31](https://github.com/noir-lang/noir/commit/9a12f31e909bbd4d4f0538704b3f40ea654fabaf)) +* Remove byte decomposition in `compute_decomposition` ([#6159](https://github.com/noir-lang/noir/issues/6159)) ([a8bcae2](https://github.com/noir-lang/noir/commit/a8bcae215bf19356226ad052710c94b64da90ffa)) +* Show LSP diagnostic related information ([#6277](https://github.com/noir-lang/noir/issues/6277)) ([c8a91a5](https://github.com/noir-lang/noir/commit/c8a91a55d69c54e3ea9b6a16053fa83ce17b1426)) +* Slightly improve "unexpected token" error message ([#6279](https://github.com/noir-lang/noir/issues/6279)) ([8232bfa](https://github.com/noir-lang/noir/commit/8232bfaf0a88dcba5a6949489b81d78c3413c5bc)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8934) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/9034) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/9099) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/9275) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* **test:** Fuzz poseidon hases against an external library ([#6273](https://github.com/noir-lang/noir/issues/6273)) ([8d8ea89](https://github.com/noir-lang/noir/commit/8d8ea8963c5e4e23bd387aa729e09d3a9553a698)) +* **test:** Fuzz test poseidon2 hash equivalence ([#6265](https://github.com/noir-lang/noir/issues/6265)) ([f61ba03](https://github.com/noir-lang/noir/commit/f61ba037c6726e19be4f894d9447fe396df95417)) +* **test:** Fuzz test stdlib hash functions ([#6233](https://github.com/noir-lang/noir/issues/6233)) ([1a2ca46](https://github.com/noir-lang/noir/commit/1a2ca46af0d1c05813dbe28670a2bc39b79e4c9f)) +* **test:** Include the PoseidonHasher in the fuzzing ([#6280](https://github.com/noir-lang/noir/issues/6280)) ([afb8a7c](https://github.com/noir-lang/noir/commit/afb8a7cf7b1751a10dd2cdd87817945fa4c1ed1f)) +* Trait inheritance ([#6252](https://github.com/noir-lang/noir/issues/6252)) ([d3301a4](https://github.com/noir-lang/noir/commit/d3301a4f5558cf4e173f7d0edc08186ad4fb2eee)) +* Visibility for impl functions ([#6179](https://github.com/noir-lang/noir/issues/6179)) ([1b26440](https://github.com/noir-lang/noir/commit/1b26440889379f491315cd9d088537b1898d57c5)) +* Visibility for struct fields ([#6221](https://github.com/noir-lang/noir/issues/6221)) ([fc1c7ab](https://github.com/noir-lang/noir/commit/fc1c7ab6ee7be7c9d57fab5b2efe252c613f326b)) +* Warn about private types leaking in public functions and struct fields ([#6296](https://github.com/noir-lang/noir/issues/6296)) ([67ac0d6](https://github.com/noir-lang/noir/commit/67ac0d60c3e8b450a9e871f3edb29322ac5045d2)) + + +### Bug Fixes + +* Add missing visibility for auto-import names ([#6205](https://github.com/noir-lang/noir/issues/6205)) ([c3cb38a](https://github.com/noir-lang/noir/commit/c3cb38a7c4de6fc321b367eda3fca6d06e76b77a)) +* Address inactive public key check in `verify_signature_noir` ([#6270](https://github.com/noir-lang/noir/issues/6270)) ([e4325aa](https://github.com/noir-lang/noir/commit/e4325aace424d5c4552c92cdb360974fdd294048)) +* Allow array map on empty arrays ([#6305](https://github.com/noir-lang/noir/issues/6305)) ([51ae1b3](https://github.com/noir-lang/noir/commit/51ae1b324cd73fdb4fe3695b5d483a44b4aff4a9)) +* Change tag attributes to require a ' prefix ([#6235](https://github.com/noir-lang/noir/issues/6235)) ([b43dcb2](https://github.com/noir-lang/noir/commit/b43dcb2b30ce090c393990b2192411f9b3dc6a9e)) +* Check for Schnorr null signature ([#6226](https://github.com/noir-lang/noir/issues/6226)) ([2430920](https://github.com/noir-lang/noir/commit/24309200f600ad20a51d9f2c6c53849466fccda4)) +* Display function name and body when inlining recursion limit hit ([#6291](https://github.com/noir-lang/noir/issues/6291)) ([33a1e7d](https://github.com/noir-lang/noir/commit/33a1e7d2246bdea48dd6fe925d427c7be8c4659d)) +* Do not warn on unused self in traits ([#6298](https://github.com/noir-lang/noir/issues/6298)) ([4d524bf](https://github.com/noir-lang/noir/commit/4d524bf34de98449419a025aa53d593bf42e70a7)) +* Don't warn on unuse global if it has an abi annotation ([#6258](https://github.com/noir-lang/noir/issues/6258)) ([e13f617](https://github.com/noir-lang/noir/commit/e13f61741d17ed2e03ff26cb858cb3d243e67c88)) +* Don't warn on unused struct that has an abi annotation ([#6254](https://github.com/noir-lang/noir/issues/6254)) ([8a31632](https://github.com/noir-lang/noir/commit/8a316324a971a10d46392d7c64125d1d6ac9d557)) +* Don't warn twice when referring to private item ([#6216](https://github.com/noir-lang/noir/issues/6216)) ([619c545](https://github.com/noir-lang/noir/commit/619c5451b152d62e01d3c4c1da7e13ff6502f915)) +* Enforce correctness of decompositions performed at compile time ([#6278](https://github.com/noir-lang/noir/issues/6278)) ([53252fd](https://github.com/noir-lang/noir/commit/53252fd521ce7818a1d97824be30466590d879f5)) +* **frontend:** Do not warn when a nested struct is provided as input to main ([#6239](https://github.com/noir-lang/noir/issues/6239)) ([9dfe223](https://github.com/noir-lang/noir/commit/9dfe223e4dc168351c5cceb9d1abda326141b014)) +* Handle dfg databus in SSA normalization ([#6249](https://github.com/noir-lang/noir/issues/6249)) ([9d8bee5](https://github.com/noir-lang/noir/commit/9d8bee5b4e9308a812b1f93c3a48ddd11971ac17)) +* Handle nested arrays in calldata ([#6232](https://github.com/noir-lang/noir/issues/6232)) ([0ab8f5e](https://github.com/noir-lang/noir/commit/0ab8f5e3c32af05a3c158562c0fcf9729741e0ab)) +* Homogeneous input points for EC ADD ([#6241](https://github.com/noir-lang/noir/issues/6241)) ([f6a7306](https://github.com/noir-lang/noir/commit/f6a7306436ea1a37ec7f3b884721b50467e9a063)) +* Integer division is not the inverse of integer multiplication ([#6243](https://github.com/noir-lang/noir/issues/6243)) ([1cd2587](https://github.com/noir-lang/noir/commit/1cd2587bf67143832f76f90c25aecca1a46b1284)) +* Panic on composite types within databus ([#6225](https://github.com/noir-lang/noir/issues/6225)) ([29bd125](https://github.com/noir-lang/noir/commit/29bd125314b58e2eac23742ff1de022a97dcc60a)) +* Prevent compiler panic when popping from empty slices ([#6274](https://github.com/noir-lang/noir/issues/6274)) ([87137d8](https://github.com/noir-lang/noir/commit/87137d8d93622052dbe1c8a933d542a5c147c15c)) +* Reject invalid expression with in CLI parser ([#6287](https://github.com/noir-lang/noir/issues/6287)) ([052aee8](https://github.com/noir-lang/noir/commit/052aee80ff3e1e4fd2ca45310d7bb8b980af126a)) +* Remove need for duplicate attributes on each function (https://github.com/AztecProtocol/aztec-packages/pull/9244) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Visibility for impl methods ([#6261](https://github.com/noir-lang/noir/issues/6261)) ([70cbeb4](https://github.com/noir-lang/noir/commit/70cbeb4322a0b11c1c167ab27bf0408d04fe7b7d)) + + +### Miscellaneous Chores + +* Remove keccak256 opcode from ACIR/Brillig (https://github.com/AztecProtocol/aztec-packages/pull/9104) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Remove pedersen commitment (https://github.com/AztecProtocol/aztec-packages/pull/9107) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Remove pedersen hash opcode (https://github.com/AztecProtocol/aztec-packages/pull/9245) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) + + +### Code Refactoring + +* **avm:** Remove CMOV opcode (https://github.com/AztecProtocol/aztec-packages/pull/9030) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) + ## [0.35.0](https://github.com/noir-lang/noir/compare/v0.34.0...v0.35.0) (2024-10-03) diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index a24908fd2e6..3bfffca46e5 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "acir" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir_field", "base64 0.21.7", @@ -26,7 +26,7 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.51.0" +version = "0.52.0" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -40,7 +40,7 @@ dependencies = [ [[package]] name = "acvm" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -59,7 +59,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir", "blake2", @@ -96,7 +96,7 @@ dependencies = [ [[package]] name = "acvm_js" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acvm", "bn254_blackbox_solver", @@ -577,7 +577,7 @@ dependencies = [ [[package]] name = "bn254_blackbox_solver" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -595,7 +595,7 @@ dependencies = [ [[package]] name = "brillig" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir_field", "serde", @@ -603,7 +603,7 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.51.0" +version = "0.52.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -651,12 +651,6 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" -[[package]] -name = "bytecount" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" - [[package]] name = "bytemuck" version = "1.13.1" @@ -1532,7 +1526,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.35.0" +version = "0.36.0" dependencies = [ "codespan-reporting", "iter-extended", @@ -2129,7 +2123,7 @@ dependencies = [ [[package]] name = "iter-extended" -version = "0.35.0" +version = "0.36.0" [[package]] name = "itertools" @@ -2519,7 +2513,7 @@ dependencies = [ [[package]] name = "nargo" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "fm", @@ -2546,7 +2540,7 @@ dependencies = [ [[package]] name = "nargo_cli" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "ark-bn254", @@ -2604,10 +2598,8 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.35.0" +version = "0.36.0" dependencies = [ - "bytecount", - "noirc_errors", "noirc_frontend", "serde", "similar-asserts", @@ -2617,7 +2609,7 @@ dependencies = [ [[package]] name = "nargo_toml" -version = "0.35.0" +version = "0.36.0" dependencies = [ "dirs", "fm", @@ -2691,7 +2683,7 @@ dependencies = [ [[package]] name = "noir_debugger" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "assert_cmd", @@ -2715,7 +2707,7 @@ dependencies = [ [[package]] name = "noir_fuzzer" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "noirc_abi", @@ -2738,7 +2730,7 @@ dependencies = [ [[package]] name = "noir_lsp" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "async-lsp", @@ -2767,7 +2759,7 @@ dependencies = [ [[package]] name = "noir_profiler" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acir", "clap", @@ -2789,7 +2781,7 @@ dependencies = [ [[package]] name = "noir_wasm" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "build-data", @@ -2813,7 +2805,7 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "iter-extended", @@ -2832,7 +2824,7 @@ dependencies = [ [[package]] name = "noirc_abi_wasm" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "build-data", @@ -2849,11 +2841,11 @@ dependencies = [ [[package]] name = "noirc_arena" -version = "0.35.0" +version = "0.36.0" [[package]] name = "noirc_artifacts" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "codespan-reporting", @@ -2868,7 +2860,7 @@ dependencies = [ [[package]] name = "noirc_driver" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "build-data", @@ -2887,7 +2879,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "base64 0.21.7", @@ -2904,7 +2896,7 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "bn254_blackbox_solver", @@ -2927,7 +2919,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "base64 0.21.7", @@ -2957,7 +2949,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.35.0" +version = "0.36.0" dependencies = [ "acvm", "iter-extended", diff --git a/noir/noir-repo/Cargo.toml b/noir/noir-repo/Cargo.toml index 0a282631288..36b4d4c2ce1 100644 --- a/noir/noir-repo/Cargo.toml +++ b/noir/noir-repo/Cargo.toml @@ -40,7 +40,7 @@ resolver = "2" [workspace.package] # x-release-please-start-version -version = "0.35.0" +version = "0.36.0" # x-release-please-end authors = ["The Noir Team "] edition = "2021" @@ -57,13 +57,13 @@ unused_qualifications = "warn" [workspace.dependencies] # ACVM workspace dependencies -acir_field = { version = "0.51.0", path = "acvm-repo/acir_field", default-features = false } -acir = { version = "0.51.0", path = "acvm-repo/acir", default-features = false } -acvm = { version = "0.51.0", path = "acvm-repo/acvm" } -brillig = { version = "0.51.0", path = "acvm-repo/brillig", default-features = false } -brillig_vm = { version = "0.51.0", path = "acvm-repo/brillig_vm", default-features = false } -acvm_blackbox_solver = { version = "0.51.0", path = "acvm-repo/blackbox_solver", default-features = false } -bn254_blackbox_solver = { version = "0.51.0", path = "acvm-repo/bn254_blackbox_solver", default-features = false } +acir_field = { version = "0.52.0", path = "acvm-repo/acir_field", default-features = false } +acir = { version = "0.52.0", path = "acvm-repo/acir", default-features = false } +acvm = { version = "0.52.0", path = "acvm-repo/acvm" } +brillig = { version = "0.52.0", path = "acvm-repo/brillig", default-features = false } +brillig_vm = { version = "0.52.0", path = "acvm-repo/brillig_vm", default-features = false } +acvm_blackbox_solver = { version = "0.52.0", path = "acvm-repo/blackbox_solver", default-features = false } +bn254_blackbox_solver = { version = "0.52.0", path = "acvm-repo/bn254_blackbox_solver", default-features = false } # Noir compiler workspace dependencies fm = { path = "compiler/fm" } diff --git a/noir/noir-repo/acvm-repo/CHANGELOG.md b/noir/noir-repo/acvm-repo/CHANGELOG.md index 9541edb74a3..2cdb21a1d65 100644 --- a/noir/noir-repo/acvm-repo/CHANGELOG.md +++ b/noir/noir-repo/acvm-repo/CHANGELOG.md @@ -5,6 +5,121 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.52.0](https://github.com/noir-lang/noir/compare/v0.51.0...v0.52.0) (2024-10-22) + + +### ⚠ BREAKING CHANGES + +* remove pedersen commitment (https://github.com/AztecProtocol/aztec-packages/pull/9107) +* remove pedersen hash opcode (https://github.com/AztecProtocol/aztec-packages/pull/9245) +* Brillig and AVM default all uninitialized memory cells to Field 0 (https://github.com/AztecProtocol/aztec-packages/pull/9057) +* remove keccak256 opcode from ACIR/Brillig (https://github.com/AztecProtocol/aztec-packages/pull/9104) +* Brillig with a stack and conditional inlining (https://github.com/AztecProtocol/aztec-packages/pull/8989) +* **avm:** remove CMOV opcode (https://github.com/AztecProtocol/aztec-packages/pull/9030) +* remove sha256 opcode (https://github.com/AztecProtocol/aztec-packages/pull/4571) +* add support for u1 in the avm, ToRadix's radix arg is a memory addr (https://github.com/AztecProtocol/aztec-packages/pull/8570) +* Add Not instruction in brillig (https://github.com/AztecProtocol/aztec-packages/pull/8488) +* **avm:** variants for SET opcode (https://github.com/AztecProtocol/aztec-packages/pull/8441) +* **avm/brillig:** take addresses in calldatacopy (https://github.com/AztecProtocol/aztec-packages/pull/8388) +* constant inputs for blackbox (https://github.com/AztecProtocol/aztec-packages/pull/7222) + +### Features + +* (bb) 128-bit challenges (https://github.com/AztecProtocol/aztec-packages/pull/8406) ([3c3ed1e](https://github.com/noir-lang/noir/commit/3c3ed1e3d28946a02071c524dd128afe131bc3da)) +* **acir_gen:** Width aware ACIR gen addition ([#5493](https://github.com/noir-lang/noir/issues/5493)) ([85fa592](https://github.com/noir-lang/noir/commit/85fa592fdef3b8589ce03b232e1b51565837b540)) +* Add assertions for ACVM `FunctionInput` `bit_size` ([#5864](https://github.com/noir-lang/noir/issues/5864)) ([8712f4c](https://github.com/noir-lang/noir/commit/8712f4c20d23f3809bcfb03f2e3ba0e5ace20a1d)) +* Add Not instruction in brillig (https://github.com/AztecProtocol/aztec-packages/pull/8488) ([95e19ab](https://github.com/noir-lang/noir/commit/95e19ab9486ad054241b6e53e40e55bdba9dc7e5)) +* Add recursive aggregation object to proving/verification keys (https://github.com/AztecProtocol/aztec-packages/pull/6770) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Add reusable procedures to brillig generation (https://github.com/AztecProtocol/aztec-packages/pull/7981) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* Add support for u1 in the avm, ToRadix's radix arg is a memory addr (https://github.com/AztecProtocol/aztec-packages/pull/8570) ([e8bbce7](https://github.com/noir-lang/noir/commit/e8bbce71fde3fc7af410c30920c2a547389d8248)) +* Added indirect const instruction (https://github.com/AztecProtocol/aztec-packages/pull/8065) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* Adding aggregation to honk and rollup (https://github.com/AztecProtocol/aztec-packages/pull/7466) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Automate verify_honk_proof input generation (https://github.com/AztecProtocol/aztec-packages/pull/8092) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* **avm/brillig:** Take addresses in calldatacopy (https://github.com/AztecProtocol/aztec-packages/pull/8388) ([3c3ed1e](https://github.com/noir-lang/noir/commit/3c3ed1e3d28946a02071c524dd128afe131bc3da)) +* **avm:** Variants for SET opcode (https://github.com/AztecProtocol/aztec-packages/pull/8441) ([3c3ed1e](https://github.com/noir-lang/noir/commit/3c3ed1e3d28946a02071c524dd128afe131bc3da)) +* Avoid heap allocs when going to/from field (https://github.com/AztecProtocol/aztec-packages/pull/7547) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Brillig and AVM default all uninitialized memory cells to Field 0 (https://github.com/AztecProtocol/aztec-packages/pull/9057) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Brillig with a stack and conditional inlining (https://github.com/AztecProtocol/aztec-packages/pull/8989) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Change the layout of arrays and vectors to be a single pointer (https://github.com/AztecProtocol/aztec-packages/pull/8448) ([d4832ec](https://github.com/noir-lang/noir/commit/d4832ece9d3ad16544afea49cc7caf40501a2cc3)) +* Constant inputs for blackbox (https://github.com/AztecProtocol/aztec-packages/pull/7222) ([fb97bb9](https://github.com/noir-lang/noir/commit/fb97bb9b795c9d7af395b82fd6f0ea8111d59c11)) +* Hook up secondary calldata column in dsl (https://github.com/AztecProtocol/aztec-packages/pull/7759) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Integrate databus in the private kernels (https://github.com/AztecProtocol/aztec-packages/pull/9028) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Integrate new proving systems in e2e (https://github.com/AztecProtocol/aztec-packages/pull/6971) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Make Brillig do integer arithmetic operations using u128 instead of Bigint (https://github.com/AztecProtocol/aztec-packages/pull/7518) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Make token transfer be recursive (https://github.com/AztecProtocol/aztec-packages/pull/7730) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* New test programs for wasm benchmarking (https://github.com/AztecProtocol/aztec-packages/pull/8389) ([95e19ab](https://github.com/noir-lang/noir/commit/95e19ab9486ad054241b6e53e40e55bdba9dc7e5)) +* Note hashes as points (https://github.com/AztecProtocol/aztec-packages/pull/7618) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Optimize allocating immediate amounts of memory (https://github.com/AztecProtocol/aztec-packages/pull/8579) ([e8bbce7](https://github.com/noir-lang/noir/commit/e8bbce71fde3fc7af410c30920c2a547389d8248)) +* Optimize constant array handling in brillig_gen (https://github.com/AztecProtocol/aztec-packages/pull/7661) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Optimize to_radix (https://github.com/AztecProtocol/aztec-packages/pull/8073) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* Pass calldata ids to the backend (https://github.com/AztecProtocol/aztec-packages/pull/7875) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Poseidon2 gates for Ultra arithmetisation (https://github.com/AztecProtocol/aztec-packages/pull/7494) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* **profiler:** Add support for brillig functions in opcodes-flamegraph (https://github.com/AztecProtocol/aztec-packages/pull/7698) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Remove sha256 opcode (https://github.com/AztecProtocol/aztec-packages/pull/4571) ([e8bbce7](https://github.com/noir-lang/noir/commit/e8bbce71fde3fc7af410c30920c2a547389d8248)) +* Removing superfluous call to MSM (https://github.com/AztecProtocol/aztec-packages/pull/7708) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Report gates and VKs of private protocol circuits with megahonk (https://github.com/AztecProtocol/aztec-packages/pull/7722) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Simplify constant calls to `poseidon2_permutation`, `schnorr_verify` and `embedded_curve_add` ([#5140](https://github.com/noir-lang/noir/issues/5140)) ([2823ba7](https://github.com/noir-lang/noir/commit/2823ba7242db788ca1d7f6e7a48be2f1de62f278)) +* Small optimization in toradix (https://github.com/AztecProtocol/aztec-packages/pull/8040) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7392) ([fb97bb9](https://github.com/noir-lang/noir/commit/fb97bb9b795c9d7af395b82fd6f0ea8111d59c11)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7400) ([fb97bb9](https://github.com/noir-lang/noir/commit/fb97bb9b795c9d7af395b82fd6f0ea8111d59c11)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7432) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7444) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7454) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7512) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7577) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7583) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7743) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7862) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7945) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7958) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8008) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8093) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8125) ([f0c2686](https://github.com/noir-lang/noir/commit/f0c268606a71381ab4504396695a0adb9b3258b6)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8237) ([f0c2686](https://github.com/noir-lang/noir/commit/f0c268606a71381ab4504396695a0adb9b3258b6)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8423) ([3c3ed1e](https://github.com/noir-lang/noir/commit/3c3ed1e3d28946a02071c524dd128afe131bc3da)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8435) ([3c3ed1e](https://github.com/noir-lang/noir/commit/3c3ed1e3d28946a02071c524dd128afe131bc3da)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8466) ([3c3ed1e](https://github.com/noir-lang/noir/commit/3c3ed1e3d28946a02071c524dd128afe131bc3da)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8482) ([d4832ec](https://github.com/noir-lang/noir/commit/d4832ece9d3ad16544afea49cc7caf40501a2cc3)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8512) ([95e19ab](https://github.com/noir-lang/noir/commit/95e19ab9486ad054241b6e53e40e55bdba9dc7e5)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8526) ([95e19ab](https://github.com/noir-lang/noir/commit/95e19ab9486ad054241b6e53e40e55bdba9dc7e5)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/8934) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/9034) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/9099) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/9275) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* **test:** Fuzz test poseidon2 hash equivalence ([#6265](https://github.com/noir-lang/noir/issues/6265)) ([f61ba03](https://github.com/noir-lang/noir/commit/f61ba037c6726e19be4f894d9447fe396df95417)) +* **test:** Fuzz test stdlib hash functions ([#6233](https://github.com/noir-lang/noir/issues/6233)) ([1a2ca46](https://github.com/noir-lang/noir/commit/1a2ca46af0d1c05813dbe28670a2bc39b79e4c9f)) +* TXE nr deployments, dependency cleanup for CLI (https://github.com/AztecProtocol/aztec-packages/pull/7548) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Typing return values of embedded_curve_ops (https://github.com/AztecProtocol/aztec-packages/pull/7413) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* Unify all acir recursion constraints based on RecursionConstraint and proof_type (https://github.com/AztecProtocol/aztec-packages/pull/7993) ([5c4f19f](https://github.com/noir-lang/noir/commit/5c4f19f097dd3704522996330c961bf0a2db8d99)) + + +### Bug Fixes + +* Add trailing extra arguments for backend in gates_flamegraph (https://github.com/AztecProtocol/aztec-packages/pull/7472) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) +* **debugger:** Update the debugger to handle the new Brillig debug metadata format ([#5706](https://github.com/noir-lang/noir/issues/5706)) ([a31f82e](https://github.com/noir-lang/noir/commit/a31f82e598def60d00c65b79b8c5411f8aa832aa)) +* Deflatten databus visibilities (https://github.com/AztecProtocol/aztec-packages/pull/7761) ([4ea25db](https://github.com/noir-lang/noir/commit/4ea25dbde87488e758139619a3ce4edf93c6ebd6)) +* Do not duplicate redundant Brillig debug metadata ([#5696](https://github.com/noir-lang/noir/issues/5696)) ([e4f7dbe](https://github.com/noir-lang/noir/commit/e4f7dbe63b55807b3ff0b4d6f47a8b7f847299fb)) +* Export brillig names in contract functions (https://github.com/AztecProtocol/aztec-packages/pull/8212) ([f0c2686](https://github.com/noir-lang/noir/commit/f0c268606a71381ab4504396695a0adb9b3258b6)) +* Handle multiple entry points for Brillig call stack resolution after metadata deduplication ([#5788](https://github.com/noir-lang/noir/issues/5788)) ([38fe9dd](https://github.com/noir-lang/noir/commit/38fe9dda111952fdb894df90a319c087382edfc9)) +* Homogeneous input points for EC ADD ([#6241](https://github.com/noir-lang/noir/issues/6241)) ([f6a7306](https://github.com/noir-lang/noir/commit/f6a7306436ea1a37ec7f3b884721b50467e9a063)) +* Move BigInt modulus checks to runtime in brillig ([#5374](https://github.com/noir-lang/noir/issues/5374)) ([741d339](https://github.com/noir-lang/noir/commit/741d33991f8e2918bf092c354ca56047e0274533)) +* Reject invalid expression with in CLI parser ([#6287](https://github.com/noir-lang/noir/issues/6287)) ([052aee8](https://github.com/noir-lang/noir/commit/052aee80ff3e1e4fd2ca45310d7bb8b980af126a)) +* Remove need for duplicate attributes on each function (https://github.com/AztecProtocol/aztec-packages/pull/9244) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Restrict keccak256_injective test input to 8 bits ([#5977](https://github.com/noir-lang/noir/issues/5977)) ([a1b1346](https://github.com/noir-lang/noir/commit/a1b1346bf7525c508fd390393c307475cc2345d7)) +* Revert "feat: Sync from noir (https://github.com/AztecProtocol/aztec-packages/pull/7512)" (https://github.com/AztecProtocol/aztec-packages/pull/7558) ([daad75c](https://github.com/noir-lang/noir/commit/daad75c26d19ae707b90a7424b77dab9937e8575)) + + +### Miscellaneous Chores + +* Remove keccak256 opcode from ACIR/Brillig (https://github.com/AztecProtocol/aztec-packages/pull/9104) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Remove pedersen commitment (https://github.com/AztecProtocol/aztec-packages/pull/9107) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) +* Remove pedersen hash opcode (https://github.com/AztecProtocol/aztec-packages/pull/9245) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) + + +### Code Refactoring + +* **avm:** Remove CMOV opcode (https://github.com/AztecProtocol/aztec-packages/pull/9030) ([70dcf4a](https://github.com/noir-lang/noir/commit/70dcf4a25dcad10daeb427f0887d3a0bf10c9916)) + ## [0.51.0](https://github.com/noir-lang/noir/compare/v0.50.0...v0.51.0) (2024-10-03) diff --git a/noir/noir-repo/acvm-repo/acir/Cargo.toml b/noir/noir-repo/acvm-repo/acir/Cargo.toml index 69d0f273bb3..c030016a716 100644 --- a/noir/noir-repo/acvm-repo/acir/Cargo.toml +++ b/noir/noir-repo/acvm-repo/acir/Cargo.toml @@ -2,7 +2,7 @@ name = "acir" description = "ACIR is the IR that the VM processes, it is analogous to LLVM IR" # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/acvm-repo/acir_field/Cargo.toml b/noir/noir-repo/acvm-repo/acir_field/Cargo.toml index 4947d0b572a..f8cd0e71ab2 100644 --- a/noir/noir-repo/acvm-repo/acir_field/Cargo.toml +++ b/noir/noir-repo/acvm-repo/acir_field/Cargo.toml @@ -2,7 +2,7 @@ name = "acir_field" description = "The field implementation being used by ACIR." # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/acvm-repo/acvm/Cargo.toml b/noir/noir-repo/acvm-repo/acvm/Cargo.toml index b086e7ac197..3e774f4dbd0 100644 --- a/noir/noir-repo/acvm-repo/acvm/Cargo.toml +++ b/noir/noir-repo/acvm-repo/acvm/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm" description = "The virtual machine that processes ACIR given a backend/proof system." # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/acvm-repo/acvm_js/Cargo.toml b/noir/noir-repo/acvm-repo/acvm_js/Cargo.toml index 7ec7e5a282e..060a507bb9d 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/Cargo.toml +++ b/noir/noir-repo/acvm-repo/acvm_js/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_js" description = "Typescript wrapper around the ACVM allowing execution of ACIR code" # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/acvm-repo/acvm_js/package.json b/noir/noir-repo/acvm-repo/acvm_js/package.json index 03197cc41f8..6d7152e719a 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/package.json +++ b/noir/noir-repo/acvm-repo/acvm_js/package.json @@ -1,6 +1,6 @@ { "name": "@noir-lang/acvm_js", - "version": "0.51.0", + "version": "0.52.0", "publishConfig": { "access": "public" }, diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml b/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml index d99240c5a24..69bdb2fcf81 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml +++ b/noir/noir-repo/acvm-repo/blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_blackbox_solver" description = "A solver for the blackbox functions found in ACIR and Brillig" # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml index bd63f51410a..b4716a0bdda 100644 --- a/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml +++ b/noir/noir-repo/acvm-repo/bn254_blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "bn254_blackbox_solver" description = "Solvers for black box functions which are specific for the bn254 curve" # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/acvm-repo/brillig/Cargo.toml b/noir/noir-repo/acvm-repo/brillig/Cargo.toml index 8fe66201a04..340fb2df29e 100644 --- a/noir/noir-repo/acvm-repo/brillig/Cargo.toml +++ b/noir/noir-repo/acvm-repo/brillig/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig" description = "Brillig is the bytecode ACIR uses for non-determinism." # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/acvm-repo/brillig_vm/Cargo.toml b/noir/noir-repo/acvm-repo/brillig_vm/Cargo.toml index e82274d203d..9f6772c31af 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/Cargo.toml +++ b/noir/noir-repo/acvm-repo/brillig_vm/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig_vm" description = "The virtual machine that processes Brillig bytecode, used to introduce non-determinism to the ACVM" # x-release-please-start-version -version = "0.51.0" +version = "0.52.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs index a6ef0cb2442..75d91716c23 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs @@ -9,7 +9,7 @@ use super::{ }; use acvm::acir::{brillig::MemoryAddress, AcirField}; -pub(crate) const MAX_STACK_SIZE: usize = 32768; +pub(crate) const MAX_STACK_SIZE: usize = 16 * MAX_STACK_FRAME_SIZE; pub(crate) const MAX_STACK_FRAME_SIZE: usize = 2048; pub(crate) const MAX_SCRATCH_SPACE: usize = 64; diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 3c931f8cada..0bf7fe6a146 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -60,9 +60,7 @@ pub(super) fn simplify_call( } else { unreachable!("ICE: Intrinsic::ToRadix return type must be array") }; - let result_array = constant_to_radix(endian, field, 2, limb_count, dfg); - - SimplifyResult::SimplifiedTo(result_array) + constant_to_radix(endian, field, 2, limb_count, dfg) } else { SimplifyResult::None } @@ -79,10 +77,7 @@ pub(super) fn simplify_call( } else { unreachable!("ICE: Intrinsic::ToRadix return type must be array") }; - - let result_array = constant_to_radix(endian, field, radix, limb_count, dfg); - - SimplifyResult::SimplifiedTo(result_array) + constant_to_radix(endian, field, radix, limb_count, dfg) } else { SimplifyResult::None } @@ -606,7 +601,7 @@ fn constant_to_radix( radix: u32, limb_count: u32, dfg: &mut DataFlowGraph, -) -> ValueId { +) -> SimplifyResult { let bit_size = u32::BITS - (radix - 1).leading_zeros(); let radix_big = BigUint::from(radix); assert_eq!(BigUint::from(2u128).pow(bit_size), radix_big, "ICE: Radix must be a power of 2"); @@ -614,14 +609,21 @@ fn constant_to_radix( // Decompose the integer into its radix digits in little endian form. let decomposed_integer = big_integer.to_radix_le(radix); - let mut limbs = vecmap(0..limb_count, |i| match decomposed_integer.get(i as usize) { - Some(digit) => FieldElement::from_be_bytes_reduce(&[*digit]), - None => FieldElement::zero(), - }); - if endian == Endian::Big { - limbs.reverse(); + if limb_count < decomposed_integer.len() as u32 { + // `field` cannot be represented as `limb_count` bits. + // defer error to acir_gen. + SimplifyResult::None + } else { + let mut limbs = vecmap(0..limb_count, |i| match decomposed_integer.get(i as usize) { + Some(digit) => FieldElement::from_be_bytes_reduce(&[*digit]), + None => FieldElement::zero(), + }); + if endian == Endian::Big { + limbs.reverse(); + } + let result_array = make_constant_array(dfg, limbs, Type::unsigned(bit_size)); + SimplifyResult::SimplifiedTo(result_array) } - make_constant_array(dfg, limbs, Type::unsigned(bit_size)) } fn to_u8_vec(dfg: &DataFlowGraph, values: im::Vector>) -> Vec { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index 9086011251a..2eb0f2eda0f 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -413,13 +413,14 @@ impl InlineContext { ) -> Vec { self.recursion_level += 1; + let source_function = &ssa.functions[&id]; + if self.recursion_level > RECURSION_LIMIT { panic!( - "Attempted to recur more than {RECURSION_LIMIT} times during function inlining." + "Attempted to recur more than {RECURSION_LIMIT} times during inlining function '{}': {}", source_function.name(), source_function ); } - let source_function = &ssa.functions[&id]; let mut context = PerFunctionContext::new(self, source_function); let parameters = source_function.parameters(); @@ -1091,6 +1092,30 @@ mod test { assert_eq!(main.reachable_blocks().len(), 4); } + #[test] + #[should_panic( + expected = "Attempted to recur more than 1000 times during inlining function 'main': acir(inline) fn main f0 {" + )] + fn unconditional_recursion() { + // fn main f1 { + // b0(): + // call f1() + // return + // } + let main_id = Id::test_new(0); + let mut builder = FunctionBuilder::new("main".into(), main_id); + + let main = builder.import_function(main_id); + let results = builder.insert_call(main, Vec::new(), vec![]).to_vec(); + builder.terminate_with_return(results); + + let ssa = builder.finish(); + assert_eq!(ssa.functions.len(), 1); + + let inlined = ssa.inline_functions(i64::MAX); + assert_eq!(inlined.functions.len(), 0); + } + #[test] fn inliner_disabled() { // brillig fn foo { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 165e0e36b71..9e3dd3e5a30 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -61,38 +61,6 @@ //! SSA optimization pipeline, although it will be more successful the simpler the program's CFG is. //! This pass is currently performed several times to enable other passes - most notably being //! performed before loop unrolling to try to allow for mutable variables used for loop indices. -//! -//! As stated above, the algorithm above can sometimes miss known references. -//! This most commonly occurs in the case of loops, where we may have allocations preceding a loop that are known, -//! but the loop body's blocks are predecessors to the loop header block, causing those known allocations to be marked unknown. -//! In certain cases we may be able to remove these allocations that precede a loop. -//! For example, if a reference is not stored to again in the loop we should be able to remove that store which precedes the loop. -//! -//! To handle cases such as the one laid out above, we maintain some extra state per function, -//! that we will analyze after the initial run through all of the blocks. -//! We refer to this as the "function cleanup" and it requires having already iterated through all blocks. -//! -//! The state contains the following: -//! - For each load address we store the number of loads from a given address, -//! the last load instruction from a given address across all blocks, and the respective block id of that instruction. -//! - A mapping of each load result to its number of uses, the load instruction that produced the given result, and the respective block id of that instruction. -//! - A set of the references and their aliases passed as an argument to a call. -//! - Maps the references which have been aliased to the instructions that aliased that reference. -//! - As we go through each instruction, if a load result has been used we increment its usage counter. -//! Upon removing an instruction, we decrement the load result counter. -//! After analyzing all of a function's blocks we can analyze the per function state: -//! - If we find that a load result's usage counter equals zero, we can remove that load. -//! - We can then remove a store if the following conditions are met: -//! - All loads to a given address have been removed -//! - None of the aliases of a reference are used in any of the following: -//! - Block parameters, function parameters, call arguments, terminator arguments -//! - The store address is not aliased. -//! - If a store is in a return block, we can have special handling that only checks if there is a load after -//! that store in the return block. In the case of a return block, even if there are other loads -//! in preceding blocks we can safely remove those stores. -//! - To further catch any stores to references which are never loaded, we can count the number of stores -//! that were removed in the previous step. If there is only a single store leftover, we can safely map -//! the value of this final store to any loads of that store. mod alias_set; mod block; @@ -125,7 +93,6 @@ impl Ssa { for function in self.functions.values_mut() { function.mem2reg(); } - self } } @@ -155,10 +122,7 @@ struct PerFunctionContext<'f> { /// Track a value's last load across all blocks. /// If a value is not used in anymore loads we can remove the last store to that value. - last_loads: HashMap, - - /// Track whether a load result was used across all blocks. - load_results: HashMap, + last_loads: HashMap, /// Track whether a reference was passed into another entry point /// This is needed to determine whether we can remove a store. @@ -168,41 +132,6 @@ struct PerFunctionContext<'f> { /// instruction that aliased that reference. /// If that store has been set for removal, we can also remove this instruction. aliased_references: HashMap>, - - // The index of the last load instruction in a given block - return_block_load_locations: HashMap<(ValueId, BasicBlockId), usize>, -} - -#[derive(Debug, Clone)] -struct PerFuncLastLoadContext { - /// Reference counter that keeps track of how many times we loaded from a given address - num_loads: u32, - /// Last load instruction from a given address - load_instruction: InstructionId, - /// Block of the last load instruction - block_id: BasicBlockId, -} - -impl PerFuncLastLoadContext { - fn new(load_instruction: InstructionId, block_id: BasicBlockId, num_loads: u32) -> Self { - Self { num_loads, load_instruction, block_id } - } -} - -#[derive(Debug, Clone)] -struct PerFuncLoadResultContext { - /// Reference counter that keeps track of how many times a load was used in other instructions - uses: u32, - /// Load instruction that produced a given load result - load_instruction: InstructionId, - /// Block of the load instruction that produced a given result - block_id: BasicBlockId, -} - -impl PerFuncLoadResultContext { - fn new(load_instruction: InstructionId, block_id: BasicBlockId) -> Self { - Self { uses: 0, load_instruction, block_id } - } } impl<'f> PerFunctionContext<'f> { @@ -217,10 +146,8 @@ impl<'f> PerFunctionContext<'f> { blocks: BTreeMap::new(), instructions_to_remove: HashSet::default(), last_loads: HashMap::default(), - load_results: HashMap::default(), calls_reference_input: HashSet::default(), aliased_references: HashMap::default(), - return_block_load_locations: HashMap::default(), } } @@ -238,7 +165,110 @@ impl<'f> PerFunctionContext<'f> { self.analyze_block(block, references); } - self.cleanup_function(); + let mut all_terminator_values = HashSet::default(); + let mut per_func_block_params: HashSet = HashSet::default(); + for (block_id, _) in self.blocks.iter() { + let block_params = self.inserter.function.dfg.block_parameters(*block_id); + per_func_block_params.extend(block_params.iter()); + let terminator = self.inserter.function.dfg[*block_id].unwrap_terminator(); + terminator.for_each_value(|value| { + self.recursively_add_values(value, &mut all_terminator_values); + }); + } + + // If we never load from an address within a function we can remove all stores to that address. + // This rule does not apply to reference parameters, which we must also check for before removing these stores. + for (_, block) in self.blocks.iter() { + for (store_address, store_instruction) in block.last_stores.iter() { + let store_alias_used = self.is_store_alias_used( + store_address, + block, + &all_terminator_values, + &per_func_block_params, + ); + + let is_dereference = block + .expressions + .get(store_address) + .map_or(false, |expression| matches!(expression, Expression::Dereference(_))); + + if self.last_loads.get(store_address).is_none() + && !store_alias_used + && !is_dereference + { + self.instructions_to_remove.insert(*store_instruction); + } + } + } + } + + // Extra checks on where a reference can be used aside a load instruction. + // Even if all loads to a reference have been removed we need to make sure that + // an allocation did not come from an entry point or was passed to an entry point. + fn is_store_alias_used( + &self, + store_address: &ValueId, + block: &Block, + all_terminator_values: &HashSet, + per_func_block_params: &HashSet, + ) -> bool { + let func_params = self.inserter.function.parameters(); + let reference_parameters = func_params + .iter() + .filter(|param| self.inserter.function.dfg.value_is_reference(**param)) + .collect::>(); + + let mut store_alias_used = false; + if let Some(expression) = block.expressions.get(store_address) { + if let Some(aliases) = block.aliases.get(expression) { + let allocation_aliases_parameter = + aliases.any(|alias| reference_parameters.contains(&alias)); + if allocation_aliases_parameter == Some(true) { + store_alias_used = true; + } + + let allocation_aliases_parameter = + aliases.any(|alias| per_func_block_params.contains(&alias)); + if allocation_aliases_parameter == Some(true) { + store_alias_used = true; + } + + let allocation_aliases_parameter = + aliases.any(|alias| self.calls_reference_input.contains(&alias)); + if allocation_aliases_parameter == Some(true) { + store_alias_used = true; + } + + let allocation_aliases_parameter = + aliases.any(|alias| all_terminator_values.contains(&alias)); + if allocation_aliases_parameter == Some(true) { + store_alias_used = true; + } + + let allocation_aliases_parameter = aliases.any(|alias| { + if let Some(alias_instructions) = self.aliased_references.get(&alias) { + self.instructions_to_remove.is_disjoint(alias_instructions) + } else { + false + } + }); + + if allocation_aliases_parameter == Some(true) { + store_alias_used = true; + } + } + } + + store_alias_used + } + + fn recursively_add_values(&self, value: ValueId, set: &mut HashSet) { + set.insert(value); + if let Some((elements, _)) = self.inserter.function.dfg.get_array_constant(value) { + for array_element in elements { + self.recursively_add_values(array_element, set); + } + } } /// The value of each reference at the start of the given block is the unification @@ -294,8 +324,6 @@ impl<'f> PerFunctionContext<'f> { .filter(|param| self.inserter.function.dfg.value_is_reference(**param)) .collect::>(); - // Must collect here as we are immutably borrowing `self` to fetch the reference parameters - let mut values_to_reduce_counts = Vec::new(); for (allocation, instruction) in &references.last_stores { if let Some(expression) = references.expressions.get(allocation) { if let Some(aliases) = references.aliases.get(expression) { @@ -305,27 +333,10 @@ impl<'f> PerFunctionContext<'f> { // If `allocation_aliases_parameter` is known to be false if allocation_aliases_parameter == Some(false) { self.instructions_to_remove.insert(*instruction); - values_to_reduce_counts.push(*allocation); } } } } - - for value in values_to_reduce_counts { - self.reduce_load_result_count(value); - } - } - - fn increase_load_ref_counts(&mut self, value: ValueId) { - if let Some(context) = self.load_results.get_mut(&value) { - context.uses += 1; - } - let array_const = self.inserter.function.dfg.get_array_constant(value); - if let Some((values, _)) = array_const { - for array_value in values { - self.increase_load_ref_counts(array_value); - } - } } fn analyze_instruction( @@ -343,16 +354,6 @@ impl<'f> PerFunctionContext<'f> { return; } - let mut collect_values = Vec::new(); - // Track whether any load results were used in the instruction - self.inserter.function.dfg[instruction].for_each_value(|value| { - collect_values.push(value); - }); - - for value in collect_values { - self.increase_load_ref_counts(value); - } - match &self.inserter.function.dfg[instruction] { Instruction::Load { address } => { let address = self.inserter.function.dfg.resolve(*address); @@ -362,43 +363,13 @@ impl<'f> PerFunctionContext<'f> { // If the load is known, replace it with the known value and remove the load if let Some(value) = references.get_known_value(address) { + let result = self.inserter.function.dfg.instruction_results(instruction)[0]; self.inserter.map_value(result, value); self.instructions_to_remove.insert(instruction); } else { references.mark_value_used(address, self.inserter.function); - let expression = - references.expressions.entry(result).or_insert(Expression::Other(result)); - // Make sure this load result is marked an alias to itself - if let Some(aliases) = references.aliases.get_mut(expression) { - // If we have an alias set, add to the set - aliases.insert(result); - } else { - // Otherwise, create a new alias set containing just the load result - references - .aliases - .insert(Expression::Other(result), AliasSet::known(result)); - } - // Mark that we know a load result is equivalent to the address of a load. - references.set_known_value(result, address); - - self.load_results - .insert(result, PerFuncLoadResultContext::new(instruction, block_id)); - - let num_loads = - self.last_loads.get(&address).map_or(1, |context| context.num_loads + 1); - let last_load = PerFuncLastLoadContext::new(instruction, block_id, num_loads); - self.last_loads.insert(address, last_load); - - // If we are in a return block we want to save the last location of a load - let terminator = self.inserter.function.dfg[block_id].unwrap_terminator(); - let is_return = matches!(terminator, TerminatorInstruction::Return { .. }); - if is_return { - let instruction_index = - self.inserter.function.dfg[block_id].instructions().len(); - self.return_block_load_locations - .insert((address, block_id), instruction_index); - } + self.last_loads.insert(address, (instruction, block_id)); } } Instruction::Store { address, value } => { @@ -407,31 +378,10 @@ impl<'f> PerFunctionContext<'f> { self.check_array_aliasing(references, value); - // If there was another store to this address without any (unremoved) loads or + // If there was another store to this instruction without any (unremoved) loads or // function calls in-between, we can remove the previous store. if let Some(last_store) = references.last_stores.get(&address) { self.instructions_to_remove.insert(*last_store); - let Instruction::Store { address, value } = - self.inserter.function.dfg[*last_store] - else { - panic!("Should have a store instruction here"); - }; - self.reduce_load_result_count(address); - self.reduce_load_result_count(value); - } - - let known_value = references.get_known_value(value); - if let Some(known_value) = known_value { - let known_value_is_address = known_value == address; - if known_value_is_address { - self.instructions_to_remove.insert(instruction); - self.reduce_load_result_count(address); - self.reduce_load_result_count(value); - } else { - references.last_stores.insert(address, instruction); - } - } else { - references.last_stores.insert(address, instruction); } if self.inserter.function.dfg.value_is_reference(value) { @@ -448,6 +398,7 @@ impl<'f> PerFunctionContext<'f> { } references.set_known_value(address, value); + references.last_stores.insert(address, instruction); } Instruction::Allocate => { // Register the new reference @@ -571,26 +522,14 @@ impl<'f> PerFunctionContext<'f> { } fn update_data_bus(&mut self) { - self.inserter.map_data_bus_in_place(); + let databus = self.inserter.function.dfg.data_bus.clone(); + self.inserter.function.dfg.data_bus = databus.map_values(|t| self.inserter.resolve(t)); } fn handle_terminator(&mut self, block: BasicBlockId, references: &mut Block) { self.inserter.map_terminator_in_place(block); - let terminator: &TerminatorInstruction = - self.inserter.function.dfg[block].unwrap_terminator(); - - let mut collect_values = Vec::new(); - terminator.for_each_value(|value| { - collect_values.push(value); - }); - - let terminator = terminator.clone(); - for value in collect_values.iter() { - self.increase_load_ref_counts(*value); - } - - match &terminator { + match self.inserter.function.dfg[block].unwrap_terminator() { TerminatorInstruction::JmpIf { .. } => (), // Nothing to do TerminatorInstruction::Jmp { destination, arguments, .. } => { let destination_parameters = self.inserter.function.dfg[*destination].parameters(); @@ -618,311 +557,6 @@ impl<'f> PerFunctionContext<'f> { } } } - - fn reduce_load_result_count(&mut self, value: ValueId) { - if let Some(context) = self.load_results.get_mut(&value) { - // TODO this was saturating https://github.com/noir-lang/noir/issues/6124 - context.uses = context.uses.wrapping_sub(1); - } - } - - fn recursively_add_values(&self, value: ValueId, set: &mut HashSet) { - set.insert(value); - if let Some((elements, _)) = self.inserter.function.dfg.get_array_constant(value) { - for array_element in elements { - self.recursively_add_values(array_element, set); - } - } - } - - /// The mem2reg pass is sometimes unable to determine certain known values - /// when iterating over a function's block in reverse post order. - /// We collect state about any final loads and stores to a given address during the initial mem2reg pass. - /// We can then utilize this state to clean up any loads and stores that may have been missed. - fn cleanup_function(&mut self) { - // Removing remaining unused loads during mem2reg can help expose removable stores that the initial - // mem2reg pass deemed we could not remove due to the existence of those unused loads. - let removed_loads = self.remove_unused_loads(); - let remaining_last_stores = self.remove_unloaded_last_stores(&removed_loads); - let stores_were_removed = - self.remove_remaining_last_stores(&removed_loads, &remaining_last_stores); - - // When removing some last loads with the last stores we will map the load result to the store value. - // We need to then map all the instructions again as we do not know which instructions are reliant on the load result. - if stores_were_removed { - let mut block_order = PostOrder::with_function(self.inserter.function).into_vec(); - block_order.reverse(); - for block in block_order { - let instructions = self.inserter.function.dfg[block].take_instructions(); - for instruction in instructions { - if !self.instructions_to_remove.contains(&instruction) { - self.inserter.push_instruction(instruction, block); - } - } - self.inserter.map_terminator_in_place(block); - } - } - } - - /// Cleanup remaining loads across the entire function - /// Remove any loads whose reference counter is zero. - /// Returns a map of the removed load address to the number of load instructions removed for that address - fn remove_unused_loads(&mut self) -> HashMap { - let mut removed_loads = HashMap::default(); - for (_, PerFuncLoadResultContext { uses, load_instruction, block_id, .. }) in - self.load_results.iter() - { - let Instruction::Load { address } = self.inserter.function.dfg[*load_instruction] - else { - unreachable!("Should only have a load instruction here"); - }; - // If the load result's counter is equal to zero we can safely remove that load instruction. - if *uses == 0 { - self.return_block_load_locations.remove(&(address, *block_id)); - - removed_loads.entry(address).and_modify(|counter| *counter += 1).or_insert(1); - self.instructions_to_remove.insert(*load_instruction); - } - } - removed_loads - } - - fn recursively_check_address_in_terminator( - &self, - return_value: ValueId, - store_address: ValueId, - is_return_value: &mut bool, - ) { - *is_return_value = return_value == store_address || *is_return_value; - let array_const = self.inserter.function.dfg.get_array_constant(return_value); - if let Some((values, _)) = array_const { - for array_value in values { - self.recursively_check_address_in_terminator( - array_value, - store_address, - is_return_value, - ); - } - } - } - - /// Cleanup remaining stores across the entire function. - /// If we never load from an address within a function we can remove all stores to that address. - /// This rule does not apply to reference parameters, which we must also check for before removing these stores. - /// Returns a map of any remaining stores which may still have loads in use. - fn remove_unloaded_last_stores( - &mut self, - removed_loads: &HashMap, - ) -> HashMap { - let mut all_terminator_values = HashSet::default(); - let mut per_func_block_params: HashSet = HashSet::default(); - for (block_id, _) in self.blocks.iter() { - let block_params = self.inserter.function.dfg.block_parameters(*block_id); - per_func_block_params.extend(block_params.iter()); - - let terminator = self.inserter.function.dfg[*block_id].unwrap_terminator(); - terminator.for_each_value(|value| { - self.recursively_add_values(value, &mut all_terminator_values); - }); - } - - let mut remaining_last_stores: HashMap = HashMap::default(); - for (block_id, block) in self.blocks.iter() { - for (store_address, store_instruction) in block.last_stores.iter() { - if self.instructions_to_remove.contains(store_instruction) { - continue; - } - - let all_loads_removed = self.all_loads_removed_for_address( - store_address, - *store_instruction, - *block_id, - removed_loads, - ); - - let store_alias_used = self.is_store_alias_used( - store_address, - block, - &all_terminator_values, - &per_func_block_params, - ); - - if all_loads_removed && !store_alias_used { - self.instructions_to_remove.insert(*store_instruction); - if let Some((_, counter)) = remaining_last_stores.get_mut(store_address) { - // TODO this was saturating https://github.com/noir-lang/noir/issues/6124 - *counter = counter.wrapping_sub(1); - } - } else if let Some((_, counter)) = remaining_last_stores.get_mut(store_address) { - *counter += 1; - } else { - remaining_last_stores.insert(*store_address, (*store_instruction, 1)); - } - } - } - remaining_last_stores - } - - fn all_loads_removed_for_address( - &self, - store_address: &ValueId, - store_instruction: InstructionId, - block_id: BasicBlockId, - removed_loads: &HashMap, - ) -> bool { - let terminator = self.inserter.function.dfg[block_id].unwrap_terminator(); - let is_return = matches!(terminator, TerminatorInstruction::Return { .. }); - // Determine whether any loads that reference this store address - // have been removed while cleaning up unused loads. - if is_return { - // If we are in a return terminator, and the last loads of a reference - // come before a store to that reference, we can safely remove that store. - let store_after_load = if let Some(max_load_index) = - self.return_block_load_locations.get(&(*store_address, block_id)) - { - let store_index = self.inserter.function.dfg[block_id] - .instructions() - .iter() - .position(|id| *id == store_instruction) - .expect("Store instruction should exist in the return block"); - store_index > *max_load_index - } else { - // Otherwise there is no load in this block - true - }; - store_after_load - } else if let (Some(context), Some(loads_removed_counter)) = - (self.last_loads.get(store_address), removed_loads.get(store_address)) - { - // `last_loads` contains the total number of loads for a given load address - // If the number of removed loads for a given address is equal to the total number of loads for that address, - // we know we can safely remove any stores to that load address. - context.num_loads == *loads_removed_counter - } else { - self.last_loads.get(store_address).is_none() - } - } - - // Extra checks on where a reference can be used aside a load instruction. - // Even if all loads to a reference have been removed we need to make sure that - // an allocation did not come from an entry point or was passed to an entry point. - fn is_store_alias_used( - &self, - store_address: &ValueId, - block: &Block, - all_terminator_values: &HashSet, - per_func_block_params: &HashSet, - ) -> bool { - let func_params = self.inserter.function.parameters(); - let reference_parameters = func_params - .iter() - .filter(|param| self.inserter.function.dfg.value_is_reference(**param)) - .collect::>(); - - let mut store_alias_used = false; - if let Some(expression) = block.expressions.get(store_address) { - if let Some(aliases) = block.aliases.get(expression) { - let allocation_aliases_parameter = - aliases.any(|alias| reference_parameters.contains(&alias)); - if allocation_aliases_parameter == Some(true) { - store_alias_used = true; - } - - let allocation_aliases_parameter = - aliases.any(|alias| per_func_block_params.contains(&alias)); - if allocation_aliases_parameter == Some(true) { - store_alias_used = true; - } - - let allocation_aliases_parameter = - aliases.any(|alias| self.calls_reference_input.contains(&alias)); - if allocation_aliases_parameter == Some(true) { - store_alias_used = true; - } - - let allocation_aliases_parameter = - aliases.any(|alias| all_terminator_values.contains(&alias)); - if allocation_aliases_parameter == Some(true) { - store_alias_used = true; - } - - let allocation_aliases_parameter = aliases.any(|alias| { - if let Some(alias_instructions) = self.aliased_references.get(&alias) { - self.instructions_to_remove.is_disjoint(alias_instructions) - } else { - false - } - }); - if allocation_aliases_parameter == Some(true) { - store_alias_used = true; - } - } - } - - store_alias_used - } - - /// Check if any remaining last stores are only used in a single load - /// Returns true if any stores were removed. - fn remove_remaining_last_stores( - &mut self, - removed_loads: &HashMap, - remaining_last_stores: &HashMap, - ) -> bool { - let mut stores_were_removed = false; - // Filter out any still in use load results and any load results that do not contain addresses from the remaining last stores - self.load_results.retain(|_, PerFuncLoadResultContext { load_instruction, uses, .. }| { - let Instruction::Load { address } = self.inserter.function.dfg[*load_instruction] - else { - unreachable!("Should only have a load instruction here"); - }; - remaining_last_stores.contains_key(&address) && *uses > 0 - }); - - for (store_address, (store_instruction, store_counter)) in remaining_last_stores { - let Instruction::Store { value, .. } = self.inserter.function.dfg[*store_instruction] - else { - unreachable!("Should only have a store instruction"); - }; - - if let (Some(context), Some(loads_removed_counter)) = - (self.last_loads.get(store_address), removed_loads.get(store_address)) - { - assert!( - context.num_loads >= *loads_removed_counter, - "The number of loads removed should not be more than all loads" - ); - } - - // We only want to remove last stores referencing a single address. - if *store_counter != 0 { - continue; - } - - self.instructions_to_remove.insert(*store_instruction); - - // Map any remaining load results to the value from the removed store - for (result, context) in self.load_results.iter() { - let Instruction::Load { address } = - self.inserter.function.dfg[context.load_instruction] - else { - unreachable!("Should only have a load instruction here"); - }; - if address != *store_address { - continue; - } - - // Map the load result to its respective store value - // We will have to map all instructions following this method - // as we do not know what instructions depend upon this result - self.inserter.map_value(*result, value); - self.instructions_to_remove.insert(context.load_instruction); - - stores_were_removed = true; - } - } - stores_were_removed - } } #[cfg(test)] @@ -1202,6 +836,7 @@ mod tests { // acir fn main f0 { // b0(): // v9 = allocate + // store Field 0 at v9 // v10 = allocate // jmp b1() // b1(): @@ -1209,6 +844,7 @@ mod tests { // } let ssa = ssa.mem2reg(); println!("{}", ssa); + let main = ssa.main(); assert_eq!(main.reachable_blocks().len(), 2); @@ -1216,12 +852,14 @@ mod tests { assert_eq!(count_loads(main.entry_block(), &main.dfg), 0); assert_eq!(count_loads(b1, &main.dfg), 0); - // All stores should be removed. + // The first store is not removed as it is used as a nested reference in another store. + // We would need to track whether the store where `v9` is the store value gets removed to know whether + // to remove it. + assert_eq!(count_stores(main.entry_block(), &main.dfg), 1); // The first store in b1 is removed since there is another store to the same reference // in the same block, and the store is not needed before the later store. // The rest of the stores are also removed as no loads are done within any blocks // to the stored values. - assert_eq!(count_stores(main.entry_block(), &main.dfg), 0); assert_eq!(count_stores(b1, &main.dfg), 0); let b1_instructions = main.dfg[b1].instructions(); @@ -1230,163 +868,6 @@ mod tests { assert_eq!(b1_instructions.len(), 0); } - #[test] - fn remove_unused_loads_and_stores() { - // acir(inline) fn main f0 { - // b0(): - // v0 = allocate - // store Field 1 at v0 - // v2 = allocate - // store Field 1 at v2 - // v4 = allocate - // store u1 0 at v4 - // v5 = allocate - // store u1 0 at v5 - // v6 = allocate - // store u1 0 at v6 - // jmp b1(u1 0) - // b1(v7: u32): - // v9 = eq v7, u32 0 - // jmpif v9 then: b3, else: b2 - // b3(): - // v20 = load v0 - // v21 = load v2 - // v22 = load v4 - // v23 = load v5 - // v24 = load v6 - // constrain v20 == Field 1 - // v25 = eq v21, Field 1 - // constrain v21 == Field 1 - // v26 = eq v7, u32 0 - // jmp b1(v26) - // b2(): - // v10 = load v0 - // v11 = load v2 - // v12 = load v4 - // v13 = load v5 - // v14 = load v6 - // store Field 1 at v0 - // store Field 1 at v2 - // store v12 at v4 - // store v13 at v5 - // store v14 at v6 - // v15 = load v0 - // v16 = load v2 - // v17 = load v4 - // v18 = load v5 - // v19 = load v6 - // constrain v15 == Field 1 - // return v16 - // } - let main_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("main".into(), main_id); - - let v0 = builder.insert_allocate(Type::field()); - let one = builder.numeric_constant(1u128, Type::field()); - builder.insert_store(v0, one); - - let v2 = builder.insert_allocate(Type::field()); - builder.insert_store(v2, one); - - let zero_bool = builder.numeric_constant(0u128, Type::bool()); - let v4 = builder.insert_allocate(Type::bool()); - builder.insert_store(v4, zero_bool); - - let v6 = builder.insert_allocate(Type::bool()); - builder.insert_store(v6, zero_bool); - - let v8 = builder.insert_allocate(Type::bool()); - builder.insert_store(v8, zero_bool); - - let b1 = builder.insert_block(); - builder.terminate_with_jmp(b1, vec![zero_bool]); - - builder.switch_to_block(b1); - - let v7 = builder.add_block_parameter(b1, Type::unsigned(32)); - let zero_u32 = builder.numeric_constant(0u128, Type::unsigned(32)); - let is_zero = builder.insert_binary(v7, BinaryOp::Eq, zero_u32); - - let b2 = builder.insert_block(); - let b3 = builder.insert_block(); - builder.terminate_with_jmpif(is_zero, b3, b2); - - builder.switch_to_block(b2); - - let _ = builder.insert_load(v0, Type::field()); - let _ = builder.insert_load(v2, Type::field()); - let v12 = builder.insert_load(v4, Type::bool()); - let v13 = builder.insert_load(v6, Type::bool()); - let v14 = builder.insert_load(v8, Type::bool()); - - builder.insert_store(v0, one); - builder.insert_store(v2, one); - builder.insert_store(v4, v12); - builder.insert_store(v6, v13); - builder.insert_store(v8, v14); - - let v15 = builder.insert_load(v0, Type::field()); - // Insert unused loads - let v16 = builder.insert_load(v2, Type::field()); - let _ = builder.insert_load(v4, Type::bool()); - let _ = builder.insert_load(v6, Type::bool()); - let _ = builder.insert_load(v8, Type::bool()); - - builder.insert_constrain(v15, one, None); - builder.terminate_with_return(vec![v16]); - - builder.switch_to_block(b3); - - let v26 = builder.insert_load(v0, Type::field()); - // Insert unused loads - let v27 = builder.insert_load(v2, Type::field()); - let _ = builder.insert_load(v4, Type::bool()); - let _ = builder.insert_load(v6, Type::bool()); - let _ = builder.insert_load(v8, Type::bool()); - - builder.insert_constrain(v26, one, None); - let _ = builder.insert_binary(v27, BinaryOp::Eq, one); - builder.insert_constrain(v27, one, None); - let one_u32 = builder.numeric_constant(0u128, Type::unsigned(32)); - let plus_one = builder.insert_binary(v7, BinaryOp::Eq, one_u32); - builder.terminate_with_jmp(b1, vec![plus_one]); - - let ssa = builder.finish(); - - // Expected result: - // acir(inline) fn main f0 { - // b0(): - // v27 = allocate - // v28 = allocate - // v29 = allocate - // v30 = allocate - // v31 = allocate - // jmp b1(u1 0) - // b1(v7: u32): - // v32 = eq v7, u32 0 - // jmpif v32 then: b3, else: b2 - // b3(): - // v49 = eq v7, u32 0 - // jmp b1(v49) - // b2(): - // return Field 1 - // } - let ssa = ssa.mem2reg(); - - let main = ssa.main(); - assert_eq!(main.reachable_blocks().len(), 4); - - // All loads should be removed - assert_eq!(count_loads(b2, &main.dfg), 0); - assert_eq!(count_loads(b3, &main.dfg), 0); - - // All stores should be removed - assert_eq!(count_stores(main.entry_block(), &main.dfg), 0); - assert_eq!(count_stores(b2, &main.dfg), 0); - // Should only have one instruction in b3 - assert_eq!(main.dfg[b3].instructions().len(), 1); - } - #[test] fn keep_store_to_alias_in_loop_block() { // This test makes sure the instruction `store Field 2 at v5` in b2 remains after mem2reg. @@ -1480,240 +961,4 @@ mod tests { assert_eq!(count_loads(b2, &main.dfg), 1); assert_eq!(count_loads(b3, &main.dfg), 3); } - - #[test] - fn accurate_tracking_of_load_results() { - // acir(inline) fn main f0 { - // b0(): - // v0 = allocate - // store Field 5 at v0 - // v2 = allocate - // store u32 10 at v2 - // v4 = load v0 - // v5 = load v2 - // v6 = allocate - // store v4 at v6 - // v7 = allocate - // store v5 at v7 - // v8 = load v6 - // v9 = load v7 - // v10 = load v6 - // v11 = load v7 - // v12 = allocate - // store Field 0 at v12 - // v15 = eq v11, u32 0 - // jmpif v15 then: b1, else: b2 - // b1(): - // v16 = load v12 - // v17 = add v16, v8 - // store v17 at v12 - // jmp b2() - // b2(): - // v18 = load v12 - // return [v18] - // } - let main_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("main".into(), main_id); - - let v0 = builder.insert_allocate(Type::field()); - let five = builder.numeric_constant(5u128, Type::field()); - builder.insert_store(v0, five); - - let v2 = builder.insert_allocate(Type::unsigned(32)); - let ten = builder.numeric_constant(10u128, Type::unsigned(32)); - builder.insert_store(v2, ten); - - let v4 = builder.insert_load(v0, Type::field()); - let v5 = builder.insert_load(v2, Type::unsigned(32)); - let v4_type = builder.current_function.dfg.type_of_value(v4); - let v5_type = builder.current_function.dfg.type_of_value(v5); - - let v6 = builder.insert_allocate(Type::field()); - builder.insert_store(v6, v4); - let v7 = builder.insert_allocate(Type::unsigned(32)); - builder.insert_store(v7, v5); - - let v8 = builder.insert_load(v6, v4_type.clone()); - let _v9 = builder.insert_load(v7, v5_type.clone()); - - let _v10 = builder.insert_load(v6, v4_type); - let v11 = builder.insert_load(v7, v5_type); - - let v12 = builder.insert_allocate(Type::field()); - let zero = builder.numeric_constant(0u128, Type::field()); - builder.insert_store(v12, zero); - - let zero_u32 = builder.numeric_constant(0u128, Type::unsigned(32)); - let v15 = builder.insert_binary(v11, BinaryOp::Eq, zero_u32); - - let b1 = builder.insert_block(); - let b2 = builder.insert_block(); - builder.terminate_with_jmpif(v15, b1, b2); - - builder.switch_to_block(b1); - - let v16 = builder.insert_load(v12, Type::field()); - let v17 = builder.insert_binary(v16, BinaryOp::Add, v8); - builder.insert_store(v12, v17); - - builder.terminate_with_jmp(b2, vec![]); - - builder.switch_to_block(b2); - let v18 = builder.insert_load(v12, Type::field()); - - // Include the load result as part of an array constant to check that we are accounting for arrays - // when updating the reference counts of load results. - // - // If we were not accounting for arrays appropriately, the load of v18 would be removed. - // If v18 is the last load of a reference and is inadvertently removed, - // any stores to v12 will then be potentially removed as well and the program will be broken. - let return_array = - builder.array_constant(vector![v18], Type::Array(Arc::new(vec![Type::field()]), 1)); - builder.terminate_with_return(vec![return_array]); - - let ssa = builder.finish(); - - // Expected result: - // acir(inline) fn main f0 { - // b0(): - // v20 = allocate - // v21 = allocate - // v24 = allocate - // v25 = allocate - // v30 = allocate - // store Field 0 at v30 - // jmpif u1 0 then: b1, else: b2 - // b1(): - // store Field 5 at v30 - // jmp b2() - // b2(): - // v33 = load v30 - // return [v33] - // } - let ssa = ssa.mem2reg(); - - let main = ssa.main(); - assert_eq!(main.reachable_blocks().len(), 3); - - // A single store from the entry block should remain. - // If we are not appropriately handling unused stores across a function, - // we would expect all five stores from the original SSA to remain. - assert_eq!(count_stores(main.entry_block(), &main.dfg), 1); - // The store from the conditional block should remain, - // as it is loaded from in a successor block and used in the return terminator. - assert_eq!(count_stores(b1, &main.dfg), 1); - - assert_eq!(count_loads(main.entry_block(), &main.dfg), 0); - assert_eq!(count_loads(b1, &main.dfg), 0); - assert_eq!(count_loads(b2, &main.dfg), 1); - } - - #[test] - fn keep_unused_store_only_used_as_an_alias_across_blocks() { - // acir(inline) fn main f0 { - // b0(v0: u32): - // v1 = allocate - // store u32 0 at v1 - // v3 = allocate - // store v1 at v3 - // v4 = allocate - // store v0 at v4 - // v5 = allocate - // store v4 at v5 - // jmp b1(u32 0) - // b1(v6: u32): - // v7 = eq v6, u32 0 - // jmpif v7 then: b2, else: b3 - // b2(): - // v8 = load v5 - // store v8 at u2 2 - // v11 = add v6, u32 1 - // jmp b1(v11) - // b3(): - // v12 = load v4 - // constrain v12 == u2 2 - // v13 = load v5 - // v14 = load v13 - // constrain v14 == u2 2 - // v15 = load v3 - // v16 = load v15 - // v18 = lt v16, u32 4 - // constrain v18 == u32 1 - // return - // } - let main_id = Id::test_new(0); - let mut builder = FunctionBuilder::new("main".into(), main_id); - - let v0 = builder.add_parameter(Type::unsigned(32)); - - let v1 = builder.insert_allocate(Type::unsigned(32)); - let zero = builder.numeric_constant(0u128, Type::unsigned(32)); - builder.insert_store(v1, zero); - - let v1_type = builder.type_of_value(v1); - let v3 = builder.insert_allocate(v1_type.clone()); - builder.insert_store(v3, v1); - - let v4 = builder.insert_allocate(Type::unsigned(32)); - builder.insert_store(v4, v0); - - let v5 = builder.insert_allocate(Type::Reference(Arc::new(Type::unsigned(32)))); - builder.insert_store(v5, v4); - - let b1 = builder.insert_block(); - builder.terminate_with_jmp(b1, vec![zero]); - builder.switch_to_block(b1); - - let v6 = builder.add_block_parameter(b1, Type::unsigned(32)); - let is_zero = builder.insert_binary(v6, BinaryOp::Eq, zero); - - let b2 = builder.insert_block(); - let b3 = builder.insert_block(); - builder.terminate_with_jmpif(is_zero, b2, b3); - - builder.switch_to_block(b2); - let v4_type = builder.type_of_value(v4); - // let v0_type = builder.type_of_value(v4); - let v8 = builder.insert_load(v5, v4_type); - let two = builder.numeric_constant(2u128, Type::unsigned(2)); - builder.insert_store(v8, two); - let one = builder.numeric_constant(1u128, Type::unsigned(32)); - let v11 = builder.insert_binary(v6, BinaryOp::Add, one); - builder.terminate_with_jmp(b1, vec![v11]); - - builder.switch_to_block(b3); - - let v12 = builder.insert_load(v4, Type::unsigned(32)); - builder.insert_constrain(v12, two, None); - - let v3_type = builder.type_of_value(v3); - let v13 = builder.insert_load(v5, v3_type); - let v14 = builder.insert_load(v13, Type::unsigned(32)); - builder.insert_constrain(v14, two, None); - - let v15 = builder.insert_load(v3, v1_type); - let v16 = builder.insert_load(v15, Type::unsigned(32)); - let four = builder.numeric_constant(4u128, Type::unsigned(32)); - let less_than_four = builder.insert_binary(v16, BinaryOp::Lt, four); - builder.insert_constrain(less_than_four, one, None); - - builder.terminate_with_return(vec![]); - let ssa = builder.finish(); - - // We expect the same result as above. - let ssa = ssa.mem2reg(); - let main = ssa.main(); - - // We expect all the stores to remain. - // The references in b0 are aliased and those are aliases may never be stored to again, - // but they are loaded from and used in later instructions. - // We need to make sure that the store of the address being aliased, is not removed from the program. - assert_eq!(count_stores(main.entry_block(), &main.dfg), 4); - // The store inside of the loop should remain - assert_eq!(count_stores(b2, &main.dfg), 1); - - // We expect the loads to remain the same - assert_eq!(count_loads(b2, &main.dfg), 1); - assert_eq!(count_loads(b3, &main.dfg), 5); - } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs index 5fe0d00c2b9..661109c1786 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/unrolling.rs @@ -81,35 +81,6 @@ impl Ssa { } impl Function { - // TODO(https://github.com/noir-lang/noir/issues/6192): are both this and - // TODO: Ssa::unroll_loops_iteratively needed? Likely able to be combined - pub(crate) fn unroll_loops_iteratively(&mut self) -> Result<(), RuntimeError> { - // Try to unroll loops first: - let mut unroll_errors = vec![]; - self.try_to_unroll_loops(&mut unroll_errors); - - // Keep unrolling until no more errors are found - while !unroll_errors.is_empty() { - let prev_unroll_err_count = unroll_errors.len(); - - // Simplify the SSA before retrying - - // Do a mem2reg after the last unroll to aid simplify_cfg - self.mem2reg(); - self.simplify_function(); - // Do another mem2reg after simplify_cfg to aid the next unroll - self.mem2reg(); - - // Unroll again - self.try_to_unroll_loops(&mut unroll_errors); - // If we didn't manage to unroll any more loops, exit - if unroll_errors.len() >= prev_unroll_err_count { - return Err(unroll_errors.swap_remove(0)); - } - } - Ok(()) - } - pub(crate) fn try_to_unroll_loops(&mut self, errors: &mut Vec) { // Loop unrolling in brillig can lead to a code explosion currently. This can // also be true for ACIR, but we have no alternative to unrolling in ACIR. diff --git a/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs index 07f15f37c6e..e85563691ba 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs @@ -173,6 +173,12 @@ pub enum GenericTypeArg { Named(Ident, UnresolvedType), } +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +pub enum GenericTypeArgKind { + Ordered, + Named, +} + #[derive(Debug, Default, PartialEq, Eq, Clone, Hash)] pub struct GenericTypeArgs { /// Each ordered argument, e.g. `` @@ -181,6 +187,9 @@ pub struct GenericTypeArgs { /// All named arguments, e.g. ``. /// Used for associated types. pub named_args: Vec<(Ident, UnresolvedType)>, + + /// The kind of each argument, in order (in case traversing the generics in order is needed) + pub kinds: Vec, } impl GenericTypeArgs { @@ -351,7 +360,11 @@ impl UnresolvedType { let last_segment = path.segments.last_mut().unwrap(); let generics = last_segment.generics.take(); let generic_type_args = if let Some(generics) = generics { - GenericTypeArgs { ordered_args: generics, named_args: Vec::new() } + let mut kinds = Vec::with_capacity(generics.len()); + for _ in 0..generics.len() { + kinds.push(GenericTypeArgKind::Ordered); + } + GenericTypeArgs { ordered_args: generics, named_args: Vec::new(), kinds } } else { GenericTypeArgs::default() }; diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs index 5067ac05c44..aef0771c486 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs @@ -3,7 +3,9 @@ use std::{ rc::Rc, }; -use crate::{ast::ItemVisibility, hir_def::traits::ResolvedTraitBound, StructField, TypeBindings}; +use crate::{ + ast::ItemVisibility, hir_def::traits::ResolvedTraitBound, StructField, StructType, TypeBindings, +}; use crate::{ ast::{ BlockExpression, FunctionKind, GenericTypeArgs, Ident, NoirFunction, NoirStruct, Param, @@ -53,7 +55,7 @@ mod unquote; use fm::FileId; use iter_extended::vecmap; -use noirc_errors::{Location, Span}; +use noirc_errors::{Location, Span, Spanned}; use types::bind_ordered_generics; use self::traits::check_trait_impl_method_matches_declaration; @@ -398,13 +400,36 @@ impl<'context> Elaborator<'context> { self.run_function_lints(&func_meta, &modifiers); + // Check arg and return-value visibility of standalone functions. + if self.should_check_function_visibility(&func_meta, &modifiers) { + let name = Ident(Spanned::from( + func_meta.name.location.span, + self.interner.definition_name(func_meta.name.id).to_string(), + )); + for (_, typ, _) in func_meta.parameters.iter() { + self.check_type_is_not_more_private_then_item( + &name, + modifiers.visibility, + typ, + name.span(), + ); + } + self.check_type_is_not_more_private_then_item( + &name, + modifiers.visibility, + func_meta.return_type(), + name.span(), + ); + } + self.introduce_generics_into_scope(func_meta.all_generics.clone()); // The DefinitionIds for each parameter were already created in define_function_meta // so we need to reintroduce the same IDs into scope here. for parameter in &func_meta.parameter_idents { let name = self.interner.definition_name(parameter.id).to_owned(); - self.add_existing_variable_to_scope(name, parameter.clone(), true); + let warn_if_unused = !(func_meta.trait_impl.is_some() && name == "self"); + self.add_existing_variable_to_scope(name, parameter.clone(), warn_if_unused); } self.add_trait_constraints_to_scope(&func_meta); @@ -1279,14 +1304,49 @@ impl<'context> Elaborator<'context> { let typ = self.resolve_type(alias.type_alias_def.typ); if visibility != ItemVisibility::Private { - self.check_aliased_type_is_not_more_private(name, visibility, &typ, span); + self.check_type_is_not_more_private_then_item(name, visibility, &typ, span); } self.interner.set_type_alias(alias_id, typ, generics); self.generics.clear(); } - fn check_aliased_type_is_not_more_private( + /// Find the struct in the parent module so we can know its visibility + fn find_struct_visibility(&self, struct_type: &StructType) -> Option { + let parent_module_id = struct_type.id.parent_module_id(self.def_maps); + let parent_module_data = self.get_module(parent_module_id); + let per_ns = parent_module_data.find_name(&struct_type.name); + per_ns.types.map(|(_, vis, _)| vis) + } + + /// Check whether a functions return value and args should be checked for private type visibility. + fn should_check_function_visibility( + &self, + func_meta: &FuncMeta, + modifiers: &FunctionModifiers, + ) -> bool { + // Private functions don't leak anything. + if modifiers.visibility == ItemVisibility::Private { + return false; + } + // Implementing public traits on private types is okay, they can't be used unless the type itself is accessible. + if func_meta.trait_impl.is_some() { + return false; + } + // Public struct functions should not expose private types. + if let Some(struct_visibility) = func_meta.struct_id.and_then(|id| { + let struct_def = self.get_struct(id); + let struct_def = struct_def.borrow(); + self.find_struct_visibility(&struct_def) + }) { + return struct_visibility != ItemVisibility::Private; + } + // Standalone functions should be checked + true + } + + /// Check that an item such as a struct field or type alias is not more visible than the type it refers to. + fn check_type_is_not_more_private_then_item( &mut self, name: &Ident, visibility: ItemVisibility, @@ -1302,11 +1362,7 @@ impl<'context> Elaborator<'context> { // then it's either accessible (all good) or it's not, in which case a different // error will happen somewhere else, but no need to error again here. if struct_module_id.krate == self.crate_id { - // Find the struct in the parent module so we can know its visibility - let parent_module_id = struct_type.id.parent_module_id(self.def_maps); - let parent_module_data = self.get_module(parent_module_id); - let per_ns = parent_module_data.find_name(&struct_type.name); - if let Some((_, aliased_visibility, _)) = per_ns.types { + if let Some(aliased_visibility) = self.find_struct_visibility(&struct_type) { if aliased_visibility < visibility { self.push_err(ResolverError::TypeIsMorePrivateThenItem { typ: struct_type.name.to_string(), @@ -1318,16 +1374,16 @@ impl<'context> Elaborator<'context> { } for generic in generics { - self.check_aliased_type_is_not_more_private(name, visibility, generic, span); + self.check_type_is_not_more_private_then_item(name, visibility, generic, span); } } Type::Tuple(types) => { for typ in types { - self.check_aliased_type_is_not_more_private(name, visibility, typ, span); + self.check_type_is_not_more_private_then_item(name, visibility, typ, span); } } Type::Alias(alias_type, generics) => { - self.check_aliased_type_is_not_more_private( + self.check_type_is_not_more_private_then_item( name, visibility, &alias_type.borrow().get_type(generics), @@ -1336,17 +1392,17 @@ impl<'context> Elaborator<'context> { } Type::Function(args, return_type, env, _) => { for arg in args { - self.check_aliased_type_is_not_more_private(name, visibility, arg, span); + self.check_type_is_not_more_private_then_item(name, visibility, arg, span); } - self.check_aliased_type_is_not_more_private(name, visibility, return_type, span); - self.check_aliased_type_is_not_more_private(name, visibility, env, span); + self.check_type_is_not_more_private_then_item(name, visibility, return_type, span); + self.check_type_is_not_more_private_then_item(name, visibility, env, span); } Type::MutableReference(typ) | Type::Array(_, typ) | Type::Slice(typ) => { - self.check_aliased_type_is_not_more_private(name, visibility, typ, span); + self.check_type_is_not_more_private_then_item(name, visibility, typ, span); } Type::InfixExpr(left, _op, right) => { - self.check_aliased_type_is_not_more_private(name, visibility, left, span); - self.check_aliased_type_is_not_more_private(name, visibility, right, span); + self.check_type_is_not_more_private_then_item(name, visibility, left, span); + self.check_type_is_not_more_private_then_item(name, visibility, right, span); } Type::FieldElement | Type::Integer(..) @@ -1383,6 +1439,22 @@ impl<'context> Elaborator<'context> { } } + // Check that the a public struct doesn't have a private type as a public field. + if typ.struct_def.visibility != ItemVisibility::Private { + for field in &fields { + let ident = Ident(Spanned::from( + field.name.span(), + format!("{}::{}", typ.struct_def.name, field.name), + )); + self.check_type_is_not_more_private_then_item( + &ident, + field.visibility, + &field.typ, + field.name.span(), + ); + } + } + let fields_len = fields.len(); self.interner.update_struct(*type_id, |struct_def| { struct_def.set_fields(fields); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/display.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/display.rs index 60661211a09..9f753f11e4b 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/display.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/display.rs @@ -860,6 +860,7 @@ fn remove_interned_in_generic_type_args( named_args: vecmap(args.named_args, |(name, typ)| { (name, remove_interned_in_unresolved_type(interner, typ)) }), + kinds: args.kinds, } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs index 5217bbd1e71..dfd328f85f0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -226,6 +226,10 @@ pub enum InterpreterError { location: Location, expression: String, }, + UnknownArrayLength { + length: Type, + location: Location, + }, // These cases are not errors, they are just used to prevent us from running more code // until the loop can be resumed properly. These cases will never be displayed to users. @@ -299,7 +303,8 @@ impl InterpreterError { | InterpreterError::DuplicateGeneric { duplicate_location: location, .. } | InterpreterError::TypeAnnotationsNeededForMethodCall { location } | InterpreterError::CannotResolveExpression { location, .. } - | InterpreterError::CannotSetFunctionBody { location, .. } => *location, + | InterpreterError::CannotSetFunctionBody { location, .. } + | InterpreterError::UnknownArrayLength { location, .. } => *location, InterpreterError::FailedToParseMacro { error, file, .. } => { Location::new(error.span(), *file) @@ -635,6 +640,10 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let msg = format!("`{expression}` is not a valid function body"); CustomDiagnostic::simple_error(msg, String::new(), location.span) } + InterpreterError::UnknownArrayLength { length, location } => { + let msg = format!("Could not determine array length `{length}`"); + CustomDiagnostic::simple_error(msg, String::new(), location.span) + } } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs index 97d90b905d4..260c4e3848a 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs @@ -303,7 +303,8 @@ impl Type { Type::Struct(def, generics) => { let struct_def = def.borrow(); let ordered_args = vecmap(generics, |generic| generic.to_display_ast()); - let generics = GenericTypeArgs { ordered_args, named_args: Vec::new() }; + let generics = + GenericTypeArgs { ordered_args, named_args: Vec::new(), kinds: Vec::new() }; let name = Path::from_ident(struct_def.name.clone()); UnresolvedTypeData::Named(name, generics, false) } @@ -312,7 +313,8 @@ impl Type { // alias' definition was changed let type_def = type_def.borrow(); let ordered_args = vecmap(generics, |generic| generic.to_display_ast()); - let generics = GenericTypeArgs { ordered_args, named_args: Vec::new() }; + let generics = + GenericTypeArgs { ordered_args, named_args: Vec::new(), kinds: Vec::new() }; let name = Path::from_ident(type_def.name.clone()); UnresolvedTypeData::Named(name, generics, false) } @@ -330,7 +332,7 @@ impl Type { let named_args = vecmap(&generics.named, |named_type| { (named_type.name.clone(), named_type.typ.to_display_ast()) }); - let generics = GenericTypeArgs { ordered_args, named_args }; + let generics = GenericTypeArgs { ordered_args, named_args, kinds: Vec::new() }; let name = Path::from_single(name.as_ref().clone(), Span::default()); UnresolvedTypeData::TraitAsType(name, generics) } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 622ec8650df..273f34a8a5e 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -63,6 +63,9 @@ impl<'local, 'context> Interpreter<'local, 'context> { "as_slice" => as_slice(interner, arguments, location), "ctstring_eq" => ctstring_eq(arguments, location), "ctstring_hash" => ctstring_hash(arguments, location), + "derive_pedersen_generators" => { + derive_generators(interner, arguments, return_type, location) + } "expr_as_array" => expr_as_array(interner, arguments, return_type, location), "expr_as_assert" => expr_as_assert(interner, arguments, return_type, location), "expr_as_assert_eq" => expr_as_assert_eq(interner, arguments, return_type, location), @@ -2793,3 +2796,56 @@ fn ctstring_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult fn ctstring_hash(arguments: Vec<(Value, Location)>, location: Location) -> IResult { hash_item(arguments, location, get_ctstring) } + +fn derive_generators( + interner: &mut NodeInterner, + arguments: Vec<(Value, Location)>, + return_type: Type, + location: Location, +) -> IResult { + let (domain_separator_string, starting_index) = check_two_arguments(arguments, location)?; + + let domain_separator_location = domain_separator_string.1; + let (domain_separator_string, _) = get_array(interner, domain_separator_string)?; + let starting_index = get_u32(starting_index)?; + + let domain_separator_string = + try_vecmap(domain_separator_string, |byte| get_u8((byte, domain_separator_location)))?; + + let (size, elements) = match return_type.clone() { + Type::Array(size, elements) => (size, elements), + _ => panic!("ICE: Should only have an array return type"), + }; + + let Some(num_generators) = size.evaluate_to_u32() else { + return Err(InterpreterError::UnknownArrayLength { length: *size, location }); + }; + + let generators = bn254_blackbox_solver::derive_generators( + &domain_separator_string, + num_generators, + starting_index, + ); + + let is_infinite = FieldElement::zero(); + let x_field_name: Rc = Rc::new("x".to_owned()); + let y_field_name: Rc = Rc::new("y".to_owned()); + let is_infinite_field_name: Rc = Rc::new("is_infinite".to_owned()); + let mut results = Vector::new(); + for gen in generators { + let x_big: BigUint = gen.x.into(); + let x = FieldElement::from_be_bytes_reduce(&x_big.to_bytes_be()); + let y_big: BigUint = gen.y.into(); + let y = FieldElement::from_be_bytes_reduce(&y_big.to_bytes_be()); + let mut embedded_curve_point_fields = HashMap::default(); + embedded_curve_point_fields.insert(x_field_name.clone(), Value::Field(x)); + embedded_curve_point_fields.insert(y_field_name.clone(), Value::Field(y)); + embedded_curve_point_fields + .insert(is_infinite_field_name.clone(), Value::Field(is_infinite)); + let embedded_curve_point_struct = + Value::Struct(embedded_curve_point_fields, *elements.clone()); + results.push_back(embedded_curve_point_struct); + } + + Ok(Value::Array(results, return_type)) +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs index adc68351e3c..904ce41fbf0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs @@ -575,7 +575,11 @@ impl<'a> Lexer<'a> { return self.lookup_word_token(word, start, end); } - let delimiter = self.next_token()?; + let mut delimiter = self.next_token()?; + while let Token::Whitespace(_) = delimiter.token() { + delimiter = self.next_token()?; + } + let (start_delim, end_delim) = match delimiter.token() { Token::LeftBrace => (Token::LeftBrace, Token::RightBrace), Token::LeftBracket => (Token::LeftBracket, Token::RightBracket), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs index a8e463fb93b..8f05832d26d 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs @@ -377,7 +377,7 @@ impl fmt::Display for Token { } Token::Keyword(k) => write!(f, "{k}"), Token::Attribute(ref a) => write!(f, "{a}"), - Token::InnerAttribute(ref a) => write!(f, "#![{a}]"), + Token::InnerAttribute(ref a) => write!(f, "#![{}]", a.contents()), Token::LineComment(ref s, style) => match style { Some(DocStyle::Inner) => write!(f, "//!{s}"), Some(DocStyle::Outer) => write!(f, "///{s}"), @@ -1010,28 +1010,32 @@ impl SecondaryAttribute { pub(crate) fn is_abi(&self) -> bool { matches!(self, SecondaryAttribute::Abi(_)) } -} -impl fmt::Display for SecondaryAttribute { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + pub(crate) fn contents(&self) -> String { match self { - SecondaryAttribute::Deprecated(None) => write!(f, "#[deprecated]"), + SecondaryAttribute::Deprecated(None) => "deprecated".to_string(), SecondaryAttribute::Deprecated(Some(ref note)) => { - write!(f, r#"#[deprecated({note:?})]"#) + format!("deprecated({note:?})") } - SecondaryAttribute::Tag(ref attribute) => write!(f, "#['{}]", attribute.contents), - SecondaryAttribute::Meta(ref attribute) => write!(f, "#[{}]", attribute.contents), - SecondaryAttribute::ContractLibraryMethod => write!(f, "#[contract_library_method]"), - SecondaryAttribute::Export => write!(f, "#[export]"), - SecondaryAttribute::Field(ref k) => write!(f, "#[field({k})]"), - SecondaryAttribute::Abi(ref k) => write!(f, "#[abi({k})]"), - SecondaryAttribute::Varargs => write!(f, "#[varargs]"), - SecondaryAttribute::UseCallersScope => write!(f, "#[use_callers_scope]"), - SecondaryAttribute::Allow(ref k) => write!(f, "#[allow(#{k})]"), + SecondaryAttribute::Tag(ref attribute) => format!("'{}", attribute.contents), + SecondaryAttribute::Meta(ref attribute) => attribute.contents.to_string(), + SecondaryAttribute::ContractLibraryMethod => "contract_library_method".to_string(), + SecondaryAttribute::Export => "export".to_string(), + SecondaryAttribute::Field(ref k) => format!("field({k})"), + SecondaryAttribute::Abi(ref k) => format!("abi({k})"), + SecondaryAttribute::Varargs => "varargs".to_string(), + SecondaryAttribute::UseCallersScope => "use_callers_scope".to_string(), + SecondaryAttribute::Allow(ref k) => format!("allow({k})"), } } } +impl fmt::Display for SecondaryAttribute { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "#[{}]", self.contents()) + } +} + #[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] pub struct CustomAttribute { pub contents: String, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/generics.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/generics.rs index 2c8ba5a2a65..f577a237615 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/generics.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/generics.rs @@ -130,9 +130,11 @@ impl<'a> Parser<'a> { match generic { GenericTypeArg::Ordered(typ) => { generic_type_args.ordered_args.push(typ); + generic_type_args.kinds.push(crate::ast::GenericTypeArgKind::Ordered); } GenericTypeArg::Named(name, typ) => { generic_type_args.named_args.push((name, typ)); + generic_type_args.kinds.push(crate::ast::GenericTypeArgKind::Named); } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests/unused_items.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests/unused_items.rs index 51bdf785688..86f77fc397a 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests/unused_items.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests/unused_items.rs @@ -274,3 +274,23 @@ fn no_warning_on_indirect_struct_if_it_has_an_abi_attribute() { "#; assert_no_errors(src); } + +#[test] +fn no_warning_on_self_in_trait_impl() { + let src = r#" + struct Bar {} + + trait Foo { + fn foo(self, a: u64); + } + + impl Foo for Bar { + fn foo(self, _a: u64) {} + } + + fn main() { + let _ = Bar {}; + } + "#; + assert_no_errors(src); +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests/visibility.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests/visibility.rs index f02771b3760..7cfec32062d 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests/visibility.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests/visibility.rs @@ -28,29 +28,38 @@ fn errors_once_on_unused_import_that_is_not_accessible() { )) )); } + +fn assert_type_is_more_private_than_item_error(src: &str, private_typ: &str, public_item: &str) { + let errors = get_program_errors(src); + + assert!(!errors.is_empty(), "expected visibility error, got nothing"); + for (error, _) in &errors { + let CompilationError::ResolverError(ResolverError::TypeIsMorePrivateThenItem { + typ, + item, + .. + }) = error + else { + panic!("Expected a type vs item visibility error, got {}", error); + }; + + assert_eq!(typ, private_typ); + assert_eq!(item, public_item); + } + assert_eq!(errors.len(), 1, "only expected one error"); +} + #[test] fn errors_if_type_alias_aliases_more_private_type() { let src = r#" struct Foo {} pub type Bar = Foo; - pub fn no_unused_warnings(_b: Bar) { - let _ = Foo {}; + pub fn no_unused_warnings() { + let _: Bar = Foo {}; } fn main() {} "#; - - let errors = get_program_errors(src); - assert_eq!(errors.len(), 1); - - let CompilationError::ResolverError(ResolverError::TypeIsMorePrivateThenItem { - typ, item, .. - }) = &errors[0].0 - else { - panic!("Expected an unused item error"); - }; - - assert_eq!(typ, "Foo"); - assert_eq!(item, "Bar"); + assert_type_is_more_private_than_item_error(src, "Foo", "Bar"); } #[test] @@ -59,25 +68,165 @@ fn errors_if_type_alias_aliases_more_private_type_in_generic() { pub struct Generic { value: T } struct Foo {} pub type Bar = Generic; - pub fn no_unused_warnings(_b: Bar) { + pub fn no_unused_warnings() { let _ = Foo {}; - let _ = Generic { value: 1 }; + let _: Bar = Generic { value: Foo {} }; } fn main() {} "#; + assert_type_is_more_private_than_item_error(src, "Foo", "Bar"); +} - let errors = get_program_errors(src); - assert_eq!(errors.len(), 1); +#[test] +fn errors_if_pub_type_alias_leaks_private_type_in_generic() { + let src = r#" + pub mod moo { + struct Bar {} + pub struct Foo { pub value: T } + pub type FooBar = Foo; - let CompilationError::ResolverError(ResolverError::TypeIsMorePrivateThenItem { - typ, item, .. - }) = &errors[0].0 - else { - panic!("Expected an unused item error"); - }; + pub fn no_unused_warnings() { + let _: FooBar = Foo { value: Bar {} }; + } + } + fn main() {} + "#; + assert_type_is_more_private_than_item_error(src, "Bar", "FooBar"); +} - assert_eq!(typ, "Foo"); - assert_eq!(item, "Bar"); +#[test] +fn errors_if_pub_struct_field_leaks_private_type_in_generic() { + let src = r#" + pub mod moo { + struct Bar {} + pub struct Foo { pub value: T } + pub struct FooBar { pub value: Foo } + + pub fn no_unused_warnings() { + let _ = FooBar { value: Foo { value: Bar {} } }; + } + } + fn main() {} + "#; + assert_type_is_more_private_than_item_error(src, "Bar", "FooBar::value"); +} + +#[test] +fn errors_if_pub_function_leaks_private_type_in_return() { + let src = r#" + pub mod moo { + struct Bar {} + + pub fn bar() -> Bar { + Bar {} + } + } + fn main() {} + "#; + assert_type_is_more_private_than_item_error(src, "Bar", "bar"); +} + +#[test] +fn errors_if_pub_function_leaks_private_type_in_arg() { + let src = r#" + pub mod moo { + struct Bar {} + pub fn bar(_bar: Bar) {} + + pub fn no_unused_warnings() { + let _ = Bar {}; + } + } + fn main() {} + "#; + assert_type_is_more_private_than_item_error(src, "Bar", "bar"); +} + +#[test] +fn does_not_error_if_pub_function_is_on_private_struct() { + let src = r#" + pub mod moo { + struct Bar {} + + impl Bar { + pub fn bar() -> Bar { + Bar {} + } + } + + pub fn no_unused_warnings() { + let _ = Bar {}; + } + } + fn main() {} + "#; + assert_no_errors(src); +} + +#[test] +fn errors_if_pub_function_on_pub_struct_returns_private() { + let src = r#" + pub mod moo { + struct Bar {} + pub struct Foo {} + + impl Foo { + pub fn bar() -> Bar { + Bar {} + } + } + + pub fn no_unused_warnings() { + let _ = Foo {}; + } + } + fn main() {} + "#; + assert_type_is_more_private_than_item_error(src, "Bar", "bar"); +} + +#[test] +fn does_not_error_if_pub_trait_is_defined_on_private_struct() { + let src = r#" + pub mod moo { + struct Bar {} + + pub trait Foo { + fn foo() -> Self; + } + + impl Foo for Bar { + fn foo() -> Self { + Bar {} + } + } + + pub fn no_unused_warnings() { + let _ = Bar {}; + } + } + fn main() {} + "#; + assert_no_errors(src); +} + +#[test] +fn errors_if_pub_trait_returns_private_struct() { + let src = r#" + pub mod moo { + struct Bar {} + + pub trait Foo { + fn foo() -> Bar; + } + + pub fn no_unused_warnings() { + let _ = Bar {}; + } + } + fn main() {} + "#; + assert_type_is_more_private_than_item_error(src, "Bar", "foo"); } #[test] diff --git a/noir/noir-repo/compiler/wasm/package.json b/noir/noir-repo/compiler/wasm/package.json index 009f861c5b1..33afde0c27a 100644 --- a/noir/noir-repo/compiler/wasm/package.json +++ b/noir/noir-repo/compiler/wasm/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.35.0", + "version": "0.36.0", "license": "(MIT OR Apache-2.0)", "main": "dist/main.js", "types": "./dist/types/src/index.d.cts", diff --git a/noir/noir-repo/cspell.json b/noir/noir-repo/cspell.json index 6fd25a77182..8945ad21bdc 100644 --- a/noir/noir-repo/cspell.json +++ b/noir/noir-repo/cspell.json @@ -164,6 +164,7 @@ "plonkc", "PLONKish", "pprof", + "precomputes", "preimage", "preprocess", "prettytable", @@ -178,6 +179,7 @@ "reqwest", "rfind", "rustc", + "rustfmt", "rustup", "sboxed", "schnorr", @@ -229,6 +231,8 @@ "wasi", "wasmer", "Weierstraß", + "whitespace", + "whitespaces", "zkhash", "zshell" ], diff --git a/noir/noir-repo/docs/.gitignore b/noir/noir-repo/docs/.gitignore index 501e7e465ea..7ff8bd69a72 100644 --- a/noir/noir-repo/docs/.gitignore +++ b/noir/noir-repo/docs/.gitignore @@ -25,3 +25,4 @@ yarn-error.log* package-lock.json versions.json +.supermavenignore diff --git a/noir/noir-repo/docs/.markdownlint.json b/noir/noir-repo/docs/.markdownlint.json deleted file mode 100644 index 40896b4542f..00000000000 --- a/noir/noir-repo/docs/.markdownlint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "no-missing-space-atx": false -} diff --git a/noir/noir-repo/docs/README.md b/noir/noir-repo/docs/README.md index c1d2bbd6d4e..d3554ae39f2 100644 --- a/noir/noir-repo/docs/README.md +++ b/noir/noir-repo/docs/README.md @@ -28,7 +28,13 @@ yarn build ### Local Development ``` -yarn workspace docs start +yarn workspace docs version +``` + +This command fetches and compiles the list of documentation versions to build with. + +``` +yarn workspace docs dev ``` This command starts a local development server and opens up a browser window. Most changes are diff --git a/noir/noir-repo/docs/docs/getting_started/backend/index.md b/noir/noir-repo/docs/docs/getting_started/backend/index.md deleted file mode 100644 index 7192d954877..00000000000 --- a/noir/noir-repo/docs/docs/getting_started/backend/index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Proving Backend Installation -description: Proving backends offer command line tools for proving and verifying Noir programs. This page describes how to install `bb` as an example. -keywords: [ - Proving - Backend - Barretenberg - bb - bbup - Installation - Terminal - Command - CLI - Version -] -pagination_next: getting_started/hello_noir/index ---- - -Proving backends each provide their own tools for working with Noir programs, providing functionality like proof generation, proof verification, and verifier smart contract generation. - -For the latest information on tooling provided by each proving backend, installation instructions, Noir version compatibility... you may refer to the proving backends' own documentation. - -You can find the full list of proving backends compatible with Noir in [Awesome Noir](https://github.com/noir-lang/awesome-noir/?tab=readme-ov-file#proving-backends). - -## Example: Installing `bb` - -`bb` is the CLI tool provided by the [Barretenberg proving backend](https://github.com/AztecProtocol/barretenberg) developed by Aztec Labs. - -You can find the instructions for installation in [`bb`'s documentation](https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/readme.md#installation). - -Once installed, we are ready to start working on [our first Noir program](../hello_noir/index.md). diff --git a/noir/noir-repo/docs/docs/getting_started/hello_noir/index.md b/noir/noir-repo/docs/docs/getting_started/hello_noir/index.md deleted file mode 100644 index 6760e54aad1..00000000000 --- a/noir/noir-repo/docs/docs/getting_started/hello_noir/index.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: Creating a Project -description: - Learn how to create and verify your first Noir program using Nargo, a programming language for - zero-knowledge proofs. -keywords: - [ - Nargo, - Noir, - zero-knowledge proofs, - programming language, - create Noir program, - verify Noir program, - step-by-step guide, - ] -sidebar_position: 1 - ---- - -Now that we have installed Nargo and a proving backend, it is time to make our first hello world program! - -### 1. Create a new project directory - -Noir code can live anywhere on your computer. Let us create a _projects_ folder in the home -directory to house our first Noir program. - -Create the directory and change directory into it by running: - -```sh -mkdir ~/projects -cd ~/projects -``` - -## Nargo - -Nargo provides the ability to initiate and execute Noir projects. Read the [Nargo installation](../installation/index.md) section to learn more about Nargo and how to install it. - -### 2. Create a new Noir project - -Now that we are in the projects directory, create a new Nargo project by running: - -```sh -nargo new hello_world -``` - -`hello_world` can be any arbitrary project name, we are simply using `hello_world` for demonstration. - -In production, it is common practice to name the project folder, `circuits`, for clarity amongst other folders in the codebase (like: `contracts`, `scripts`, and `test`). - -A `hello_world` folder would be created. Similar to Rust, the folder houses _src/main.nr_ and -_Nargo.toml_ which contain the source code and environmental options of your Noir program -respectively. - -#### Intro to Noir Syntax - -Let us take a closer look at _main.nr_. The default _main.nr_ generated should look like this: - -```rust -fn main(x : Field, y : pub Field) { - assert(x != y); -} -``` - -The first line of the program specifies the program's inputs: - -```rust -x : Field, y : pub Field -``` - -Program inputs in Noir are private by default (e.g. `x`), but can be labeled public using the -keyword `pub` (e.g. `y`). To learn more about private and public values, check the -[Data Types](../../noir/concepts/data_types/index.md) section. - -The next line of the program specifies its body: - -```rust -assert(x != y); -``` - -The Noir syntax `assert` can be interpreted as something similar to constraints in other zk-contract languages. - -For more Noir syntax, check the [Language Concepts](../../noir/concepts/comments.md) chapter. - -### 3. Build in/output files - -Change directory into _hello_world_ and build in/output files for your Noir program by running: - -```sh -cd hello_world -nargo check -``` - -A _Prover.toml_ file will be generated in your project directory, to allow specifying input values to the program. - -### 4. Execute the Noir program - -Now that the project is set up, we can execute our Noir program. - -Fill in input values for execution in the _Prover.toml_ file. For example: - -```toml -x = "1" -y = "2" -``` - -Execute your Noir program: - -```sh -nargo execute witness-name -``` - -The witness corresponding to this execution will then be written to the file `./target/witness-name.gz`. - -The command also automatically compiles your Noir program if it was not already / was edited, which you may notice the compiled artifacts being written to the file `./target/hello_world.json`. - -## Proving Backend - -Proving backends provide the ability to generate and verify proofs of executing Noir programs, following Noir's tooling that compiles and executes the programs. Read the [proving backend installation](../backend/index.md) section to learn more about proving backends and how to install them. - -Barretenberg is used as an example here to demonstrate how proving and verifying could be implemented and used. Read the [`bb` installation](../backend/index.md#example-installing-bb) section for how to install Barretenberg's CLI tool; refer to [`bb`'s documentation](https://github.com/AztecProtocol/aztec-packages/blob/master/barretenberg/cpp/src/barretenberg/bb/readme.md) for full details about the tool. - -### 5. Prove an execution of the Noir program - -Using Barretenberg as an example, prove the valid execution of your Noir program running: - -```sh -bb prove -b ./target/hello_world.json -w ./target/witness-name.gz -o ./target/proof -``` - -The proof generated will then be written to the file `./target/proof`. - -:::tip -Since the params for `nargo` and `bb` often specify multiple filenames to read from or write to, remember to check each command is referring to the desired filenames. -Or for greater certainty, delete the target folder and go through each step again (compile, witness, prove, ...) to ensure files generated in past commands are being referenced in future ones. -::: - -### 6. Verify the execution proof - -Once a proof is generated, we can verify correct execution of our Noir program by verifying the proof file. - -Using Barretenberg as an example, compute the verification key for the Noir program by running: - -```sh -bb write_vk -b ./target/hello_world.json -o ./target/vk -``` - -And verify your proof by running: - -```sh -bb verify -k ./target/vk -p ./target/proof -``` - -If successful, the verification will complete in silence; if unsuccessful, the command will trigger logging of the corresponding error. - -Congratulations, you have now created and verified a proof for your very first Noir program! - -In the [next section](./project_breakdown.md), we will go into more detail on each step performed. diff --git a/noir/noir-repo/docs/docs/getting_started/installation/index.md b/noir/noir-repo/docs/docs/getting_started/installation/index.md deleted file mode 100644 index 53ea9c7891c..00000000000 --- a/noir/noir-repo/docs/docs/getting_started/installation/index.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Nargo Installation -description: - nargo is a command line tool for interacting with Noir programs. This page is a quick guide on how to install Nargo through the most common and easy method, noirup -keywords: [ - Nargo - Noir - Rust - Cargo - Noirup - Installation - Terminal Commands - Version Check - Nightlies - Specific Versions - Branches - Noirup Repository -] -pagination_next: getting_started/hello_noir/index ---- - -`nargo` is a tool for working with Noir programs on the CLI, providing you with the ability to start new projects, compile, execute and test Noir programs from the terminal. - -The name is inspired by Rust's package manager `cargo`; and similar to Rust's `rustup`, Noir also has an easy installation script `noirup`. - -## Installing Noirup - -Open a terminal on your machine, and write: - -```bash -curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash -``` - -Close the terminal, open another one, and run - -```bash -noirup -``` - -Done. That's it. You should have the latest version working. You can check with `nargo --version`. - -You can also install nightlies, specific versions -or branches. Check out the [noirup repository](https://github.com/noir-lang/noirup) for more -information. - -Now we're ready to start working on [our first Noir program!](../hello_noir/index.md) diff --git a/noir/noir-repo/docs/docs/getting_started/installation/other_install_methods.md b/noir/noir-repo/docs/docs/getting_started/noir_installation.md similarity index 93% rename from noir/noir-repo/docs/docs/getting_started/installation/other_install_methods.md rename to noir/noir-repo/docs/docs/getting_started/noir_installation.md index 3634723562b..f92fd8dea38 100644 --- a/noir/noir-repo/docs/docs/getting_started/installation/other_install_methods.md +++ b/noir/noir-repo/docs/docs/getting_started/noir_installation.md @@ -1,5 +1,5 @@ --- -title: Alternative Installations +title: Standalone Noir Installation description: There are different ways to install Nargo, the one-stop shop and command-line tool for developing Noir programs. This guide explains how to specify which version to install when using noirup, and using WSL for windows. keywords: [ Installation @@ -14,11 +14,9 @@ keywords: [ Direnv Uninstalling Nargo ] -sidebar_position: 1 +sidebar_position: 2 --- -## Encouraged Installation Method: Noirup - Noirup is the endorsed method for installing Nargo, streamlining the process of fetching binaries or compiling from source. It supports a range of options to cater to your specific needs, from nightly builds and specific versions to compiling from various sources. ### Installing Noirup @@ -40,6 +38,7 @@ With `noirup`, you can easily switch between different Nargo versions, including ``` - **Specific Version**: Install a specific version of Nargo. + ```sh noirup --version ``` @@ -79,6 +78,7 @@ With `noirup`, you can easily switch between different Nargo versions, including ``` - **From Local Source**: Compile and install from a local directory. + ```sh noirup --path ./path/to/local/source ``` @@ -89,7 +89,7 @@ The default backend for Noir (Barretenberg) doesn't provide Windows binaries at Step 1: Follow the instructions [here](https://learn.microsoft.com/en-us/windows/wsl/install) to install and run WSL. -step 2: Follow the [Noirup instructions](#encouraged-installation-method-noirup). +step 2: Follow the [Noirup instructions](#installing-noirup). ## Uninstalling Nargo diff --git a/noir/noir-repo/docs/docs/getting_started/hello_noir/project_breakdown.md b/noir/noir-repo/docs/docs/getting_started/project_breakdown.md similarity index 95% rename from noir/noir-repo/docs/docs/getting_started/hello_noir/project_breakdown.md rename to noir/noir-repo/docs/docs/getting_started/project_breakdown.md index 96e653f6c08..e442e377040 100644 --- a/noir/noir-repo/docs/docs/getting_started/hello_noir/project_breakdown.md +++ b/noir/noir-repo/docs/docs/getting_started/project_breakdown.md @@ -5,7 +5,7 @@ description: file, and how to prove and verify your program. keywords: [Nargo, Nargo project, Prover.toml, proof verification, private asset transfer] -sidebar_position: 2 +sidebar_position: 1 --- This section breaks down our hello world program from the previous section. @@ -46,7 +46,7 @@ license = "MIT" ecrecover = {tag = "v0.9.0", git = "https://github.com/colinnielsen/ecrecover-noir.git"} ``` -Nargo.toml for a [workspace](../../noir/modules_packages_crates/workspaces.md) will look a bit different. For example: +Nargo.toml for a [workspace](../noir/modules_packages_crates/workspaces.md) will look a bit different. For example: ```toml [workspace] @@ -66,11 +66,11 @@ The package section defines a number of fields including: - `entry` (optional) - a relative filepath to use as the entry point into your package (overrides the default of `src/lib.nr` or `src/main.nr`) - `backend` (optional) - `license` (optional) -- `expression_width` (optional) - Sets the default backend expression width. This field will override the default backend expression width specified by the Noir compiler (currently set to width 4). +- `expression_width` (optional) - Sets the default backend expression width. This field will override the default backend expression width specified by the Noir compiler (currently set to width 4). #### Dependencies section -This is where you will specify any dependencies for your project. See the [Dependencies page](../../noir/modules_packages_crates/dependencies.md) for more info. +This is where you will specify any dependencies for your project. See the [Dependencies page](../noir/modules_packages_crates/dependencies.md) for more info. `./proofs/` and `./contract/` directories will not be immediately visible until you create a proof or verifier contract respectively. diff --git a/noir/noir-repo/docs/docs/getting_started/quick_start.md b/noir/noir-repo/docs/docs/getting_started/quick_start.md new file mode 100644 index 00000000000..4ce48409818 --- /dev/null +++ b/noir/noir-repo/docs/docs/getting_started/quick_start.md @@ -0,0 +1,124 @@ +--- +title: Quick Start +tags: [] +sidebar_position: 0 +--- + +## Installation + +### Noir + +The easiest way to develop with Noir is using Nargo the CLI tool. It provides you the ability to start new projects, compile, execute and test Noir programs from the terminal. + +You can use `noirup` the installation script to quickly install and update Nargo: + +```bash +curl -L noirup.dev | bash +noirup +``` + +### Proving backend + +After installing Noir, we install a proving backend to work with our Noir programs. + +Proving backends provide you the abilities to generate proofs, verify proofs, generate smart contracts and more for your Noir programs. + +Different proving backends provide different tools for working with Noir programs, here we will use the [Barretenberg proving backend](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg) developed by Aztec Labs as an example. + +You can use the `bbup` installation script to quickly install and update BB, Barretenberg's CLI tool: + +You can find the full list of proving backends compatible with Noir in Awesome Noir. + +```bash +curl -L bbup.dev | bash +bbup +``` + +For the full list of proving backends compatible with Noir, visit [Awesome Noir](https://github.com/noir-lang/awesome-noir/?tab=readme-ov-file#proving-backends). + +## Nargo + +Nargo provides the ability to initiate and execute Noir projects. Let's initialize the traditional `hello_world`: + +```sh +nargo new hello_world +``` + +Two files will be created. + +- `src/main.nr` contains a simple boilerplate circuit +- `Nargo.toml` contains environmental options, such as name, author, dependencies, and others. + +Glancing at _main.nr_ , we can see that inputs in Noir are private by default, but can be labeled public using the keyword `pub`. This means that we will _assert_ that we know a value `x` which is different from `y` without revealing `x`: + +```rust +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` + +To learn more about private and public values, check the [Data Types](../noir/concepts/data_types/index.md) section. + +### Compiling and executing + +We can now use `nargo` to generate a _Prover.toml_ file, where our input values will be specified: + +```sh +cd hello_world +nargo check + +Let's feed some valid values into this file: + +```toml +x = "1" +y = "2" +``` + +We're now ready to compile and execute our Noir program. By default the `nargo execute` command will do both, and generate the `witness` that we need to feed to our proving backend: + +```sh +nargo execute +``` + +The witness corresponding to this execution will then be written to the file _./target/witness-name.gz_. + +The command also automatically compiles your Noir program if it was not already / was edited, which you may notice the compiled artifacts being written to the file _./target/hello_world.json_. + +With circuit compiled and witness generated, we're ready to prove. + +## Proving backend + +Different proving backends may provide different tools and commands to work with Noir programs. Here Barretenberg's `bb` CLI tool is used as an example: + +```sh +bb prove -b ./target/hello_world.json -w ./target/hello_world.gz -o ./target/proof +``` + +:::tip + +Naming can be confusing, specially as you pass them to the `bb` commands. If unsure, it won't hurt to delete the target folder and start anew to make sure you're using the most recent versions of the compiled circuit and witness. + +::: + +The proof is now generated in the `target` folder. To verify it we first need to compute the verification key from the compiled circuit, and use it to verify: + +```sh +bb write_vk -b ./target/hello_world.json -o ./target/vk +bb verify -k ./target/vk -p ./target/proof +``` + +:::info + +Notice that in order to verify a proof, the verifier knows nothing but the circuit, which is compiled and used to generate the verification key. This is obviously quite important: private inputs remain private. + +As for the public inputs, you may have noticed they haven't been specified. This behavior varies with each particular backend, but barretenberg typically attaches them to the proof. You can see them by parsing and splitting it. For example for if your public inputs are 32 bytes: + +```bash +head -c 32 ./target/proof | od -An -v -t x1 | tr -d $' \n' +``` + +::: + +Congratulations, you have now created and verified a proof for your very first Noir program! + +In the [next section](./project_breakdown.md), we will go into more detail on each step performed. diff --git a/noir/noir-repo/docs/docs/how_to/how-to-oracles.md b/noir/noir-repo/docs/docs/how_to/how-to-oracles.md index 2f69902062c..dc49b192384 100644 --- a/noir/noir-repo/docs/docs/how_to/how-to-oracles.md +++ b/noir/noir-repo/docs/docs/how_to/how-to-oracles.md @@ -174,7 +174,7 @@ If the Oracle function is returning an array containing other arrays, such as `[ ## Step 3 - Usage with Nargo -Using the [`nargo` CLI tool](../getting_started/installation/index.md), you can use oracles in the `nargo test` and `nargo execute` commands by passing a value to `--oracle-resolver`. For example: +Using the [`nargo` CLI tool](../getting_started/noir_installation.md), you can use oracles in the `nargo test` and `nargo execute` commands by passing a value to `--oracle-resolver`. For example: ```bash nargo test --oracle-resolver http://localhost:5555 diff --git a/noir/noir-repo/docs/docs/how_to/how-to-solidity-verifier.md b/noir/noir-repo/docs/docs/how_to/how-to-solidity-verifier.md index a8169595b3d..2cc0f8e57ce 100644 --- a/noir/noir-repo/docs/docs/how_to/how-to-solidity-verifier.md +++ b/noir/noir-repo/docs/docs/how_to/how-to-solidity-verifier.md @@ -27,7 +27,7 @@ This allows for a powerful feature set, as one can make use of the conciseness a This guide shows you how to generate a Solidity Verifier and deploy it on the [Remix IDE](https://remix.ethereum.org/). It is assumed that: - You are comfortable with the Solidity programming language and understand how contracts are deployed on the Ethereum network -- You have Noir installed and you have a Noir program. If you don't, [get started](../getting_started/installation/index.md) with Nargo and the example Hello Noir circuit +- You have Noir installed and you have a Noir program. If you don't, [get started](../getting_started/quick_start.md) with Nargo and the example Hello Noir circuit - You are comfortable navigating RemixIDE. If you aren't or you need a refresher, you can find some video tutorials [here](https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA) that could help you. ## Rundown @@ -57,7 +57,7 @@ bb contract replacing `` with the name of your Noir project. A new `contract` folder would then be generated in your project directory, containing the Solidity file `contract.sol`. It can be deployed to any EVM blockchain acting as a verifier smart contract. -You can find more information about `bb` and the default Noir proving backend on [this page](../getting_started/hello_noir/index.md#proving-backend). +You can find more information about `bb` and the default Noir proving backend on [this page](../getting_started/quick_start.md#proving-backend). :::info @@ -133,9 +133,9 @@ To verify a proof using the Solidity verifier contract, we call the `verify` fun function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) ``` -When using the default example in the [Hello Noir](../getting_started/hello_noir/index.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. Note that the public inputs must be passed in separately to the rest of the proof so we must split the proof as returned from `bb`. +When using the default example in the [Hello Noir](../getting_started/quick_start.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. Note that the public inputs must be passed in separately to the rest of the proof so we must split the proof as returned from `bb`. -First generate a proof with `bb` at the location `./proof` using the steps in [get started](../getting_started/hello_noir/index.md), this proof is in a binary format but we want to convert it into a hex string to pass into Remix, this can be done with the +First generate a proof with `bb` at the location `./proof` using the steps in [get started](../getting_started/quick_start.md), this proof is in a binary format but we want to convert it into a hex string to pass into Remix, this can be done with the ```bash # This value must be changed to match the number of public inputs (including return values!) in your program. diff --git a/noir/noir-repo/docs/docs/noir/concepts/data_types/arrays.md b/noir/noir-repo/docs/docs/noir/concepts/data_types/arrays.md index bb68e60fe53..289145a8c4d 100644 --- a/noir/noir-repo/docs/docs/noir/concepts/data_types/arrays.md +++ b/noir/noir-repo/docs/docs/noir/concepts/data_types/arrays.md @@ -203,6 +203,8 @@ fn main() { Same as fold, but uses the first element as the starting element. +Requires `self` to be non-empty. + ```rust fn reduce(self, f: fn(T, T) -> T) -> T ``` diff --git a/noir/noir-repo/docs/docs/reference/noir_codegen.md b/noir/noir-repo/docs/docs/reference/noir_codegen.md index db8f07dc22e..e4c362f9610 100644 --- a/noir/noir-repo/docs/docs/reference/noir_codegen.md +++ b/noir/noir-repo/docs/docs/reference/noir_codegen.md @@ -7,7 +7,8 @@ sidebar_position: 3 When using TypeScript, it is extra work to interpret Noir program outputs in a type-safe way. Third party libraries may exist for popular Noir programs, but they are either hard to find or unmaintained. -Now you can generate TypeScript bindings for your Noir programs in two steps: +Now you can generate TypeScript bindings for your Noir programs in two steps: + 1. Exporting Noir functions using `nargo export` 2. Using the TypeScript module `noir_codegen` to generate TypeScript binding @@ -33,7 +34,8 @@ yarn add @noir-lang/noir_codegen -D ``` ### Nargo library -Make sure you have Nargo, v0.25.0 or greater, installed. If you don't, follow the [installation guide](../getting_started/installation/index.md). + +Make sure you have Nargo, v0.25.0 or greater, installed. If you don't, follow the [installation guide](../getting_started/noir_installation.md). If you're in a new project, make a `circuits` folder and create a new Noir library: diff --git a/noir/noir-repo/docs/docs/tooling/debugger.md b/noir/noir-repo/docs/docs/tooling/debugger.md index 9b7565ba9ff..200b5fc423a 100644 --- a/noir/noir-repo/docs/docs/tooling/debugger.md +++ b/noir/noir-repo/docs/docs/tooling/debugger.md @@ -12,7 +12,7 @@ There are currently two ways of debugging Noir programs: 1. From VS Code, via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). 2. Via the REPL debugger, which ships with Nargo. -In order to use either version of the debugger, you will need to install recent enough versions of Noir, [Nargo](../getting_started/installation/index.md) and vscode-noir: +In order to use either version of the debugger, you will need to install recent enough versions of Noir, [Nargo](../getting_started/noir_installation.md) and vscode-noir: - Noir & Nargo ≥0.28.0 - Noir's VS Code extension ≥0.0.11 diff --git a/noir/noir-repo/docs/docs/tutorials/noirjs_app.md b/noir/noir-repo/docs/docs/tutorials/noirjs_app.md index eac28168445..6e69ea0bbed 100644 --- a/noir/noir-repo/docs/docs/tutorials/noirjs_app.md +++ b/noir/noir-repo/docs/docs/tutorials/noirjs_app.md @@ -24,13 +24,13 @@ Before we start, we want to make sure we have Node, Nargo and the Barretenberg p We start by opening a terminal and executing `node --version`. If we don't get an output like `v20.10.0`, that means node is not installed. Let's do that by following the handy [nvm guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script). -As for `Nargo`, we can follow the [Nargo guide](../getting_started/installation/index.md) to install it. If you're lazy, just paste this on a terminal and run `noirup`: +As for `Nargo`, we can follow the [Nargo guide](../getting_started/quick_start.md) to install it. If you're lazy, just paste this on a terminal and run `noirup`: ```sh curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash ``` -Follow the instructions on [this page](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg/cpp/src/barretenberg/bb#installation) to install `bb`. +Follow the instructions on [this page](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg/cpp/src/barretenberg/bb#installation) to install `bb`. Version 0.41.0 is compatible with `nargo` version 0.31.0, which you can install with `bbup -v 0.41.0` once `bbup` is installed. Easy enough. Onwards! @@ -78,7 +78,7 @@ At this point in the tutorial, your folder structure should look like this: ### Node and Vite If you want to explore Nargo, feel free to go on a side-quest now and follow the steps in the -[getting started](../getting_started/hello_noir/index.md) guide. However, we want our app to run on the browser, so we need Vite. +[getting started](../getting_started/quick_start.md) guide. However, we want our app to run on the browser, so we need Vite. Vite is a powerful tool to generate static websites. While it provides all kinds of features, let's just go barebones with some good old vanilla JS. @@ -350,13 +350,17 @@ You should also check out the more advanced examples in the [noir-examples repo] ## UltraHonk Backend Barretenberg has recently exposed a new UltraHonk backend. We can use UltraHonk in NoirJS after version 0.33.0. Everything will be the same as the tutorial above, except that the class we need to import will change: + ```js import { UltraHonkBackend, UltraHonkVerifier as Verifier } from '@noir-lang/backend_barretenberg'; ``` + The backend will then be instantiated as such: + ```js const backend = new UltraHonkBackend(circuit); ``` + Then all the commands to prove and verify your circuit will be same. -The only feature currently unsupported with UltraHonk are [recursive proofs](../explainers/explainer-recursion.md). \ No newline at end of file +The only feature currently unsupported with UltraHonk are [recursive proofs](../explainers/explainer-recursion.md). diff --git a/noir/noir-repo/docs/docusaurus.config.ts b/noir/noir-repo/docs/docusaurus.config.ts index 29f612b0109..c7af7e494d1 100644 --- a/noir/noir-repo/docs/docusaurus.config.ts +++ b/noir/noir-repo/docs/docusaurus.config.ts @@ -15,7 +15,7 @@ export default { url: 'https://noir-lang.org', baseUrl: '/', onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'throw', + onBrokenMarkdownLinks: process.env.ENV === 'dev' ? 'warn' : 'throw', i18n: { defaultLocale: 'en', locales: ['en'], @@ -26,7 +26,7 @@ export default { '@docusaurus/preset-classic', { docs: { - path: 'processed-docs', + path: process.env.ENV === 'dev' ? 'docs' : 'processed-docs', sidebarPath: './sidebars.js', routeBasePath: '/docs', remarkPlugins: [math], @@ -48,7 +48,7 @@ export default { ], ], customFields: { - MATOMO_ENV: process.env.MATOMO_ENV, + MATOMO_ENV: process.env.ENV, }, themeConfig: { colorMode: { diff --git a/noir/noir-repo/docs/package.json b/noir/noir-repo/docs/package.json index c81d0b7b24f..39807588eaa 100644 --- a/noir/noir-repo/docs/package.json +++ b/noir/noir-repo/docs/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "preprocess": "yarn workspace @noir-lang/acvm_js build && ./scripts/codegen_nargo_reference.sh && yarn node ./scripts/preprocess/index.js", - "start": "yarn preprocess && MATOMO_ENV=dev docusaurus start", + "dev": "yarn preprocess && ENV=dev docusaurus start", "build": "yarn preprocess && docusaurus build", "clean": "rm -rf ./processed-docs ./processed-docs ./build", "version::stables": "ts-node ./scripts/setStable.ts", @@ -13,8 +13,8 @@ "version": "yarn version::stables && ./scripts/cut_version.sh" }, "dependencies": { - "@docusaurus/core": "^3.0.1", - "@docusaurus/preset-classic": "^3.0.1", + "@docusaurus/core": "^3.5.2", + "@docusaurus/preset-classic": "^3.5.2", "@easyops-cn/docusaurus-search-local": "^0.35.0", "@mdx-js/react": "^3.0.0", "@noir-lang/noir_js": "workspace:*", @@ -31,9 +31,9 @@ "remark-math": "^6.0.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "^3.0.1", - "@docusaurus/tsconfig": "^3.0.1", - "@docusaurus/types": "^3.0.1", + "@docusaurus/module-type-aliases": "^3.5.2", + "@docusaurus/tsconfig": "^3.5.2", + "@docusaurus/types": "^3.5.2", "@types/prettier": "^3", "docusaurus-plugin-typedoc": "1.0.0-next.18", "eslint-plugin-prettier": "^5.1.3", diff --git a/noir/noir-repo/docs/src/pages/index.jsx b/noir/noir-repo/docs/src/pages/index.jsx index e6532b1db85..868df304233 100644 --- a/noir/noir-repo/docs/src/pages/index.jsx +++ b/noir/noir-repo/docs/src/pages/index.jsx @@ -31,7 +31,7 @@ export default function Landing() {

- +
diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/cspell.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/cspell.json new file mode 100644 index 00000000000..c60b0a597b1 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/cspell.json @@ -0,0 +1,5 @@ +{ + "words": [ + "Cryptdoku" + ] +} diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-oracle.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-oracle.md new file mode 100644 index 00000000000..821e1f95c04 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-oracle.md @@ -0,0 +1,57 @@ +--- +title: Oracles +description: This guide provides an in-depth understanding of how Oracles work in Noir programming. Learn how to use outside calculations in your programs, constrain oracles, and understand their uses and limitations. +keywords: + - Noir Programming + - Oracles + - JSON-RPC + - Foreign Call Handlers + - Constrained Functions + - Blockchain Programming +sidebar_position: 1 +--- + +If you've seen "The Matrix" you may recall "The Oracle" as Gloria Foster smoking cigarettes and baking cookies. While she appears to "know things", she is actually providing a calculation of a pre-determined future. Noir Oracles are similar, in a way. They don't calculate the future (yet), but they allow you to use outside calculations in your programs. + +![matrix oracle prediction](@site/static/img/memes/matrix_oracle.jpeg) + +A Noir program is usually self-contained. You can pass certain inputs to it, and it will generate a deterministic output for those inputs. But what if you wanted to defer some calculation to an outside process or source? + +Oracles are functions that provide this feature. + +## Use cases + +An example usage for Oracles is proving something on-chain. For example, proving that the ETH-USDC quote was below a certain target at a certain block time. Or even making more complex proofs like proving the ownership of an NFT as an anonymous login method. + +Another interesting use case is to defer expensive calculations to be made outside of the Noir program, and then constraining the result; similar to the use of [unconstrained functions](../noir/concepts//unconstrained.md). + +In short, anything that can be constrained in a Noir program but needs to be fetched from an external source is a great candidate to be used in oracles. + +## Constraining oracles + +Just like in The Matrix, Oracles are powerful. But with great power, comes great responsibility. Just because you're using them in a Noir program doesn't mean they're true. Noir has no superpowers. If you want to prove that Portugal won the Euro Cup 2016, you're still relying on potentially untrusted information. + +To give a concrete example, Alice wants to login to the [NounsDAO](https://nouns.wtf/) forum with her username "noir_nouner" by proving she owns a noun without revealing her ethereum address. Her Noir program could have an oracle call like this: + +```rust +#[oracle(getNoun)] +unconstrained fn get_noun(address: Field) -> Field +``` + +This oracle could naively resolve with the number of Nouns she possesses. However, it is useless as a trusted source, as the oracle could resolve to anything Alice wants. In order to make this oracle call actually useful, Alice would need to constrain the response from the oracle, by proving her address and the noun count belongs to the state tree of the contract. + +In short, **Oracles don't prove anything. Your Noir program does.** + +:::danger + +If you don't constrain the return of your oracle, you could be clearly opening an attack vector on your Noir program. Make double-triple sure that the return of an oracle call is constrained! + +::: + +## How to use Oracles + +On CLI, Nargo resolves oracles by making JSON RPC calls, which means it would require an RPC node to be running. + +In JavaScript, NoirJS accepts and resolves arbitrary call handlers (that is, not limited to JSON) as long as they match the expected types the developer defines. Refer to [Foreign Call Handler](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) to learn more about NoirJS's call handling. + +If you want to build using oracles, follow through to the [oracle guide](../how_to/how-to-oracles.md) for a simple example on how to do that. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-recursion.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-recursion.md new file mode 100644 index 00000000000..df8529ef4e0 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-recursion.md @@ -0,0 +1,176 @@ +--- +title: Recursive proofs +description: Explore the concept of recursive proofs in Zero-Knowledge programming. Understand how recursion works in Noir, a language for writing smart contracts on the EVM blockchain. Learn through practical examples like Alice and Bob's guessing game, Charlie's recursive merkle tree, and Daniel's reusable components. Discover how to use recursive proofs to optimize computational resources and improve efficiency. + +keywords: + [ + "Recursive Proofs", + "Zero-Knowledge Programming", + "Noir", + "EVM Blockchain", + "Smart Contracts", + "Recursion in Noir", + "Alice and Bob Guessing Game", + "Recursive Merkle Tree", + "Reusable Components", + "Optimizing Computational Resources", + "Improving Efficiency", + "Verification Key", + "Aggregation", + "Recursive zkSNARK schemes", + "PLONK", + "Proving and Verification Keys" + ] +sidebar_position: 1 +pagination_next: how_to/how-to-recursion +--- + +In programming, we tend to think of recursion as something calling itself. A classic example would be the calculation of the factorial of a number: + +```js +function factorial(n) { + if (n === 0 || n === 1) { + return 1; + } else { + return n * factorial(n - 1); + } +} +``` + +In this case, while `n` is not `1`, this function will keep calling itself until it hits the base case, bubbling up the result on the call stack: + +```md + Is `n` 1? <--------- + /\ / + / \ n = n -1 + / \ / + Yes No -------- +``` + +In Zero-Knowledge, recursion has some similarities. + +It is not a Noir function calling itself, but a proof being used as an input to another circuit. In short, you verify one proof *inside* another proof, returning the proof that both proofs are valid. + +This means that, given enough computational resources, you can prove the correctness of any arbitrary number of proofs in a single proof. This could be useful to design state channels (for which a common example would be [Bitcoin's Lightning Network](https://en.wikipedia.org/wiki/Lightning_Network)), to save on gas costs by settling one proof on-chain, or simply to make business logic less dependent on a consensus mechanism. + +## Examples + +Let us look at some of these examples + +### Alice and Bob - Guessing game + +Alice and Bob are friends, and they like guessing games. They want to play a guessing game online, but for that, they need a trusted third-party that knows both of their secrets and finishes the game once someone wins. + +So, they use zero-knowledge proofs. Alice tries to guess Bob's number, and Bob will generate a ZK proof stating whether she succeeded or failed. + +This ZK proof can go on a smart contract, revealing the winner and even giving prizes. However, this means every turn needs to be verified on-chain. This incurs some cost and waiting time that may simply make the game too expensive or time-consuming to be worth it. + +As a solution, Alice proposes the following: "what if Bob generates his proof, and instead of sending it on-chain, I verify it *within* my own proof before playing my own turn?". + +She can then generate a proof that she verified his proof, and so on. + +```md + Did you fail? <-------------------------- + / \ / + / \ n = n -1 + / \ / + Yes No / + | | / + | | / + | You win / + | / + | / +Generate proof of that / + + / + my own guess ---------------- +``` + +### Charlie - Recursive merkle tree + +Charlie is a concerned citizen, and wants to be sure his vote in an election is accounted for. He votes with a ZK proof, but he has no way of knowing that his ZK proof was included in the total vote count! + +If the vote collector puts all of the votes into a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree), everyone can prove the verification of two proofs within one proof, as such: + +```md + abcd + __________|______________ + | | + ab cd + _____|_____ ______|______ + | | | | + alice bob charlie daniel +``` + +Doing this recursively allows us to arrive on a final proof `abcd` which if true, verifies the correctness of all the votes. + +### Daniel - Reusable components + +Daniel has a big circuit and a big headache. A part of his circuit is a setup phase that finishes with some assertions that need to be made. But that section alone takes most of the proving time, and is largely independent of the rest of the circuit. + +He might find it more efficient to generate a proof for that setup phase separately, and verify that proof recursively in the actual business logic section of his circuit. This will allow for parallelization of both proofs, which results in a considerable speedup. + +## What params do I need + +As you can see in the [recursion reference](noir/standard_library/recursion.mdx), a simple recursive proof requires: + +- The proof to verify +- The Verification Key of the circuit that generated the proof +- A hash of this verification key, as it's needed for some backends +- The public inputs for the proof + +:::info + +Recursive zkSNARK schemes do not necessarily "verify a proof" in the sense that you expect a true or false to be spit out by the verifier. Rather an aggregation object is built over the public inputs. + +So, taking the example of Alice and Bob and their guessing game: + +- Alice makes her guess. Her proof is *not* recursive: it doesn't verify any proof within it! It's just a standard `assert(x != y)` circuit +- Bob verifies Alice's proof and makes his own guess. In this circuit, he doesn't exactly *prove* the verification of Alice's proof. Instead, he *aggregates* his proof to Alice's proof. The actual verification is done when the full proof is verified, for example when using `nargo verify` or through the verifier smart contract. + +We can imagine recursive proofs a [relay race](https://en.wikipedia.org/wiki/Relay_race). The first runner doesn't have to receive the baton from anyone else, as he/she already starts with it. But when his/her turn is over, the next runner needs to receive it, run a bit more, and pass it along. Even though every runner could theoretically verify the baton mid-run (why not? 🏃🔍), only at the end of the race does the referee verify that the whole race is valid. + +::: + +## Some architecture + +As with everything in computer science, there's no one-size-fits all. But there are some patterns that could help understanding and implementing them. To give three examples: + +### Adding some logic to a proof verification + +This would be an approach for something like our guessing game, where proofs are sent back and forth and are verified by each opponent. This circuit would be divided in two sections: + +- A `recursive verification` section, which would be just the call to `std::verify_proof`, and that would be skipped on the first move (since there's no proof to verify) +- A `guessing` section, which is basically the logic part where the actual guessing happens + +In such a situation, and assuming Alice is first, she would skip the first part and try to guess Bob's number. Bob would then verify her proof on the first section of his run, and try to guess Alice's number on the second part, and so on. + +### Aggregating proofs + +In some one-way interaction situations, recursion would allow for aggregation of simple proofs that don't need to be immediately verified on-chain or elsewhere. + +To give a practical example, a barman wouldn't need to verify a "proof-of-age" on-chain every time he serves alcohol to a customer. Instead, the architecture would comprise two circuits: + +- A `main`, non-recursive circuit with some logic +- A `recursive` circuit meant to verify two proofs in one proof + +The customer's proofs would be intermediate, and made on their phones, and the barman could just verify them locally. He would then aggregate them into a final proof sent on-chain (or elsewhere) at the end of the day. + +### Recursively verifying different circuits + +Nothing prevents you from verifying different circuits in a recursive proof, for example: + +- A `circuit1` circuit +- A `circuit2` circuit +- A `recursive` circuit + +In this example, a regulator could verify that taxes were paid for a specific purchase by aggregating both a `payer` circuit (proving that a purchase was made and taxes were paid), and a `receipt` circuit (proving that the payment was received) + +## How fast is it + +At the time of writing, verifying recursive proofs is surprisingly fast. This is because most of the time is spent on generating the verification key that will be used to generate the next proof. So you are able to cache the verification key and reuse it later. + +Currently, Noir JS packages don't expose the functionality of loading proving and verification keys, but that feature exists in the underlying `bb.js` package. + +## How can I try it + +Learn more about using recursion in Nargo and NoirJS in the [how-to guide](../how_to/how-to-recursion.md) and see a full example in [noir-examples](https://github.com/noir-lang/noir-examples). diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-writing-noir.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-writing-noir.md new file mode 100644 index 00000000000..3ef6e014a2f --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/explainers/explainer-writing-noir.md @@ -0,0 +1,177 @@ +--- +title: Writing Performant Noir +description: Understand new considerations when writing Noir +keywords: [Noir, programming, rust] +tags: [Optimization] +sidebar_position: 0 +--- + + +This article intends to set you up with key concepts essential for writing more viable applications that use zero knowledge proofs, namely around efficient circuits. + +## Context - 'Efficient' is subjective + +When writing a web application for a performant computer with high-speed internet connection, writing efficient code sometimes is seen as an afterthought only if needed. Large multiplications running at the innermost of nested loops may not even be on a dev's radar. +When writing firmware for a battery-powered microcontroller, you think of cpu cycles as rations to keep within a product's power budget. + +> Code is written to create applications that perform specific tasks within specific constraints + +And these constraints differ depending on where the compiled code is execute. + +### The Ethereum Virtual Machine (EVM) + +In scenarios where extremely low gas costs are required for an Ethereum application to be viable/competitive, Ethereum smart contract developers get into what is colloquially known as: "*gas golfing*". Finding the lowest execution cost of their compiled code (EVM bytecode) to achieve a specific task. + +The equivalent optimization task when writing zk circuits is affectionately referred to as "*gate golfing*", finding the lowest gate representation of the compiled Noir code. + +### Coding for circuits - a paradigm shift + +In zero knowledge cryptography, code is compiled to "circuits" consisting of arithmetic gates, and gate count is the significant cost. Depending on the proving system this is linearly proportionate to proving time, and so from a product point this should be kept as low as possible. + +Whilst writing efficient code for web apps and Solidity has a few key differences, writing efficient circuits have a different set of considerations. It is a bit of a paradigm shift, like writing code for GPUs for the first time... + +For example, drawing a circle at (0, 0) of radius `r`: +- For a single CPU thread, +``` +for theta in 0..2*pi { + let x = r * cos(theta); + let y = r * sin(theta); + draw(x, y); +} // note: would do 0 - pi/2 and draw +ve/-ve x and y. +``` + +- For GPUs (simultaneous parallel calls with x, y across image), +``` +if (x^2 + y^2 = r^2) { + draw(x, y); +} +``` + +([Related](https://www.youtube.com/watch?v=-P28LKWTzrI)) + +Whilst this CPU -> GPU does not translate to circuits exactly, it is intended to exemplify the difference in intuition when coding for different machine capabilities/constraints. + +### Context Takeaway + +For those coming from a primarily web app background, this article will explain what you need to consider when writing circuits. Furthermore, for those experienced writing efficient machine code, prepare to shift what you think is efficient 😬 + +## Translating from Rust + +For some applications using Noir, existing code might be a convenient starting point to then proceed to optimize the gate count of. + +:::note +Many valuable functions and algorithms have been written in more established languages (C/C++), and converted to modern ones (like Rust). +::: + +Fortunately for Noir developers, when needing a particular function a Rust implementation can be readily compiled into Noir with some key changes. While the compiler does a decent amount of optimizations, it won't be able to change code that has been optimized for clock-cycles into code optimized for arithmetic gates. + +A few things to do when converting Rust code to Noir: +- `println!` is not a macro, use `println` function (same for `assert_eq`) +- No early `return` in function. Use constrain via assertion instead +- No passing by reference. Remove `&` operator to pass by value (copy) +- No boolean operators (`&&`, `||`). Use bitwise operators (`&`, `|`) with boolean values +- No type `usize`. Use types `u8`, `u32`, `u64`, ... +- `main` return must be public, `pub` +- No `const`, use `global` +- Noir's LSP is your friend, so error message should be informative enough to resolve syntax issues. + +## Writing efficient Noir for performant products + +The following points help refine our understanding over time. + +:::note +A Noir program makes a statement that can be verified. +::: + +It compiles to a structure that represents the calculation, and can assert results within the calculation at any stage (via the `constrain` keyword). + +A Noir program compiles to an Abstract Circuit Intermediate Representation which is: + - Conceptually a tree structure + - Leaves (inputs) are the `Field` type + - Nodes contain arithmetic operations to combine them (gates) + - The root is the final result (return value) + +:::tip +The command `nargo info` shows the programs circuit size, and is useful to compare the value of changes made. +You can dig deeper and use the `--print-acir` param to take a closer look at individual ACIR opcodes, and the proving backend to see its gate count (eg for barretenberg, `bb gates -b ./target/program.json`). +::: + +### Use the `Field` type + +Since the native type of values in circuits are `Field`s, using them for variables in Noir means less gates converting them under the hood. +Some things to be mindful of when using a Field type for a regular integer value: +- A variable of type `Field` can be cast `as` an integer type (eg `u8`, `u64`) + - Note: this retains only the bits of the integer type. Eg a Field value of 260 as a `u8` becomes 4 +- For Field types arithmetic operations meaningfully overflow/underflow, yet for integer types they are checked according to their size +- Comparisons and bitwise operations do not exist for `Field`s, cast to an appropriately sized integer type when you need to + +:::tip +Where possible, use `Field` type for values. Using smaller value types, and bit-packing strategies, will result in MORE gates +::: + + +### Use Arithmetic over non-arithmetic operations + +Since circuits are made of arithmetic gates, the cost of arithmetic operations tends to be one gate. Whereas for procedural code, they represent several clock cycles. + +Inversely, non-arithmetic operators are achieved with multiple gates, vs 1 clock cycle for procedural code. + +| (cost\op) | arithmetic
(`*`, `+`) | bit-wise ops
(eg `<`, `\|`, `>>`) | +| - | - | - | +| **cycles** | 10+ | 1 | +| **gates** | 1 | 10+ | + +Bit-wise operations (e.g. bit shifts `<<` and `>>`), albeit commonly used in general programming and especially for clock cycle optimizations, are on the contrary expensive in gates when performed within circuits. + +Translate away from bit shifts when writing constrained functions for the best performance. + +On the flip side, feel free to use bit shifts in unconstrained functions and tests if necessary, as they are executed outside of circuits and does not induce performance hits. + +### Use static over dynamic values + +Another general theme that manifests in different ways is that static reads are represented with less gates than dynamic ones. + +Reading from read-only memory (ROM) adds less gates than random-access memory (RAM), 2 vs ~3.25 due to the additional bounds checks. Arrays of fixed length (albeit used at a lower capacity), will generate less gates than dynamic storage. + +Related to this, if an index used to access an array is not known at compile time (ie unknown until run time), then ROM will be converted to RAM, expanding the gate count. + +:::tip +Use arrays and indices that are known at compile time where possible. +Using `assert_constant(i);` before an index, `i`, is used in an array will give a compile error if `i` is NOT known at compile time. +::: + +### Leverage unconstrained execution + +Constrained verification can leverage unconstrained execution, this is especially useful for operations that are represented by many gates. +Use an [unconstrained function](../noir/concepts/unconstrained.md) to perform gate-heavy calculations, then verify and constrain the result. + +Eg division generates more gates than multiplication, so calculating the quotient in an unconstrained function then constraining the product for the quotient and divisor (+ any remainder) equals the dividend will be more efficient. + +Use ` if is_unconstrained() { /`, to conditionally execute code if being called in an unconstrained vs constrained way. + +## Advanced + +Unless you're well into the depth of gate optimization, this advanced section can be ignored. + +### Combine arithmetic operations + +A Noir program can be honed further by combining arithmetic operators in a way that makes the most of each constraint of the backend proving system. This is in scenarios where the backend might not be doing this perfectly. + +Eg Barretenberg backend (current default for Noir) is a width-4 PLONKish constraint system +$ w_1*w_2*q_m + w_1*q_1 + w_2*q_2 + w_3*q_3 + w_4*q_4 + q_c = 0 $ + +Here we see there is one occurrence of witness 1 and 2 ($w_1$, $w_2$) being multiplied together, with addition to witnesses 1-4 ($w_1$ .. $w_4$) multiplied by 4 corresponding circuit constants ($q_1$ .. $q_4$) (plus a final circuit constant, $q_c$). + +Use `nargo info --print-acir`, to inspect the ACIR opcodes (and the proving system for gates), and it may present opportunities to amend the order of operations and reduce the number of constraints. + +#### Variable as witness vs expression + +If you've come this far and really know what you're doing at the equation level, a temporary lever (that will become unnecessary/useless over time) is: `std::as_witness`. This informs the compiler to save a variable as a witness not an expression. + +The compiler will mostly be correct and optimal, but this may help some near term edge cases that are yet to optimize. +Note: When used incorrectly it will create **less** efficient circuits (higher gate count). + +## References +- Guillaume's ["`Cryptdoku`" talk](https://www.youtube.com/watch?v=MrQyzuogxgg) (Jun'23) +- Tips from Tom, Jake and Zac. +- [Idiomatic Noir](https://www.vlayer.xyz/blog/idiomatic-noir-part-1-collections) blog post diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/noir_installation.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/noir_installation.md new file mode 100644 index 00000000000..f92fd8dea38 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/noir_installation.md @@ -0,0 +1,102 @@ +--- +title: Standalone Noir Installation +description: There are different ways to install Nargo, the one-stop shop and command-line tool for developing Noir programs. This guide explains how to specify which version to install when using noirup, and using WSL for windows. +keywords: [ + Installation + Nargo + Noirup + Binaries + Compiling from Source + WSL for Windows + macOS + Linux + Nix + Direnv + Uninstalling Nargo + ] +sidebar_position: 2 +--- + +Noirup is the endorsed method for installing Nargo, streamlining the process of fetching binaries or compiling from source. It supports a range of options to cater to your specific needs, from nightly builds and specific versions to compiling from various sources. + +### Installing Noirup + +First, ensure you have `noirup` installed: + +```sh +curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +``` + +### Fetching Binaries + +With `noirup`, you can easily switch between different Nargo versions, including nightly builds: + +- **Nightly Version**: Install the latest nightly build. + + ```sh + noirup --version nightly + ``` + +- **Specific Version**: Install a specific version of Nargo. + + ```sh + noirup --version + ``` + +### Compiling from Source + +`noirup` also enables compiling Nargo from various sources: + +- **From a Specific Branch**: Install from the latest commit on a branch. + + ```sh + noirup --branch + ``` + +- **From a Fork**: Install from the main branch of a fork. + + ```sh + noirup --repo + ``` + +- **From a Specific Branch in a Fork**: Install from a specific branch in a fork. + + ```sh + noirup --repo --branch + ``` + +- **From a Specific Pull Request**: Install from a specific PR. + + ```sh + noirup --pr + ``` + +- **From a Specific Commit**: Install from a specific commit. + + ```sh + noirup -C + ``` + +- **From Local Source**: Compile and install from a local directory. + + ```sh + noirup --path ./path/to/local/source + ``` + +## Installation on Windows + +The default backend for Noir (Barretenberg) doesn't provide Windows binaries at this time. For that reason, Noir cannot be installed natively. However, it is available by using Windows Subsystem for Linux (WSL). + +Step 1: Follow the instructions [here](https://learn.microsoft.com/en-us/windows/wsl/install) to install and run WSL. + +step 2: Follow the [Noirup instructions](#installing-noirup). + +## Uninstalling Nargo + +If you installed Nargo with `noirup`, you can uninstall Nargo by removing the files in `~/.nargo`, `~/nargo`, and `~/noir_cache`. This ensures that all installed binaries, configurations, and cache related to Nargo are fully removed from your system. + +```bash +rm -r ~/.nargo +rm -r ~/nargo +rm -r ~/noir_cache +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/project_breakdown.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/project_breakdown.md new file mode 100644 index 00000000000..e442e377040 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/project_breakdown.md @@ -0,0 +1,159 @@ +--- +title: Project Breakdown +description: + Learn about the anatomy of a Nargo project, including the purpose of the Prover TOML + file, and how to prove and verify your program. +keywords: + [Nargo, Nargo project, Prover.toml, proof verification, private asset transfer] +sidebar_position: 1 +--- + +This section breaks down our hello world program from the previous section. + +## Anatomy of a Nargo Project + +Upon creating a new project with `nargo new` and building the in/output files with `nargo check` +commands, you would get a minimal Nargo project of the following structure: + + - src + - Prover.toml + - Nargo.toml + +The source directory _src_ holds the source code for your Noir program. By default only a _main.nr_ +file will be generated within it. + +### Prover.toml + +_Prover.toml_ is used for specifying the input values for executing and proving the program. You can specify `toml` files with different names by using the `--prover-name` or `-p` flags, see the [Prover](#provertoml) section below. Optionally you may specify expected output values for prove-time checking as well. + +### Nargo.toml + +_Nargo.toml_ contains the environmental options of your project. It contains a "package" section and a "dependencies" section. + +Example Nargo.toml: + +```toml +[package] +name = "noir_starter" +type = "bin" +authors = ["Alice"] +compiler_version = "0.9.0" +description = "Getting started with Noir" +entry = "circuit/main.nr" +license = "MIT" + +[dependencies] +ecrecover = {tag = "v0.9.0", git = "https://github.com/colinnielsen/ecrecover-noir.git"} +``` + +Nargo.toml for a [workspace](../noir/modules_packages_crates/workspaces.md) will look a bit different. For example: + +```toml +[workspace] +members = ["crates/a", "crates/b"] +default-member = "crates/a" +``` + +#### Package section + +The package section defines a number of fields including: + +- `name` (**required**) - the name of the package +- `type` (**required**) - can be "bin", "lib", or "contract" to specify whether its a binary, library or Aztec contract +- `authors` (optional) - authors of the project +- `compiler_version` - specifies the version of the compiler to use. This is enforced by the compiler and follow's [Rust's versioning](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field), so a `compiler_version = 0.18.0` will enforce Nargo version 0.18.0, `compiler_version = ^0.18.0` will enforce anything above 0.18.0 but below 0.19.0, etc. For more information, see how [Rust handles these operators](https://docs.rs/semver/latest/semver/enum.Op.html) +- `description` (optional) +- `entry` (optional) - a relative filepath to use as the entry point into your package (overrides the default of `src/lib.nr` or `src/main.nr`) +- `backend` (optional) +- `license` (optional) +- `expression_width` (optional) - Sets the default backend expression width. This field will override the default backend expression width specified by the Noir compiler (currently set to width 4). + +#### Dependencies section + +This is where you will specify any dependencies for your project. See the [Dependencies page](../noir/modules_packages_crates/dependencies.md) for more info. + +`./proofs/` and `./contract/` directories will not be immediately visible until you create a proof or +verifier contract respectively. + +### main.nr + +The _main.nr_ file contains a `main` method, this method is the entry point into your Noir program. + +In our sample program, _main.nr_ looks like this: + +```rust +fn main(x : Field, y : Field) { + assert(x != y); +} +``` + +The parameters `x` and `y` can be seen as the API for the program and must be supplied by the prover. Since neither `x` nor `y` is marked as public, the verifier does not supply any inputs, when verifying the proof. + +The prover supplies the values for `x` and `y` in the _Prover.toml_ file. + +As for the program body, `assert` ensures that the condition to be satisfied (e.g. `x != y`) is constrained by the proof of the execution of said program (i.e. if the condition was not met, the verifier would reject the proof as an invalid proof). + +### Prover.toml + +The _Prover.toml_ file is a file which the prover uses to supply the inputs to the Noir program (both private and public). + +In our hello world program the _Prover.toml_ file looks like this: + +```toml +x = "1" +y = "2" +``` + +When the command `nargo execute` is executed, nargo will execute the Noir program using the inputs specified in `Prover.toml`, aborting if it finds that these do not satisfy the constraints defined by `main`. In this example, `x` and `y` must satisfy the inequality constraint `assert(x != y)`. + +If an output name is specified such as `nargo execute foo`, the witness generated by this execution will be written to `./target/foo.gz`. This can then be used to generate a proof of the execution. + +#### Arrays of Structs + +The following code shows how to pass an array of structs to a Noir program to generate a proof. + +```rust +// main.nr +struct Foo { + bar: Field, + baz: Field, +} + +fn main(foos: [Foo; 3]) -> pub Field { + foos[2].bar + foos[2].baz +} +``` + +Prover.toml: + +```toml +[[foos]] # foos[0] +bar = 0 +baz = 0 + +[[foos]] # foos[1] +bar = 0 +baz = 0 + +[[foos]] # foos[2] +bar = 1 +baz = 2 +``` + +#### Custom toml files + +You can specify a `toml` file with a different name to use for execution by using the `--prover-name` or `-p` flags. + +This command looks for proof inputs in the default **Prover.toml** and generates the witness and saves it at `./target/foo.gz`: + +```bash +nargo execute foo +``` + +This command looks for proof inputs in the custom **OtherProver.toml** and generates the witness and saves it at `./target/bar.gz`: + +```bash +nargo execute -p OtherProver bar +``` + +Now that you understand the concepts, you'll probably want some editor feedback while you are writing more complex code. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/quick_start.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/quick_start.md new file mode 100644 index 00000000000..4ce48409818 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/getting_started/quick_start.md @@ -0,0 +1,124 @@ +--- +title: Quick Start +tags: [] +sidebar_position: 0 +--- + +## Installation + +### Noir + +The easiest way to develop with Noir is using Nargo the CLI tool. It provides you the ability to start new projects, compile, execute and test Noir programs from the terminal. + +You can use `noirup` the installation script to quickly install and update Nargo: + +```bash +curl -L noirup.dev | bash +noirup +``` + +### Proving backend + +After installing Noir, we install a proving backend to work with our Noir programs. + +Proving backends provide you the abilities to generate proofs, verify proofs, generate smart contracts and more for your Noir programs. + +Different proving backends provide different tools for working with Noir programs, here we will use the [Barretenberg proving backend](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg) developed by Aztec Labs as an example. + +You can use the `bbup` installation script to quickly install and update BB, Barretenberg's CLI tool: + +You can find the full list of proving backends compatible with Noir in Awesome Noir. + +```bash +curl -L bbup.dev | bash +bbup +``` + +For the full list of proving backends compatible with Noir, visit [Awesome Noir](https://github.com/noir-lang/awesome-noir/?tab=readme-ov-file#proving-backends). + +## Nargo + +Nargo provides the ability to initiate and execute Noir projects. Let's initialize the traditional `hello_world`: + +```sh +nargo new hello_world +``` + +Two files will be created. + +- `src/main.nr` contains a simple boilerplate circuit +- `Nargo.toml` contains environmental options, such as name, author, dependencies, and others. + +Glancing at _main.nr_ , we can see that inputs in Noir are private by default, but can be labeled public using the keyword `pub`. This means that we will _assert_ that we know a value `x` which is different from `y` without revealing `x`: + +```rust +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` + +To learn more about private and public values, check the [Data Types](../noir/concepts/data_types/index.md) section. + +### Compiling and executing + +We can now use `nargo` to generate a _Prover.toml_ file, where our input values will be specified: + +```sh +cd hello_world +nargo check + +Let's feed some valid values into this file: + +```toml +x = "1" +y = "2" +``` + +We're now ready to compile and execute our Noir program. By default the `nargo execute` command will do both, and generate the `witness` that we need to feed to our proving backend: + +```sh +nargo execute +``` + +The witness corresponding to this execution will then be written to the file _./target/witness-name.gz_. + +The command also automatically compiles your Noir program if it was not already / was edited, which you may notice the compiled artifacts being written to the file _./target/hello_world.json_. + +With circuit compiled and witness generated, we're ready to prove. + +## Proving backend + +Different proving backends may provide different tools and commands to work with Noir programs. Here Barretenberg's `bb` CLI tool is used as an example: + +```sh +bb prove -b ./target/hello_world.json -w ./target/hello_world.gz -o ./target/proof +``` + +:::tip + +Naming can be confusing, specially as you pass them to the `bb` commands. If unsure, it won't hurt to delete the target folder and start anew to make sure you're using the most recent versions of the compiled circuit and witness. + +::: + +The proof is now generated in the `target` folder. To verify it we first need to compute the verification key from the compiled circuit, and use it to verify: + +```sh +bb write_vk -b ./target/hello_world.json -o ./target/vk +bb verify -k ./target/vk -p ./target/proof +``` + +:::info + +Notice that in order to verify a proof, the verifier knows nothing but the circuit, which is compiled and used to generate the verification key. This is obviously quite important: private inputs remain private. + +As for the public inputs, you may have noticed they haven't been specified. This behavior varies with each particular backend, but barretenberg typically attaches them to the proof. You can see them by parsing and splitting it. For example for if your public inputs are 32 bytes: + +```bash +head -c 32 ./target/proof | od -An -v -t x1 | tr -d $' \n' +``` + +::: + +Congratulations, you have now created and verified a proof for your very first Noir program! + +In the [next section](./project_breakdown.md), we will go into more detail on each step performed. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/_category_.json new file mode 100644 index 00000000000..cc2cbb1c253 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "Debugging", + "position": 5, + "collapsible": true, + "collapsed": true +} diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_the_repl.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_the_repl.md new file mode 100644 index 00000000000..09e5bae68ad --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_the_repl.md @@ -0,0 +1,164 @@ +--- +title: Using the REPL Debugger +description: + Step by step guide on how to debug your Noir circuits with the REPL Debugger. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + REPL, + ] +sidebar_position: 1 +--- + +#### Pre-requisites + +In order to use the REPL debugger, first you need to install recent enough versions of Nargo and vscode-noir. + +## Debugging a simple circuit + +Let's debug a simple circuit: + +```rust +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` + +To start the REPL debugger, using a terminal, go to a Noir circuit's home directory. Then: + +`$ nargo debug` + +You should be seeing this in your terminal: + +``` +[main] Starting debugger +At ~/noir-examples/recursion/circuits/main/src/main.nr:1:9 + 1 -> fn main(x : Field, y : pub Field) { + 2 assert(x != y); + 3 } +> +``` + +The debugger displays the current Noir code location, and it is now waiting for us to drive it. + +Let's first take a look at the available commands. For that we'll use the `help` command. + +``` +> help +Available commands: + + opcodes display ACIR opcodes + into step into to the next opcode + next step until a new source location is reached + out step until a new source location is reached + and the current stack frame is finished + break LOCATION:OpcodeLocation add a breakpoint at an opcode location + over step until a new source location is reached + without diving into function calls + restart restart the debugging session + delete LOCATION:OpcodeLocation delete breakpoint at an opcode location + witness show witness map + witness index:u32 display a single witness from the witness map + witness index:u32 value:String update a witness with the given value + memset index:usize value:String update a memory cell with the given + value + continue continue execution until the end of the + program + vars show variable values available at this point + in execution + stacktrace display the current stack trace + memory show memory (valid when executing unconstrained code) + step step to the next ACIR opcode + +Other commands: + + help Show this help message + quit Quit repl + +``` + +Some commands operate only for unconstrained functions, such as `memory` and `memset`. If you try to use them while execution is paused at an ACIR opcode, the debugger will simply inform you that you are not executing unconstrained code: + +``` +> memory +Unconstrained VM memory not available +> +``` + +Before continuing, we can take a look at the initial witness map: + +``` +> witness +_0 = 1 +_1 = 2 +> +``` + +Cool, since `x==1`, `y==2`, and we want to check that `x != y`, our circuit should succeed. At this point we could intervene and use the witness setter command to change one of the witnesses. Let's set `y=3`, then back to 2, so we don't affect the expected result: + +``` +> witness +_0 = 1 +_1 = 2 +> witness 1 3 +_1 = 3 +> witness +_0 = 1 +_1 = 3 +> witness 1 2 +_1 = 2 +> witness +_0 = 1 +_1 = 2 +> +``` + +Now we can inspect the current state of local variables. For that we use the `vars` command. + +``` +> vars +> +``` + +We currently have no vars in context, since we are at the entry point of the program. Let's use `next` to execute until the next point in the program. + +``` +> vars +> next +At ~/noir-examples/recursion/circuits/main/src/main.nr:1:20 + 1 -> fn main(x : Field, y : pub Field) { + 2 assert(x != y); + 3 } +> vars +x:Field = 0x01 +``` + +As a result of stepping, the variable `x`, whose initial value comes from the witness map, is now in context and returned by `vars`. + +``` +> next + 1 fn main(x : Field, y : pub Field) { + 2 -> assert(x != y); + 3 } +> vars +y:Field = 0x02 +x:Field = 0x01 +``` + +Stepping again we can finally see both variables and their values. And now we can see that the next assertion should succeed. + +Let's continue to the end: + +``` +> continue +(Continuing execution...) +Finished execution +> q +[main] Circuit witness successfully solved +``` + +Upon quitting the debugger after a solved circuit, the resulting circuit witness gets saved, equivalent to what would happen if we had run the same circuit with `nargo execute`. + +We just went through the basics of debugging using Noir REPL debugger. For a comprehensive reference, check out [the reference page](../../reference/debugger/debugger_repl.md). diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_vs_code.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_vs_code.md new file mode 100644 index 00000000000..a5858c1a5eb --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/debugger/debugging_with_vs_code.md @@ -0,0 +1,68 @@ +--- +title: Using the VS Code Debugger +description: + Step by step guide on how to debug your Noir circuits with the VS Code Debugger configuration and features. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + VS Code, + IDE, + ] +sidebar_position: 0 +--- + +This guide will show you how to use VS Code with the vscode-noir extension to debug a Noir project. + +#### Pre-requisites + +- Nargo +- vscode-noir +- A Noir project with a `Nargo.toml`, `Prover.toml` and at least one Noir (`.nr`) containing an entry point function (typically `main`). + +## Running the debugger + +The easiest way to start debugging is to open the file you want to debug, and press `F5`. This will cause the debugger to launch, using your `Prover.toml` file as input. + +You should see something like this: + +![Debugger launched](@site/static/img/debugger/1-started.png) + +Let's inspect the state of the program. For that, we open VS Code's _Debug pane_. Look for this icon: + +![Debug pane icon](@site/static/img/debugger/2-icon.png) + +You will now see two categories of variables: Locals and Witness Map. + +![Debug pane expanded](@site/static/img/debugger/3-debug-pane.png) + +1. **Locals**: variables of your program. At this point in execution this section is empty, but as we step through the code it will get populated by `x`, `result`, `digest`, etc. + +2. **Witness map**: these are initially populated from your project's `Prover.toml` file. In this example, they will be used to populate `x` and `result` at the beginning of the `main` function. + +Most of the time you will probably be focusing mostly on locals, as they represent the high level state of your program. + +You might be interested in inspecting the witness map in case you are trying to solve a really low level issue in the compiler or runtime itself, so this concerns mostly advanced or niche users. + +Let's step through the program, by using the debugger buttons or their corresponding keyboard shortcuts. + +![Debugger buttons](@site/static/img/debugger/4-debugger-buttons.png) + +Now we can see in the variables pane that there's values for `digest`, `result` and `x`. + +![Inspecting locals](@site/static/img/debugger/5-assert.png) + +We can also inspect the values of variables by directly hovering on them on the code. + +![Hover locals](@site/static/img/debugger/6-hover.png) + +Let's set a break point at the `keccak256` function, so we can continue execution up to the point when it's first invoked without having to go one step at a time. + +We just need to click the to the right of the line number 18. Once the breakpoint appears, we can click the `continue` button or use its corresponding keyboard shortcut (`F5` by default). + +![Breakpoint](@site/static/img/debugger/7-break.png) + +Now we are debugging the `keccak256` function, notice the _Call Stack pane_ at the lower right. This lets us inspect the current call stack of our process. + +That covers most of the current debugger functionalities. Check out [the reference](../../reference/debugger/debugger_vscode.md) for more details on how to configure the debugger. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-oracles.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-oracles.md new file mode 100644 index 00000000000..dc49b192384 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-oracles.md @@ -0,0 +1,273 @@ +--- +title: How to use Oracles +description: Learn how to use oracles in your Noir program with examples in both Nargo and NoirJS. This guide also covers writing a JSON RPC server and providing custom foreign call handlers for NoirJS. +keywords: + - Noir Programming + - Oracles + - Nargo + - NoirJS + - JSON RPC Server + - Foreign Call Handlers +sidebar_position: 1 +--- + +This guide shows you how to use oracles in your Noir program. For the sake of clarity, it assumes that: + +- You have read the [explainer on Oracles](../explainers/explainer-oracle.md) and are comfortable with the concept. +- You have a Noir program to add oracles to. You can create one using the [vite-hardhat starter](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) as a boilerplate. +- You understand the concept of a JSON-RPC server. Visit the [JSON-RPC website](https://www.jsonrpc.org/) if you need a refresher. +- You are comfortable with server-side JavaScript (e.g. Node.js, managing packages, etc.). + +For reference, you can find the snippets used in this tutorial on the [Aztec DevRel Repository](https://github.com/AztecProtocol/dev-rel/tree/main/code-snippets/how-to-oracles). + +## Rundown + +This guide has 3 major steps: + +1. How to modify our Noir program to make use of oracle calls as unconstrained functions +2. How to write a JSON RPC Server to resolve these oracle calls with Nargo +3. How to use them in Nargo and how to provide a custom resolver in NoirJS + +## Step 1 - Modify your Noir program + +An oracle is defined in a Noir program by defining two methods: + +- An unconstrained method - This tells the compiler that it is executing an [unconstrained functions](../noir/concepts//unconstrained.md). +- A decorated oracle method - This tells the compiler that this method is an RPC call. + +An example of an oracle that returns a `Field` would be: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt(number: Field) -> Field { } + +unconstrained fn get_sqrt(number: Field) -> Field { + sqrt(number) +} +``` + +In this example, we're wrapping our oracle function in an unconstrained method, and decorating it with `oracle(getSqrt)`. We can then call the unconstrained function as we would call any other function: + +```rust +fn main(input: Field) { + let sqrt = get_sqrt(input); +} +``` + +In the next section, we will make this `getSqrt` (defined on the `sqrt` decorator) be a method of the RPC server Noir will use. + +:::danger + +As explained in the [Oracle Explainer](../explainers/explainer-oracle.md), this `main` function is unsafe unless you constrain its return value. For example: + +```rust +fn main(input: Field) { + let sqrt = get_sqrt(input); + assert(sqrt.pow_32(2) as u64 == input as u64); // <---- constrain the return of an oracle! +} +``` + +::: + +:::info + +Currently, oracles only work with single params or array params. For example: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt([Field; 2]) -> [Field; 2] { } +``` + +::: + +## Step 2 - Write an RPC server + +Brillig will call *one* RPC server. Most likely you will have to write your own, and you can do it in whatever language you prefer. In this guide, we will do it in Javascript. + +Let's use the above example of an oracle that consumes an array with two `Field` and returns their square roots: + +```rust +#[oracle(getSqrt)] +unconstrained fn sqrt(input: [Field; 2]) -> [Field; 2] { } + +unconstrained fn get_sqrt(input: [Field; 2]) -> [Field; 2] { + sqrt(input) +} + +fn main(input: [Field; 2]) { + let sqrt = get_sqrt(input); + assert(sqrt[0].pow_32(2) as u64 == input[0] as u64); + assert(sqrt[1].pow_32(2) as u64 == input[1] as u64); +} +``` + +:::info + +Why square root? + +In general, computing square roots is computationally more expensive than multiplications, which takes a toll when speaking about ZK applications. In this case, instead of calculating the square root in Noir, we are using our oracle to offload that computation to be made in plain. In our circuit we can simply multiply the two values. + +::: + +Now, we should write the correspondent RPC server, starting with the [default JSON-RPC 2.0 boilerplate](https://www.npmjs.com/package/json-rpc-2.0#example): + +```js +import { JSONRPCServer } from "json-rpc-2.0"; +import express from "express"; +import bodyParser from "body-parser"; + +const app = express(); +app.use(bodyParser.json()); + +const server = new JSONRPCServer(); +app.post("/", (req, res) => { + const jsonRPCRequest = req.body; + server.receive(jsonRPCRequest).then((jsonRPCResponse) => { + if (jsonRPCResponse) { + res.json(jsonRPCResponse); + } else { + res.sendStatus(204); + } + }); +}); + +app.listen(5555); +``` + +Now, we will add our `getSqrt` method, as expected by the `#[oracle(getSqrt)]` decorator in our Noir code. It maps through the params array and returns their square roots: + +```js +server.addMethod("resolve_function_call", async (params) => { + if params.function !== "getSqrt" { + throw Error("Unexpected foreign call") + }; + const values = params.inputs[0].Array.map((field) => { + return `${Math.sqrt(parseInt(field, 16))}`; + }); + return { values: [{ Array: values }] }; +}); +``` + +If you're using Typescript, the following types may be helpful in understanding the expected return value and making sure they're easy to follow: + +```js +interface SingleForeignCallParam { + Single: string, +} + +interface ArrayForeignCallParam { + Array: string[], +} + +type ForeignCallParam = SingleForeignCallParam | ArrayForeignCallParam; + +interface ForeignCallResult { + values: ForeignCallParam[], +} +``` + +::: Multidimensional Arrays + +If the Oracle function is returning an array containing other arrays, such as `[['1','2],['3','4']]`, you need to provide the values in json as flattened values. In the previous example, it would be `['1', '2', '3', '4']`. In the noir program, the Oracle signature can use a nested type, the flattened values will be automatically converted to the nested type. + +::: + +## Step 3 - Usage with Nargo + +Using the [`nargo` CLI tool](../getting_started/noir_installation.md), you can use oracles in the `nargo test` and `nargo execute` commands by passing a value to `--oracle-resolver`. For example: + +```bash +nargo test --oracle-resolver http://localhost:5555 +``` + +This tells `nargo` to use your RPC Server URL whenever it finds an oracle decorator. + +## Step 4 - Usage with NoirJS + +In a JS environment, an RPC server is not strictly necessary, as you may want to resolve your oracles without needing any JSON call at all. NoirJS simply expects that you pass a callback function when you generate proofs, and that callback function can be anything. + +For example, if your Noir program expects the host machine to provide CPU pseudo-randomness, you could simply pass it as the `foreignCallHandler`. You don't strictly need to create an RPC server to serve pseudo-randomness, as you may as well get it directly in your app: + +```js +const foreignCallHandler = (name, inputs) => crypto.randomBytes(16) // etc + +await noir.execute(inputs, foreignCallHandler) +``` + +As one can see, in NoirJS, the [`foreignCallHandler`](../reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md) function simply means "a callback function that returns a value of type [`ForeignCallOutput`](../reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md). It doesn't have to be an RPC call like in the case for Nargo. + +:::tip + +Does this mean you don't have to write an RPC server like in [Step #2](#step-2---write-an-rpc-server)? + +You don't technically have to, but then how would you run `nargo test`? To use both `Nargo` and `NoirJS` in your development flow, you will have to write a JSON RPC server. + +::: + +In this case, let's make `foreignCallHandler` call the JSON RPC Server we created in [Step #2](#step-2---write-an-rpc-server), by making it a JSON RPC Client. + +For example, using the same `getSqrt` program in [Step #1](#step-1---modify-your-noir-program) (comments in the code): + +```js +import { JSONRPCClient } from "json-rpc-2.0"; + +// declaring the JSONRPCClient +const client = new JSONRPCClient((jsonRPCRequest) => { +// hitting the same JSON RPC Server we coded above + return fetch("http://localhost:5555", { + method: "POST", + headers: { + "content-type": "application/json", + }, + body: JSON.stringify(jsonRPCRequest), + }).then((response) => { + if (response.status === 200) { + return response + .json() + .then((jsonRPCResponse) => client.receive(jsonRPCResponse)); + } else if (jsonRPCRequest.id !== undefined) { + return Promise.reject(new Error(response.statusText)); + } + }); +}); + +// declaring a function that takes the name of the foreign call (getSqrt) and the inputs +const foreignCallHandler = async (name, input) => { + // notice that the "inputs" parameter contains *all* the inputs + // in this case we make the RPC request with the first parameter "numbers", which would be input[0] + const oracleReturn = await client.request(name, [ + input[0].map((i) => i.toString("hex")), + ]); + return { values: oracleReturn }; +}; + +// the rest of your NoirJS code +const input = { input: [4, 16] }; +const { witness } = await noir.execute(numbers, foreignCallHandler); +``` + +:::tip + +If you're in a NoirJS environment running your RPC server together with a frontend app, you'll probably hit a familiar problem in full-stack development: requests being blocked by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) policy. For development only, you can simply install and use the [`cors` npm package](https://www.npmjs.com/package/cors) to get around the problem: + +```bash +yarn add cors +``` + +and use it as a middleware: + +```js +import cors from "cors"; + +const app = express(); +app.use(cors()) +``` + +::: + +## Conclusion + +Hopefully by the end of this guide, you should be able to: + +- Write your own logic around Oracles and how to write a JSON RPC server to make them work with your Nargo commands. +- Provide custom foreign call handlers for NoirJS. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-recursion.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-recursion.md new file mode 100644 index 00000000000..c8c4dc9f5b4 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-recursion.md @@ -0,0 +1,180 @@ +--- +title: How to use recursion on NoirJS +description: Learn how to implement recursion with NoirJS, a powerful tool for creating smart contracts on the EVM blockchain. This guide assumes familiarity with NoirJS, solidity verifiers, and the Barretenberg proving backend. Discover how to generate both final and intermediate proofs using `noir_js` and `backend_barretenberg`. +keywords: + [ + "NoirJS", + "EVM blockchain", + "smart contracts", + "recursion", + "solidity verifiers", + "Barretenberg backend", + "noir_js", + "backend_barretenberg", + "intermediate proofs", + "final proofs", + "nargo compile", + "json import", + "recursive circuit", + "recursive app" + ] +sidebar_position: 1 +--- + +This guide shows you how to use recursive proofs in your NoirJS app. For the sake of clarity, it is assumed that: + +- You already have a NoirJS app. If you don't, please visit the [NoirJS tutorial](../tutorials/noirjs_app.md) and the [reference](../reference/NoirJS/noir_js/index.md). +- You are familiar with what are recursive proofs and you have read the [recursion explainer](../explainers/explainer-recursion.md) +- You already built a recursive circuit following [the reference](../noir/standard_library/recursion.mdx), and understand how it works. + +It is also assumed that you're not using `noir_wasm` for compilation, and instead you've used [`nargo compile`](../reference/nargo_commands.md) to generate the `json` you're now importing into your project. However, the guide should work just the same if you're using `noir_wasm`. + +:::info + +As you've read in the [explainer](../explainers/explainer-recursion.md), a recursive proof is an intermediate proof. This means that it doesn't necessarily generate the final step that makes it verifiable in a smart contract. However, it is easy to verify within another circuit. + +While "standard" usage of NoirJS packages abstracts final proofs, it currently lacks the necessary interface to abstract away intermediate proofs. This means that these proofs need to be created by using the backend directly. + +In short: + +- `noir_js` generates *only* final proofs +- `backend_barretenberg` generates both types of proofs + +::: + +In a standard recursive app, you're also dealing with at least two circuits. For the purpose of this guide, we will assume the following: + +- `main`: a circuit of type `assert(x != y)`, where `main` is marked with a `#[recursive]` attribute. This attribute states that the backend should generate proofs that are friendly for verification within another circuit. +- `recursive`: a circuit that verifies `main` + +For a full example of how recursive proofs work, please refer to the [noir-examples](https://github.com/noir-lang/noir-examples) repository. We will *not* be using it as a reference for this guide. + +## Step 1: Setup + +In a common NoirJS app, you need to instantiate a backend with something like `const backend = new Backend(circuit)`. Then you feed it to the `noir_js` interface. + +For recursion, this doesn't happen, and the only need for `noir_js` is only to `execute` a circuit and get its witness and return value. Everything else is not interfaced, so it needs to happen on the `backend` object. + +It is also recommended that you instantiate the backend with as many threads as possible, to allow for maximum concurrency: + +```js +const backend = new Backend(circuit, { threads: 8 }) +``` + +:::tip +You can use the [`os.cpus()`](https://nodejs.org/api/os.html#oscpus) object in `nodejs` or [`navigator.hardwareConcurrency`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/hardwareConcurrency) on the browser to make the most out of those glorious cpu cores +::: + +## Step 2: Generating the witness and the proof for `main` + +After instantiating the backend, you should also instantiate `noir_js`. We will use it to execute the circuit and get the witness. + +```js +const noir = new Noir(circuit) +const { witness } = noir.execute(input) +``` + +With this witness, you are now able to generate the intermediate proof for the main circuit: + +```js +const { proof, publicInputs } = await backend.generateProof(witness) +``` + +:::warning + +Always keep in mind what is actually happening on your development process, otherwise you'll quickly become confused about what circuit we are actually running and why! + +In this case, you can imagine that Alice (running the `main` circuit) is proving something to Bob (running the `recursive` circuit), and Bob is verifying her proof within his proof. + +With this in mind, it becomes clear that our intermediate proof is the one *meant to be verified within another circuit*, so it must be Alice's. Actually, the only final proof in this theoretical scenario would be the last one, sent on-chain. + +::: + +## Step 3 - Verification and proof artifacts + +Optionally, you are able to verify the intermediate proof: + +```js +const verified = await backend.verifyProof({ proof, publicInputs }) +``` + +This can be useful to make sure our intermediate proof was correctly generated. But the real goal is to do it within another circuit. For that, we need to generate recursive proof artifacts that will be passed to the circuit that is verifying the proof we just generated. Instead of passing the proof and verification key as a byte array, we pass them as fields which makes it cheaper to verify in a circuit: + +```js +const { proofAsFields, vkAsFields, vkHash } = await backend.generateRecursiveProofArtifacts( { publicInputs, proof }, publicInputsCount) +``` + +This call takes the public inputs and the proof, but also the public inputs count. While this is easily retrievable by simply counting the `publicInputs` length, the backend interface doesn't currently abstract it away. + +:::info + +The `proofAsFields` has a constant size `[Field; 93]` and verification keys in Barretenberg are always `[Field; 114]`. + +::: + +:::warning + +One common mistake is to forget *who* makes this call. + +In a situation where Alice is generating the `main` proof, if she generates the proof artifacts and sends them to Bob, which gladly takes them as true, this would mean Alice could prove anything! + +Instead, Bob needs to make sure *he* extracts the proof artifacts, using his own instance of the `main` circuit backend. This way, Alice has to provide a valid proof for the correct `main` circuit. + +::: + +## Step 4 - Recursive proof generation + +With the artifacts, generating a recursive proof is no different from a normal proof. You simply use the `backend` (with the recursive circuit) to generate it: + +```js +const recursiveInputs = { + verification_key: vkAsFields, // array of length 114 + proof: proofAsFields, // array of length 93 + size of public inputs + publicInputs: [mainInput.y], // using the example above, where `y` is the only public input + key_hash: vkHash, +} + +const { witness, returnValue } = noir.execute(recursiveInputs) // we're executing the recursive circuit now! +const { proof, publicInputs } = backend.generateProof(witness) +const verified = backend.verifyProof({ proof, publicInputs }) +``` + +You can obviously chain this proof into another proof. In fact, if you're using recursive proofs, you're probably interested of using them this way! + +:::tip + +Managing circuits and "who does what" can be confusing. To make sure your naming is consistent, you can keep them in an object. For example: + +```js +const circuits = { + main: mainJSON, + recursive: recursiveJSON +} +const backends = { + main: new BarretenbergBackend(circuits.main), + recursive: new BarretenbergBackend(circuits.recursive) +} +const noir_programs = { + main: new Noir(circuits.main), + recursive: new Noir(circuits.recursive) +} +``` + +This allows you to neatly call exactly the method you want without conflicting names: + +```js +// Alice runs this 👇 +const { witness: mainWitness } = await noir_programs.main.execute(input) +const proof = await backends.main.generateProof(mainWitness) + +// Bob runs this 👇 +const verified = await backends.main.verifyProof(proof) +const { proofAsFields, vkAsFields, vkHash } = await backends.main.generateRecursiveProofArtifacts( + proof, + numPublicInputs, +); +const { witness: recursiveWitness } = await noir_programs.recursive.execute(recursiveInputs) +const recursiveProof = await backends.recursive.generateProof(recursiveWitness); +``` + +::: diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-solidity-verifier.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-solidity-verifier.md new file mode 100644 index 00000000000..2cc0f8e57ce --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/how-to-solidity-verifier.md @@ -0,0 +1,259 @@ +--- +title: Generate a Solidity Verifier +description: + Learn how to run the verifier as a smart contract on the blockchain. Compile a Solidity verifier + contract for your Noir program and deploy it on any EVM blockchain acting as a verifier smart + contract. Read more to find out +keywords: + [ + solidity verifier, + smart contract, + blockchain, + compiler, + plonk_vk.sol, + EVM blockchain, + verifying Noir programs, + proving backend, + Barretenberg, + ] +sidebar_position: 0 +pagination_next: tutorials/noirjs_app +--- + +Noir has the ability to generate a verifier contract in Solidity, which can be deployed in many EVM-compatible blockchains such as Ethereum. + +This allows for a powerful feature set, as one can make use of the conciseness and the privacy provided by Noir in an immutable ledger. Applications can range from simple P2P guessing games, to complex private DeFi interactions. + +This guide shows you how to generate a Solidity Verifier and deploy it on the [Remix IDE](https://remix.ethereum.org/). It is assumed that: + +- You are comfortable with the Solidity programming language and understand how contracts are deployed on the Ethereum network +- You have Noir installed and you have a Noir program. If you don't, [get started](../getting_started/quick_start.md) with Nargo and the example Hello Noir circuit +- You are comfortable navigating RemixIDE. If you aren't or you need a refresher, you can find some video tutorials [here](https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA) that could help you. + +## Rundown + +Generating a Solidity Verifier contract is actually a one-command process. However, compiling it and deploying it can have some caveats. Here's the rundown of this guide: + +1. How to generate a solidity smart contract +2. How to compile the smart contract in the RemixIDE +3. How to deploy it to a testnet + +## Step 1 - Generate a contract + +This is by far the most straightforward step. Just run: + +```sh +nargo compile +``` + +This will compile your source code into a Noir build artifact to be stored in the `./target` directory, you can then generate the smart contract using the commands: + +```sh +# Here we pass the path to the newly generated Noir artifact. +bb write_vk -b ./target/.json +bb contract +``` + +replacing `` with the name of your Noir project. A new `contract` folder would then be generated in your project directory, containing the Solidity +file `contract.sol`. It can be deployed to any EVM blockchain acting as a verifier smart contract. + +You can find more information about `bb` and the default Noir proving backend on [this page](../getting_started/quick_start.md#proving-backend). + +:::info + +It is possible to generate verifier contracts of Noir programs for other smart contract platforms as long as the proving backend supplies an implementation. + +Barretenberg, the default proving backend for Nargo, supports generation of verifier contracts, for the time being these are only in Solidity. +::: + +## Step 2 - Compiling + +We will mostly skip the details of RemixIDE, as the UI can change from version to version. For now, we can just open +
Remix and create a blank workspace. + +![Create Workspace](@site/static/img/how-tos/solidity_verifier_1.png) + +We will create a new file to contain the contract Nargo generated, and copy-paste its content. + +:::warning + +You'll likely see a warning advising you to not trust pasted code. While it is an important warning, it is irrelevant in the context of this guide and can be ignored. We will not be deploying anywhere near a mainnet. + +::: + +To compile our the verifier, we can navigate to the compilation tab: + +![Compilation Tab](@site/static/img/how-tos/solidity_verifier_2.png) + +Remix should automatically match a suitable compiler version. However, hitting the "Compile" button will most likely generate a "Stack too deep" error: + +![Stack too deep](@site/static/img/how-tos/solidity_verifier_3.png) + +This is due to the verify function needing to put many variables on the stack, but enabling the optimizer resolves the issue. To do this, let's open the "Advanced Configurations" tab and enable optimization. The default 200 runs will suffice. + +:::info + +This time we will see a warning about an unused function parameter. This is expected, as the `verify` function doesn't use the `_proof` parameter inside a solidity block, it is loaded from calldata and used in assembly. + +::: + +![Compilation success](@site/static/img/how-tos/solidity_verifier_4.png) + +## Step 3 - Deploying + +At this point we should have a compiled contract ready to deploy. If we navigate to the deploy section in Remix, we will see many different environments we can deploy to. The steps to deploy on each environment would be out-of-scope for this guide, so we will just use the default Remix VM. + +Looking closely, we will notice that our "Solidity Verifier" is actually three contracts working together: + +- An `UltraVerificationKey` library which simply stores the verification key for our circuit. +- An abstract contract `BaseUltraVerifier` containing most of the verifying logic. +- A main `UltraVerifier` contract that inherits from the Base and uses the Key contract. + +Remix will take care of the dependencies for us so we can simply deploy the UltraVerifier contract by selecting it and hitting "deploy": + +![Deploying UltraVerifier](@site/static/img/how-tos/solidity_verifier_5.png) + +A contract will show up in the "Deployed Contracts" section, where we can retrieve the Verification Key Hash. This is particularly useful for double-checking that the deployer contract is the correct one. + +:::note + +Why "UltraVerifier"? + +To be precise, the Noir compiler (`nargo`) doesn't generate the verifier contract directly. It compiles the Noir code into an intermediate language (ACIR), which is then executed by the backend. So it is the backend that returns the verifier smart contract, not Noir. + +In this case, the Barretenberg Backend uses the UltraPlonk proving system, hence the "UltraVerifier" name. + +::: + +## Step 4 - Verifying + +To verify a proof using the Solidity verifier contract, we call the `verify` function in this extended contract: + +```solidity +function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) +``` + +When using the default example in the [Hello Noir](../getting_started/quick_start.md) guide, the easiest way to confirm that the verifier contract is doing its job is by calling the `verify` function via remix with the required parameters. Note that the public inputs must be passed in separately to the rest of the proof so we must split the proof as returned from `bb`. + +First generate a proof with `bb` at the location `./proof` using the steps in [get started](../getting_started/quick_start.md), this proof is in a binary format but we want to convert it into a hex string to pass into Remix, this can be done with the + +```bash +# This value must be changed to match the number of public inputs (including return values!) in your program. +NUM_PUBLIC_INPUTS=1 +PUBLIC_INPUT_BYTES=32*NUM_PUBLIC_INPUTS +HEX_PUBLIC_INPUTS=$(head -c $PUBLIC_INPUT_BYTES ./proof | od -An -v -t x1 | tr -d $' \n') +HEX_PROOF=$(tail -c +$(($PUBLIC_INPUT_BYTES + 1)) ./proof | od -An -v -t x1 | tr -d $' \n') + +echo "Public inputs:" +echo $HEX_PUBLIC_INPUTS + +echo "Proof:" +echo "0x$HEX_PROOF" +``` + +Remix expects that the public inputs will be split into an array of `bytes32` values so `HEX_PUBLIC_INPUTS` needs to be split up into 32 byte chunks which are prefixed with `0x` accordingly. + +A programmatic example of how the `verify` function is called can be seen in the example zk voting application [here](https://github.com/noir-lang/noir-examples/blob/33e598c257e2402ea3a6b68dd4c5ad492bce1b0a/foundry-voting/src/zkVote.sol#L35): + +```solidity +function castVote(bytes calldata proof, uint proposalId, uint vote, bytes32 nullifierHash) public returns (bool) { + // ... + bytes32[] memory publicInputs = new bytes32[](4); + publicInputs[0] = merkleRoot; + publicInputs[1] = bytes32(proposalId); + publicInputs[2] = bytes32(vote); + publicInputs[3] = nullifierHash; + require(verifier.verify(proof, publicInputs), "Invalid proof"); +``` + +:::info[Return Values] + +A circuit doesn't have the concept of a return value. Return values are just syntactic sugar in Noir. + +Under the hood, the return value is passed as an input to the circuit and is checked at the end of the circuit program. + +For example, if you have Noir program like this: + +```rust +fn main( + // Public inputs + pubkey_x: pub Field, + pubkey_y: pub Field, + // Private inputs + priv_key: Field, +) -> pub Field +``` + +the `verify` function will expect the public inputs array (second function parameter) to be of length 3, the two inputs and the return value. + +Passing only two inputs will result in an error such as `PUBLIC_INPUT_COUNT_INVALID(3, 2)`. + +In this case, the inputs parameter to `verify` would be an array ordered as `[pubkey_x, pubkey_y, return`. + +::: + +:::tip[Structs] + +You can pass structs to the verifier contract. They will be flattened so that the array of inputs is 1-dimensional array. + +For example, consider the following program: + +```rust +struct Type1 { + val1: Field, + val2: Field, +} + +struct Nested { + t1: Type1, + is_true: bool, +} + +fn main(x: pub Field, nested: pub Nested, y: pub Field) { + //... +} +``` + +The order of these inputs would be flattened to: `[x, nested.t1.val1, nested.t1.val2, nested.is_true, y]` + +::: + +The other function you can call is our entrypoint `verify` function, as defined above. + +:::tip + +It's worth noticing that the `verify` function is actually a `view` function. A `view` function does not alter the blockchain state, so it doesn't need to be distributed (i.e. it will run only on the executing node), and therefore doesn't cost any gas. + +This can be particularly useful in some situations. If Alice generated a proof and wants Bob to verify its correctness, Bob doesn't need to run Nargo, NoirJS, or any Noir specific infrastructure. He can simply make a call to the blockchain with the proof and verify it is correct without paying any gas. + +It would be incorrect to say that a Noir proof verification costs any gas at all. However, most of the time the result of `verify` is used to modify state (for example, to update a balance, a game state, etc). In that case the whole network needs to execute it, which does incur gas costs (calldata and execution, but not storage). + +::: + +## A Note on EVM chains + +Noir proof verification requires the ecMul, ecAdd and ecPairing precompiles. Not all EVM chains support EC Pairings, notably some of the ZK-EVMs. This means that you won't be able to use the verifier contract in all of them. You can find an incomplete list of which EVM chains support these precompiles [here](https://www.evmdiff.com/features?feature=precompiles). + +For example, chains like `zkSync ERA` and `Polygon zkEVM` do not currently support these precompiles, so proof verification via Solidity verifier contracts won't work. Here's a quick list of EVM chains that have been tested and are known to work: + +- Optimism +- Arbitrum +- Polygon PoS +- Scroll +- Celo +- BSC +- Blast L2 +- Avalanche C-Chain +- Mode +- Linea +- Moonbeam + +If you test any other chains, please open a PR on this page to update the list. See [this doc](https://github.com/noir-lang/noir-starter/tree/main/with-foundry#testing-on-chain) for more info about testing verifier contracts on different EVM chains. + +## What's next + +Now that you know how to call a Noir Solidity Verifier on a smart contract using Remix, you should be comfortable with using it with some programmatic frameworks, such as [hardhat](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat) and [foundry](https://github.com/noir-lang/noir-starter/tree/main/with-foundry). + +You can find other tools, examples, boilerplates and libraries in the [awesome-noir](https://github.com/noir-lang/awesome-noir) repository. + +You should also be ready to write and deploy your first NoirJS app and start generating proofs on websites, phones, and NodeJS environments! Head on to the [NoirJS tutorial](../tutorials/noirjs_app.md) to learn how to do that. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/merkle-proof.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/merkle-proof.mdx new file mode 100644 index 00000000000..0a128adb2de --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/merkle-proof.mdx @@ -0,0 +1,48 @@ +--- +title: Prove Merkle Tree Membership +description: + Learn how to use merkle membership proof in Noir to prove that a given leaf is a member of a + merkle tree with a specified root, at a given index. +keywords: + [merkle proof, merkle membership proof, Noir, rust, hash function, Pedersen, sha256, merkle tree] +sidebar_position: 4 +--- + +Let's walk through an example of a merkle membership proof in Noir that proves that a given leaf is +in a merkle tree. + +```rust + +fn main(message : [Field; 62], index : Field, hashpath : [Field; 40], root : Field) { + let leaf = std::hash::hash_to_field(message.as_slice()); + let merkle_root = std::merkle::compute_merkle_root(leaf, index, hashpath); + assert(merkle_root == root); +} + +``` + +The message is hashed using `hash_to_field`. The specific hash function that is being used is chosen +by the backend. The only requirement is that this hash function can heuristically be used as a +random oracle. If only collision resistance is needed, then one can call `std::hash::pedersen_hash` +instead. + +```rust +let leaf = std::hash::hash_to_field(message.as_slice()); +``` + +The leaf is then passed to a compute_merkle_root function with the root, index and hashpath. The returned root can then be asserted to be the same as the provided root. + +```rust +let merkle_root = std::merkle::compute_merkle_root(leaf, index, hashpath); +assert (merkle_root == root); +``` + +> **Note:** It is possible to re-implement the merkle tree implementation without standard library. +> However, for most usecases, it is enough. In general, the standard library will always opt to be +> as conservative as possible, while striking a balance with efficiency. + +An example, the merkle membership proof, only requires a hash function that has collision +resistance, hence a hash function like Pedersen is allowed, which in most cases is more efficient +than the even more conservative sha256. + +[View an example on the starter repo](https://github.com/noir-lang/noir-examples/blob/3ea09545cabfa464124ec2f3ea8e60c608abe6df/stealthdrop/circuits/src/main.nr#L20) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/using-devcontainers.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/using-devcontainers.mdx new file mode 100644 index 00000000000..727ec6ca667 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/how_to/using-devcontainers.mdx @@ -0,0 +1,110 @@ +--- +title: Developer Containers and Codespaces +description: "Learn how to set up a devcontainer in your GitHub repository for a seamless coding experience with Codespaces. Follow our easy 8-step guide to create your own Noir environment without installing Nargo locally." +keywords: ["Devcontainer", "Codespaces", "GitHub", "Noir Environment", "Docker Image", "Development Environment", "Remote Coding", "GitHub Codespaces", "Noir Programming", "Nargo", "VSCode Extensions", "Noirup"] +sidebar_position: 1 +--- + +Adding a developer container configuration file to your Noir project is one of the easiest way to unlock coding in browser. + +## What's a devcontainer after all? + +A [Developer Container](https://containers.dev/) (devcontainer for short) is a Docker image that comes preloaded with tools, extensions, and other tools you need to quickly get started or continue a project, without having to install Nargo locally. Think of it as a development environment in a box. + +There are many advantages to this: + +- It's platform and architecture agnostic +- You don't need to have an IDE installed, or Nargo, or use a terminal at all +- It's safer for using on a public machine or public network + +One of the best ways of using devcontainers is... not using your machine at all, for maximum control, performance, and ease of use. +Enter Codespaces. + +## Codespaces + +If a devcontainer is just a Docker image, then what stops you from provisioning a `p3dn.24xlarge` AWS EC2 instance with 92 vCPUs and 768 GiB RAM and using it to prove your 10-gate SNARK proof? + +Nothing! Except perhaps the 30-40$ per hour it will cost you. + +The problem is that provisioning takes time, and I bet you don't want to see the AWS console every time you want to code something real quick. + +Fortunately, there's an easy and free way to get a decent remote machine ready and loaded in less than 2 minutes: Codespaces. [Codespaces is a Github feature](https://github.com/features/codespaces) that allows you to code in a remote machine by using devcontainers, and it's pretty cool: + +- You can start coding Noir in less than a minute +- It uses the resources of a remote machine, so you can code on your grandma's phone if needed be +- It makes it easy to share work with your frens +- It's fully reusable, you can stop and restart whenever you need to + +:::info + +Don't take out your wallet just yet. Free GitHub accounts get about [15-60 hours of coding](https://github.com/features/codespaces) for free per month, depending on the size of your provisioned machine. + +::: + +## Tell me it's _actually_ easy + +It is! + +Github comes with a default codespace and you can use it to code your own devcontainer. That's exactly what we will be doing in this guide. + + + +8 simple steps: + +#### 1. Create a new repository on GitHub. + +#### 2. Click "Start coding with Codespaces". This will use the default image. + +#### 3. Create a folder called `.devcontainer` in the root of your repository. + +#### 4. Create a Dockerfile in that folder, and paste the following code: + +```docker +FROM --platform=linux/amd64 node:lts-bookworm-slim +SHELL ["/bin/bash", "-c"] +RUN apt update && apt install -y curl bash git tar gzip libc++-dev +RUN curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +ENV PATH="/root/.nargo/bin:$PATH" +RUN noirup +ENTRYPOINT ["nargo"] +``` +#### 5. Create a file called `devcontainer.json` in the same folder, and paste the following code: + +```json +{ + "name": "Noir on Codespaces", + "build": { + "context": ".", + "dockerfile": "Dockerfile" + }, + "customizations": { + "vscode": { + "extensions": ["noir-lang.vscode-noir"] + } + } +} +``` +#### 6. Commit and push your changes + +This will pull the new image and build it, so it could take a minute or so + +#### 8. Done! +Just wait for the build to finish, and there's your easy Noir environment. + + +Refer to [noir-starter](https://github.com/noir-lang/noir-starter/) as an example of how devcontainers can be used together with codespaces. + + + +## How do I use it? + +Using the codespace is obviously much easier than setting it up. +Just navigate to your repository and click "Code" -> "Open with Codespaces". It should take a few seconds to load, and you're ready to go. + +:::info + +If you really like the experience, you can add a badge to your readme, links to existing codespaces, and more. +Check out the [official docs](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/setting-up-your-repository/facilitating-quick-creation-and-resumption-of-codespaces) for more info. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/index.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/index.mdx new file mode 100644 index 00000000000..a6bd306f91d --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/index.mdx @@ -0,0 +1,67 @@ +--- +title: Noir Lang +hide_title: true +description: + Learn about the public alpha release of Noir, a domain specific language heavily influenced by Rust that compiles to + an intermediate language which can be compiled to an arithmetic circuit or a rank-1 constraint system. +keywords: + [Noir, + Domain Specific Language, + Rust, + Intermediate Language, + Arithmetic Circuit, + Rank-1 Constraint System, + Ethereum Developers, + Protocol Developers, + Blockchain Developers, + Proving System, + Smart Contract Language] +sidebar_position: 0 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Noir Logo + +Noir is an open-source Domain-Specific Language for safe and seamless construction of privacy-preserving Zero-Knowledge programs, requiring no previous knowledge on the underlying mathematics or cryptography. + +ZK programs are programs that can generate short proofs of statements without revealing all inputs to the statements. You can read more about Zero-Knowledge Proofs [here](https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56). + +## What's new about Noir? + +Noir works differently from most ZK languages by taking a two-pronged path. First, it compiles the program to an adaptable intermediate language known as ACIR. From there, depending on a given project's needs, ACIR can be further compiled into an arithmetic circuit for integration with the proving backend. + +:::info + +Noir is backend agnostic, which means it makes no assumptions on which proving backend powers the ZK proof. Being the language that powers [Aztec Contracts](https://docs.aztec.network/developers/contracts/main), it defaults to Aztec's Barretenberg proving backend. + +However, the ACIR output can be transformed to be compatible with other PLONK-based backends, or into a [rank-1 constraint system](https://www.rareskills.io/post/rank-1-constraint-system) suitable for backends such as Arkwork's Marlin. + +::: + +## Who is Noir for? + +Noir can be used both in complex cloud-based backends and in user's smartphones, requiring no knowledge on the underlying math or cryptography. From authorization systems that keep a password in the user's device, to complex on-chain verification of recursive proofs, Noir is designed to abstract away complexity without any significant overhead. Here are some examples of situations where Noir can be used: + + + + Noir Logo + + Aztec Contracts leverage Noir to allow for the storage and execution of private information. Writing an Aztec Contract is as easy as writing Noir, and Aztec developers can easily interact with the network storage and execution through the [Aztec.nr](https://docs.aztec.network/developers/contracts/main) library. + + + Soliditry Verifier Example + Noir can auto-generate Solidity verifier contracts that verify Noir proofs. This allows for non-interactive verification of proofs containing private information in an immutable system. This feature powers a multitude of use-case scenarios, from P2P chess tournaments, to [Aztec Layer-2 Blockchain](https://docs.aztec.network/) + + + Aztec Labs developed NoirJS, an easy interface to generate and verify Noir proofs in a Javascript environment. This allows for Noir to be used in webpages, mobile apps, games, and any other environment supporting JS execution in a standalone manner. + + + + +## Libraries + +Noir is meant to be easy to extend by simply importing Noir libraries just like in Rust. +The [awesome-noir repo](https://github.com/noir-lang/awesome-noir#libraries) is a collection of libraries developed by the Noir community. +Writing a new library is easy and makes code be composable and easy to reuse. See the section on [dependencies](noir/modules_packages_crates/dependencies.md) for more information. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/migration_notes.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/migration_notes.md new file mode 100644 index 00000000000..6bd740024e5 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/migration_notes.md @@ -0,0 +1,105 @@ +--- +title: Migration notes +description: Read about migration notes from previous versions, which could solve problems while updating +keywords: [Noir, notes, migration, updating, upgrading] +--- + +Noir is in full-speed development. Things break fast, wild, and often. This page attempts to leave some notes on errors you might encounter when upgrading and how to resolve them until proper patches are built. + +### `backend encountered an error: libc++.so.1` + +Depending on your OS, you may encounter the following error when running `nargo prove` for the first time: + +```text +The backend encountered an error: "/home/codespace/.nargo/backends/acvm-backend-barretenberg/backend_binary: error while loading shared libraries: libc++.so.1: cannot open shared object file: No such file or directory\n" +``` + +Install the `libc++-dev` library with: + +```bash +sudo apt install libc++-dev +``` + +## ≥0.19 + +### Enforcing `compiler_version` + +From this version on, the compiler will check for the `compiler_version` field in `Nargo.toml`, and will error if it doesn't match the current Nargo version in use. + +To update, please make sure this field in `Nargo.toml` matches the output of `nargo --version`. + +## ≥0.14 + +The index of the [for loops](noir/concepts/control_flow.md#loops) is now of type `u64` instead of `Field`. An example refactor would be: + +```rust +for i in 0..10 { + let i = i as Field; +} +``` + +## ≥v0.11.0 and Nargo backend + +From this version onwards, Nargo starts managing backends through the `nargo backend` command. Upgrading to the versions per usual steps might lead to: + +### `backend encountered an error` + +This is likely due to the existing locally installed version of proving backend (e.g. barretenberg) is incompatible with the version of Nargo in use. + +To fix the issue: + +1. Uninstall the existing backend + +```bash +nargo backend uninstall acvm-backend-barretenberg +``` + +You may replace _acvm-backend-barretenberg_ with the name of your backend listed in `nargo backend ls` or in ~/.nargo/backends. + +2. Reinstall a compatible version of the proving backend. + +If you are using the default barretenberg backend, simply run: + +``` +nargo prove +``` + +with your Noir program. + +This will trigger the download and installation of the latest version of barretenberg compatible with your Nargo in use. + +### `backend encountered an error: illegal instruction` + +On certain Intel-based systems, an `illegal instruction` error may arise due to incompatibility of barretenberg with certain CPU instructions. + +To fix the issue: + +1. Uninstall the existing backend + +```bash +nargo backend uninstall acvm-backend-barretenberg +``` + +You may replace _acvm-backend-barretenberg_ with the name of your backend listed in `nargo backend ls` or in ~/.nargo/backends. + +2. Reinstall a compatible version of the proving backend. + +If you are using the default barretenberg backend, simply run: + +``` +nargo backend install acvm-backend-barretenberg https://github.com/noir-lang/barretenberg-js-binary/raw/master/run-bb.tar.gz +``` + +This downloads and installs a specific bb.js based version of barretenberg binary from GitHub. + +The gzipped file is running [this bash script](https://github.com/noir-lang/barretenberg-js-binary/blob/master/run-bb-js.sh), where we need to gzip it as the Nargo currently expect the backend to be zipped up. + +Then run: + +``` +DESIRED_BINARY_VERSION=0.8.1 nargo info +``` + +This overrides the bb native binary with a bb.js node application instead, which should be compatible with most if not all hardware. This does come with the drawback of being generally slower than native binary. + +0.8.1 indicates bb.js version 0.8.1, so if you change that it will update to a different version or the default version in the script if none was supplied. diff --git a/noir/noir-repo/docs/docs/getting_started/installation/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/_category_.json similarity index 68% rename from noir/noir-repo/docs/docs/getting_started/installation/_category_.json rename to noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/_category_.json index 0c02fb5d4d7..7da08f8a8c5 100644 --- a/noir/noir-repo/docs/docs/getting_started/installation/_category_.json +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/_category_.json @@ -1,6 +1,6 @@ { + "label": "Concepts", "position": 0, - "label": "Install Nargo", "collapsible": true, "collapsed": true -} +} \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/assert.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/assert.md new file mode 100644 index 00000000000..2132de42072 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/assert.md @@ -0,0 +1,78 @@ +--- +title: Assert Function +description: + Learn about the `assert` and `static_assert` functions in Noir, which can be used to explicitly + constrain the predicate or comparison expression that follows to be true, and what happens if + the expression is false at runtime or compile-time, respectively. +keywords: [Noir programming language, assert statement, predicate expression, comparison expression] +sidebar_position: 4 +--- + +Noir includes a special `assert` function which will explicitly constrain the predicate/comparison +expression that follows to be true. If this expression is false at runtime, the program will fail to +be proven. Example: + +```rust +fn main(x : Field, y : Field) { + assert(x == y); +} +``` + +> Assertions only work for predicate operations, such as `==`. If there's any ambiguity on the operation, the program will fail to compile. For example, it is unclear if `assert(x + y)` would check for `x + y == 0` or simply would return `true`. + +You can optionally provide a message to be logged when the assertion fails: + +```rust +assert(x == y, "x and y are not equal"); +``` + +Aside string literals, the optional message can be a format string or any other type supported as input for Noir's [print](../standard_library/logging.md) functions. This feature lets you incorporate runtime variables into your failed assertion logs: + +```rust +assert(x == y, f"Expected x == y, but got {x} == {y}"); +``` + +Using a variable as an assertion message directly: + +```rust +struct myStruct { + myField: Field +} + +let s = myStruct { myField: y }; +assert(s.myField == x, s); +``` + +There is also a special `static_assert` function that behaves like `assert`, +but that runs at compile-time. + +```rust +fn main(xs: [Field; 3]) { + let x = 2 + 2; + let y = 4; + static_assert(x == y, "expected 2 + 2 to equal 4"); + + // This passes since the length of `xs` is known at compile-time + static_assert(xs.len() == 3, "expected the input to have 3 elements"); +} +``` + +This function fails when passed a dynamic (run-time) argument: + +```rust +fn main(x : Field, y : Field) { + // this fails because `x` is not known at compile-time + static_assert(x == 2, "expected x to be known at compile-time and equal to 2"); + + let mut example_slice = &[]; + if y == 4 { + example_slice = example_slice.push_back(0); + } + + // This fails because the length of `example_slice` is not known at + // compile-time + let error_message = "expected an empty slice, known at compile-time"; + static_assert(example_slice.len() == 0, error_message); +} +``` + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comments.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comments.md new file mode 100644 index 00000000000..b51a85f5c94 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comments.md @@ -0,0 +1,33 @@ +--- +title: Comments +description: + Learn how to write comments in Noir programming language. A comment is a line of code that is + ignored by the compiler, but it can be read by programmers. Single-line and multi-line comments + are supported in Noir. +keywords: [Noir programming language, comments, single-line comments, multi-line comments] +sidebar_position: 10 +--- + +A comment is a line in your codebase which the compiler ignores, however it can be read by +programmers. + +Here is a single line comment: + +```rust +// This is a comment and is ignored +``` + +`//` is used to tell the compiler to ignore the rest of the line. + +Noir also supports multi-line block comments. Start a block comment with `/*` and end the block with `*/`. + +Noir does not natively support doc comments. You may be able to use [Rust doc comments](https://doc.rust-lang.org/reference/comments.html) in your code to leverage some Rust documentation build tools with Noir code. + +```rust +/* + This is a block comment describing a complex function. +*/ +fn main(x : Field, y : pub Field) { + assert(x != y); +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comptime.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comptime.md new file mode 100644 index 00000000000..ba837174639 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/comptime.md @@ -0,0 +1,445 @@ +--- +title: Compile-time Code & Metaprogramming +description: Learn how to use metaprogramming in Noir to create macros or derive your own traits +keywords: [Noir, comptime, compile-time, metaprogramming, macros, quote, unquote] +sidebar_position: 15 +--- + +# Overview + +Metaprogramming in Noir is comprised of three parts: +1. `comptime` code +2. Quoting and unquoting +3. The metaprogramming API in `std::meta` + +Each of these are explained in more detail in the next sections but the wide picture is that +`comptime` allows us to write code which runs at compile-time. In this `comptime` code we +can quote and unquote snippets of the program, manipulate them, and insert them in other +parts of the program. Comptime functions which do this are said to be macros. Additionally, +there's a compile-time API of built-in types and functions provided by the compiler which allows +for greater analysis and modification of programs. + +--- + +# Comptime + +`comptime` is a new keyword in Noir which marks an item as executing or existing at compile-time. It can be used in several ways: + +- `comptime fn` to define functions which execute exclusively during compile-time. +- `comptime global` to define a global variable which is evaluated at compile-time. + - Unlike runtime globals, `comptime global`s can be mutable. +- `comptime { ... }` to execute a block of statements during compile-time. +- `comptime let` to define a variable whose value is evaluated at compile-time. +- `comptime for` to run a for loop at compile-time. Syntax sugar for `comptime { for .. }`. + +## Scoping + +Note that while in a `comptime` context, any runtime variables _local to the current function_ are never visible. + +## Evaluating + +Evaluation rules of `comptime` follows the normal unconstrained evaluation rules for other Noir code. There are a few things to note though: + +- Certain built-in functions may not be available, although more may be added over time. +- Evaluation order of global items is currently unspecified. For example, given the following two functions we can't guarantee +which `println` will execute first. The ordering of the two printouts will be arbitrary, but should be stable across multiple compilations with the same `nargo` version as long as the program is also unchanged. + +```rust +fn one() { + comptime { println("one"); } +} + +fn two() { + comptime { println("two"); } +} +``` + +- Since evaluation order is unspecified, care should be taken when using mutable globals so that they do not rely on a particular ordering. +For example, using globals to generate unique ids should be fine but relying on certain ids always being produced (especially after edits to the program) should be avoided. +- Although most ordering of globals is unspecified, two are: + - Dependencies of a crate will always be evaluated before the dependent crate. + - Any annotations on a function will be run before the function itself is resolved. This is to allow the annotation to modify the function if necessary. Note that if the + function itself was called at compile-time previously, it will already be resolved and cannot be modified. To prevent accidentally calling functions you wish to modify + at compile-time, it may be helpful to sort your `comptime` annotation functions into a different crate along with any dependencies they require. + +## Lowering + +When a `comptime` value is used in runtime code it must be lowered into a runtime value. This means replacing the expression with the literal that it evaluated to. For example, the code: + +```rust +struct Foo { array: [Field; 2], len: u32 } + +fn main() { + println(comptime { + let mut foo = std::mem::zeroed::(); + foo.array[0] = 4; + foo.len = 1; + foo + }); +} +``` + +will be converted to the following after `comptime` expressions are evaluated: + +```rust +struct Foo { array: [Field; 2], len: u32 } + +fn main() { + println(Foo { array: [4, 0], len: 1 }); +} +``` + +Not all types of values can be lowered. For example, `Type`s and `TypeDefinition`s (among other types) cannot be lowered at all. + +```rust +fn main() { + // There's nothing we could inline here to create a Type value at runtime + // let _ = get_type!(); +} + +comptime fn get_type() -> Type { ... } +``` + +--- + +# (Quasi) Quote + +Macros in Noir are `comptime` functions which return code as a value which is inserted into the call site when it is lowered there. +A code value in this case is of type `Quoted` and can be created by a `quote { ... }` expression. +More specifically, the code value `quote` creates is a token stream - a representation of source code as a series of words, numbers, string literals, or operators. +For example, the expression `quote { Hi "there reader"! }` would quote three tokens: the word "hi", the string "there reader", and an exclamation mark. +You'll note that snippets that would otherwise be invalid syntax can still be quoted. + +When a `Quoted` value is used in runtime code, it is lowered into a `quote { ... }` expression. Since this expression is only valid +in compile-time code however, we'd get an error if we tried this. Instead, we can use macro insertion to insert each token into the +program at that point, and parse it as an expression. To do this, we have to add a `!` after the function name returning the `Quoted` value. +If the value was created locally and there is no function returning it, `std::meta::unquote!(_)` can be used instead. +Calling such a function at compile-time without `!` will just return the `Quoted` value to be further manipulated. For example: + +```rust title="quote-example" showLineNumbers +comptime fn quote_one() -> Quoted { + quote { 1 } + } + + #[test] + fn returning_versus_macro_insertion() { + comptime { + // let _a: Quoted = quote { 1 }; + let _a: Quoted = quote_one(); + + // let _b: Field = 1; + let _b: Field = quote_one!(); + + // Since integers default to fields, if we + // want a different type we have to explicitly cast + // let _c: i32 = 1 as i32; + let _c: i32 = quote_one!() as i32; + } + } +``` +> Source code: noir_stdlib/src/meta/mod.nr#L120-L140 + + +For those familiar with quoting from other languages (primarily lisps), Noir's `quote` is actually a _quasiquote_. +This means we can escape the quoting by using the unquote operator to splice values in the middle of quoted code. + +# Unquote + +The unquote operator `$` is usable within a `quote` expression. +It takes a variable as an argument, evaluates the variable, and splices the resulting value into the quoted token stream at that point. For example, + +```rust +comptime { + let x = 1 + 2; + let y = quote { $x + 4 }; +} +``` + +The value of `y` above will be the token stream containing `3`, `+`, and `4`. We can also use this to combine `Quoted` values into larger token streams: + +```rust +comptime { + let x = quote { 1 + 2 }; + let y = quote { $x + 4 }; +} +``` + +The value of `y` above is now the token stream containing five tokens: `1 + 2 + 4`. + +Note that to unquote something, a variable name _must_ follow the `$` operator in a token stream. +If it is an expression (even a parenthesized one), it will do nothing. Most likely a parse error will be given when the macro is later unquoted. + +Unquoting can also be avoided by escaping the `$` with a backslash: + +``` +comptime { + let x = quote { 1 + 2 }; + + // y contains the four tokens: `$x + 4` + let y = quote { \$x + 4 }; +} +``` + +--- + +# Annotations + +Annotations provide a way to run a `comptime` function on an item in the program. +When you use an annotation, the function with the same name will be called with that item as an argument: + +```rust +#[my_struct_annotation] +struct Foo {} + +comptime fn my_struct_annotation(s: StructDefinition) { + println("Called my_struct_annotation!"); +} + +#[my_function_annotation] +fn foo() {} + +comptime fn my_function_annotation(f: FunctionDefinition) { + println("Called my_function_annotation!"); +} +``` + +Anything returned from one of these functions will be inserted at top-level along with the original item. +Note that expressions are not valid at top-level so you'll get an error trying to return `3` or similar just as if you tried to write a program containing `3; struct Foo {}`. +You can insert other top-level items such as trait impls, structs, or functions this way though. +For example, this is the mechanism used to insert additional trait implementations into the program when deriving a trait impl from a struct: + +```rust title="derive-field-count-example" showLineNumbers +trait FieldCount { + fn field_count() -> u32; + } + + #[derive_field_count] + struct Bar { + x: Field, + y: [Field; 2], + } + + comptime fn derive_field_count(s: StructDefinition) -> Quoted { + let typ = s.as_type(); + let field_count = s.fields().len(); + quote { + impl FieldCount for $typ { + fn field_count() -> u32 { + $field_count + } + } + } + } +``` +> Source code: noir_stdlib/src/meta/mod.nr#L142-L164 + + +## Calling annotations with additional arguments + +Arguments may optionally be given to annotations. +When this is done, these additional arguments are passed to the annotation function after the item argument. + +```rust title="annotation-arguments-example" showLineNumbers +#[assert_field_is_type(quote { i32 }.as_type())] + struct MyStruct { + my_field: i32, + } + + comptime fn assert_field_is_type(s: StructDefinition, typ: Type) { + // Assert the first field in `s` has type `typ` + let fields = s.fields(); + assert_eq(fields[0].1, typ); + } +``` +> Source code: noir_stdlib/src/meta/mod.nr#L166-L177 + + +We can also take any number of arguments by adding the `varargs` annotation: + +```rust title="annotation-varargs-example" showLineNumbers +#[assert_three_args(1, 2, 3)] + struct MyOtherStruct { + my_other_field: u32, + } + + #[varargs] + comptime fn assert_three_args(_s: StructDefinition, args: [Field]) { + assert_eq(args.len(), 3); + } +``` +> Source code: noir_stdlib/src/meta/mod.nr#L179-L189 + + +--- + +# Comptime API + +Although `comptime`, `quote`, and unquoting provide a flexible base for writing macros, +Noir's true metaprogramming ability comes from being able to interact with the compiler through a compile-time API. +This API can be accessed through built-in functions in `std::meta` as well as on methods of several `comptime` types. + +The following is an incomplete list of some `comptime` types along with some useful methods on them. + +- `Quoted`: A token stream +- `Type`: The type of a Noir type + - `fn implements(self, constraint: TraitConstraint) -> bool` + - Returns true if `self` implements the given trait constraint +- `Expr`: A syntactically valid expression. Can be used to recur on a program's parse tree to inspect how it is structured. + - Methods: + - `fn as_function_call(self) -> Option<(Expr, [Expr])>` + - If this is a function call expression, return `(function, arguments)` + - `fn as_block(self) -> Option<[Expr]>` + - If this is a block, return each statement in the block +- `FunctionDefinition`: A function definition + - Methods: + - `fn parameters(self) -> [(Quoted, Type)]` + - Returns a slice of `(name, type)` pairs for each parameter +- `StructDefinition`: A struct definition + - Methods: + - `fn as_type(self) -> Type` + - Returns this `StructDefinition` as a `Type`. Any generics are kept as-is + - `fn generics(self) -> [Quoted]` + - Return the name of each generic on this struct + - `fn fields(self) -> [(Quoted, Type)]` + - Return the name and type of each field +- `TraitConstraint`: A trait constraint such as `From` +- `TypedExpr`: A type-checked expression. +- `UnresolvedType`: A syntactic notation that refers to a Noir type that hasn't been resolved yet + +There are many more functions available by exploring the `std::meta` module and its submodules. +Using these methods is the key to writing powerful metaprogramming libraries. + +## `#[use_callers_scope]` + +Since certain functions such as `Quoted::as_type`, `Expression::as_type`, or `Quoted::as_trait_constraint` will attempt +to resolve their contents in a particular scope - it can be useful to change the scope they resolve in. By default +these functions will resolve in the current function's scope which is usually the attribute function they are called in. +If you're working on a library however, this may be a completely different module or crate to the item you're trying to +use the attribute on. If you want to be able to use `Quoted::as_type` to refer to types local to the caller's scope for +example, you can annotate your attribute function with `#[use_callers_scope]`. This will ensure your attribute, and any +closures it uses, can refer to anything in the caller's scope. `#[use_callers_scope]` also works recursively. So if both +your attribute function and a helper function it calls use it, then they can both refer to the same original caller. + +--- + +# Example: Derive + +Using all of the above, we can write a `derive` macro that behaves similarly to Rust's but is not built into the language. +From the user's perspective it will look like this: + +```rust +// Example usage +#[derive(Default, Eq, Ord)] +struct MyStruct { my_field: u32 } +``` + +To implement `derive` we'll have to create a `comptime` function that accepts +a variable amount of traits. + +```rust title="derive_example" showLineNumbers +// These are needed for the unconstrained hashmap we're using to store derive functions +use crate::collections::umap::UHashMap; +use crate::hash::BuildHasherDefault; +use crate::hash::poseidon2::Poseidon2Hasher; + +// A derive function is one that given a struct definition can +// create us a quoted trait impl from it. +pub type DeriveFunction = fn(StructDefinition) -> Quoted; + +// We'll keep a global HANDLERS map to keep track of the derive handler for each trait +comptime mut global HANDLERS: UHashMap> = + UHashMap::default(); + +// Given a struct and a slice of traits to derive, create trait impls for each. +// This function is as simple as iterating over the slice, checking if we have a trait +// handler registered for the given trait, calling it, and appending the result. +#[varargs] +pub comptime fn derive(s: StructDefinition, traits: [TraitDefinition]) -> Quoted { + let mut result = quote {}; + + for trait_to_derive in traits { + let handler = unsafe { HANDLERS.get(trait_to_derive) }; + assert(handler.is_some(), f"No derive function registered for `{trait_to_derive}`"); + + let trait_impl = handler.unwrap()(s); + result = quote { $result $trait_impl }; + } + + result +} +``` +> Source code: noir_stdlib/src/meta/mod.nr#L31-L64 + + +Registering a derive function could be done as follows: + +```rust title="derive_via" showLineNumbers +// To register a handler for a trait, just add it to our handlers map +pub comptime fn derive_via(t: TraitDefinition, f: DeriveFunction) { + HANDLERS.insert(t, f); +} +``` +> Source code: noir_stdlib/src/meta/mod.nr#L66-L73 + + +```rust title="big-derive-usage-example" showLineNumbers +// Finally, to register a handler we call the above function as an annotation + // with our handler function. + #[derive_via(derive_do_nothing)] + trait DoNothing { + fn do_nothing(self); + } + + comptime fn derive_do_nothing(s: StructDefinition) -> Quoted { + // This is simplified since we don't handle generics or where clauses! + // In a real example we'd likely also need to introduce each of + // `s.generics()` as well as a trait constraint for each generic + // to ensure they also implement the trait. + let typ = s.as_type(); + quote { + impl DoNothing for $typ { + fn do_nothing(self) { + // Traits can't tell us what to do + println("something"); + } + } + } + } + + // Since `DoNothing` is a simple trait which: + // 1. Only has one method + // 2. Does not have any generics on the trait itself + // We can use `std::meta::make_trait_impl` to help us out. + // This helper function will generate our impl for us along with any + // necessary where clauses and still provides a flexible interface + // for us to work on each field on the struct. + comptime fn derive_do_nothing_alt(s: StructDefinition) -> Quoted { + let trait_name = quote { DoNothing }; + let method_signature = quote { fn do_nothing(self) }; + + // Call `do_nothing` recursively on each field in the struct + let for_each_field = |field_name| quote { self.$field_name.do_nothing(); }; + + // Some traits like Eq want to join each field expression with something like `&`. + // We don't need that here + let join_fields_with = quote {}; + + // The body function is a spot to insert any extra setup/teardown needed. + // We'll insert our println here. Since we recur on each field, we should see + // one println for the struct itself, followed by a println for every field (recursively). + let body = |body| quote { + println("something"); + $body + }; + crate::meta::make_trait_impl( + s, + trait_name, + method_signature, + for_each_field, + join_fields_with, + body, + ) + } +``` +> Source code: noir_stdlib/src/meta/mod.nr#L191-L249 + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/control_flow.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/control_flow.md new file mode 100644 index 00000000000..b365bb22728 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/control_flow.md @@ -0,0 +1,79 @@ +--- +title: Control Flow +description: + Learn how to use loops and if expressions in the Noir programming language. Discover the syntax + and examples for for loops and if-else statements. +keywords: [Noir programming language, loops, for loop, if-else statements, Rust syntax] +sidebar_position: 2 +--- + +## If Expressions + +Noir supports `if-else` statements. The syntax is most similar to Rust's where it is not required +for the statement's conditional to be surrounded by parentheses. + +```rust +let a = 0; +let mut x: u32 = 0; + +if a == 0 { + if a != 0 { + x = 6; + } else { + x = 2; + } +} else { + x = 5; + assert(x == 5); +} +assert(x == 2); +``` + +## Loops + +Noir has one kind of loop: the `for` loop. `for` loops allow you to repeat a block of code multiple +times. + +The following block of code between the braces is run 10 times. + +```rust +for i in 0..10 { + // do something +} +``` + +Alternatively, `start..=end` can be used for a range that is inclusive on both ends. + +The index for loops is of type `u64`. + +### Break and Continue + +In unconstrained code, `break` and `continue` are also allowed in `for` loops. These are only allowed +in unconstrained code since normal constrained code requires that Noir knows exactly how many iterations +a loop may have. `break` and `continue` can be used like so: + +```rust +for i in 0 .. 10 { + println("Iteration start") + + if i == 2 { + continue; + } + + if i == 5 { + break; + } + + println(i); +} +println("Loop end") +``` + +When used, `break` will end the current loop early and jump to the statement after the for loop. In the example +above, the `break` will stop the loop and jump to the `println("Loop end")`. + +`continue` will stop the current iteration of the loop, and jump to the start of the next iteration. In the example +above, `continue` will jump to `println("Iteration start")` when used. Note that the loop continues as normal after this. +The iteration variable `i` is still increased by one as normal when `continue` is used. + +`break` and `continue` cannot currently be used to jump out of more than a single loop at a time. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_bus.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_bus.mdx new file mode 100644 index 00000000000..e55e58622ce --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_bus.mdx @@ -0,0 +1,23 @@ +--- +title: Data Bus +sidebar_position: 13 +--- +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +The data bus is an optimization that the backend can use to make recursion more efficient. +In order to use it, you must define some inputs of the program entry points (usually the `main()` +function) with the `call_data` modifier, and the return values with the `return_data` modifier. +These modifiers are incompatible with `pub` and `mut` modifiers. + +## Example + +```rust +fn main(mut x: u32, y: call_data u32, z: call_data [u32;4] ) -> return_data u32 { + let a = z[x]; + a+y +} +``` + +As a result, both call_data and return_data will be treated as private inputs and encapsulated into a read-only array each, for the backend to process. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/arrays.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/arrays.md new file mode 100644 index 00000000000..289145a8c4d --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/arrays.md @@ -0,0 +1,276 @@ +--- +title: Arrays +description: + Dive into the Array data type in Noir. Grasp its methods, practical examples, and best practices for efficiently using Arrays in your Noir code. +keywords: + [ + noir, + array type, + methods, + examples, + indexing, + ] +sidebar_position: 4 +--- + +An array is one way of grouping together values into one compound type. Array types can be inferred +or explicitly specified via the syntax `[; ]`: + +```rust +fn main(x : Field, y : Field) { + let my_arr = [x, y]; + let your_arr: [Field; 2] = [x, y]; +} +``` + +Here, both `my_arr` and `your_arr` are instantiated as an array containing two `Field` elements. + +Array elements can be accessed using indexing: + +```rust +fn main() { + let a = [1, 2, 3, 4, 5]; + + let first = a[0]; + let second = a[1]; +} +``` + +All elements in an array must be of the same type (i.e. homogeneous). That is, an array cannot group +a `Field` value and a `u8` value together for example. + +You can write mutable arrays, like: + +```rust +fn main() { + let mut arr = [1, 2, 3, 4, 5]; + assert(arr[0] == 1); + + arr[0] = 42; + assert(arr[0] == 42); +} +``` + +You can instantiate a new array of a fixed size with the same value repeated for each element. The following example instantiates an array of length 32 where each element is of type Field and has the value 0. + +```rust +let array: [Field; 32] = [0; 32]; +``` + +Like in Rust, arrays in Noir are a fixed size. However, if you wish to convert an array to a [slice](./slices.mdx), you can just call `as_slice` on your array: + +```rust +let array: [Field; 32] = [0; 32]; +let sl = array.as_slice() +``` + +You can define multidimensional arrays: + +```rust +let array : [[Field; 2]; 2]; +let element = array[0][0]; +``` + +However, multidimensional slices are not supported. For example, the following code will error at compile time: + +```rust +let slice : [[Field]] = &[]; +``` + +## Types + +You can create arrays of primitive types or structs. There is not yet support for nested arrays +(arrays of arrays) or arrays of structs that contain arrays. + +## Methods + +For convenience, the STD provides some ready-to-use, common methods for arrays. +Each of these functions are located within the generic impl `impl [T; N] {`. +So anywhere `self` appears, it refers to the variable `self: [T; N]`. + +### len + +Returns the length of an array + +```rust +fn len(self) -> Field +``` + +example + +```rust +fn main() { + let array = [42, 42]; + assert(array.len() == 2); +} +``` + +### sort + +Returns a new sorted array. The original array remains untouched. Notice that this function will +only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting +logic it uses internally is optimized specifically for these values. If you need a sort function to +sort any type, you should use the function `sort_via` described below. + +```rust +fn sort(self) -> [T; N] +``` + +example + +```rust +fn main() { + let arr = [42, 32]; + let sorted = arr.sort(); + assert(sorted == [32, 42]); +} +``` + +### sort_via + +Sorts the array with a custom comparison function. The ordering function must return true if the first argument should be sorted to be before the second argument or is equal to the second argument. + +Using this method with an operator like `<` that does not return `true` for equal values will result in an assertion failure for arrays with equal elements. + +```rust +fn sort_via(self, ordering: fn(T, T) -> bool) -> [T; N] +``` + +example + +```rust +fn main() { + let arr = [42, 32] + let sorted_ascending = arr.sort_via(|a, b| a <= b); + assert(sorted_ascending == [32, 42]); // verifies + + let sorted_descending = arr.sort_via(|a, b| a >= b); + assert(sorted_descending == [32, 42]); // does not verify +} +``` + +### map + +Applies a function to each element of the array, returning a new array containing the mapped elements. + +```rust +fn map(self, f: fn(T) -> U) -> [U; N] +``` + +example + +```rust +let a = [1, 2, 3]; +let b = a.map(|a| a * 2); // b is now [2, 4, 6] +``` + +### fold + +Applies a function to each element of the array, returning the final accumulated value. The first +parameter is the initial value. + +```rust +fn fold(self, mut accumulator: U, f: fn(U, T) -> U) -> U +``` + +This is a left fold, so the given function will be applied to the accumulator and first element of +the array, then the second, and so on. For a given call the expected result would be equivalent to: + +```rust +let a1 = [1]; +let a2 = [1, 2]; +let a3 = [1, 2, 3]; + +let f = |a, b| a - b; +a1.fold(10, f) //=> f(10, 1) +a2.fold(10, f) //=> f(f(10, 1), 2) +a3.fold(10, f) //=> f(f(f(10, 1), 2), 3) +``` + +example: + +```rust + +fn main() { + let arr = [2, 2, 2, 2, 2]; + let folded = arr.fold(0, |a, b| a + b); + assert(folded == 10); +} + +``` + +### reduce + +Same as fold, but uses the first element as the starting element. + +Requires `self` to be non-empty. + +```rust +fn reduce(self, f: fn(T, T) -> T) -> T +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 2]; + let reduced = arr.reduce(|a, b| a + b); + assert(reduced == 10); +} +``` + +### all + +Returns true if all the elements satisfy the given predicate + +```rust +fn all(self, predicate: fn(T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 2]; + let all = arr.all(|a| a == 2); + assert(all); +} +``` + +### any + +Returns true if any of the elements satisfy the given predicate + +```rust +fn any(self, predicate: fn(T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let arr = [2, 2, 2, 2, 5]; + let any = arr.any(|a| a == 5); + assert(any); +} +``` + +### as_str_unchecked + +Converts a byte array of type `[u8; N]` to a string. Note that this performs no UTF-8 validation - +the given array is interpreted as-is as a string. + +```rust +impl [u8; N] { + pub fn as_str_unchecked(self) -> str +} +``` + +example: + +```rust +fn main() { + let hi = [104, 105].as_str_unchecked(); + assert_eq(hi, "hi"); +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/booleans.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/booleans.md new file mode 100644 index 00000000000..2507af710e7 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/booleans.md @@ -0,0 +1,28 @@ +--- +title: Booleans +description: + Delve into the Boolean data type in Noir. Understand its methods, practical examples, and best practices for using Booleans in your Noir programs. +keywords: + [ + noir, + boolean type, + methods, + examples, + logical operations, + ] +sidebar_position: 2 +--- + + +The `bool` type in Noir has two possible values: `true` and `false`: + +```rust +fn main() { + let t = true; + let f: bool = false; +} +``` + +The boolean type is most commonly used in conditionals like `if` expressions and `assert` +statements. More about conditionals is covered in the [Control Flow](../control_flow.md) and +[Assert Function](../assert.md) sections. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/fields.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/fields.md new file mode 100644 index 00000000000..f8b1e727816 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/fields.md @@ -0,0 +1,246 @@ +--- +title: Fields +description: + Dive deep into the Field data type in Noir. Understand its methods, practical examples, and best practices to effectively use Fields in your Noir programs. +keywords: + [ + noir, + field type, + methods, + examples, + best practices, + ] +sidebar_position: 0 +--- + +The field type corresponds to the native field type of the proving backend. + +The size of a Noir field depends on the elliptic curve's finite field for the proving backend +adopted. For example, a field would be a 254-bit integer when paired with the default backend that +spans the Grumpkin curve. + +Fields support integer arithmetic and are often used as the default numeric type in Noir: + +```rust +fn main(x : Field, y : Field) { + let z = x + y; +} +``` + +`x`, `y` and `z` are all private fields in this example. Using the `let` keyword we defined a new +private value `z` constrained to be equal to `x + y`. + +If proving efficiency is of priority, fields should be used as a default for solving problems. +Smaller integer types (e.g. `u64`) incur extra range constraints. + +## Methods + +After declaring a Field, you can use these common methods on it: + +### to_le_bits + +Transforms the field into an array of bits, Little Endian. + +```rust title="to_le_bits" showLineNumbers +pub fn to_le_bits(self: Self) -> [u1; N] {} +``` +> Source code: noir_stdlib/src/field/mod.nr#L32-L34 + + +example: + +```rust title="to_le_bits_example" showLineNumbers +fn test_to_le_bits() { + let field = 2; + let bits: [u1; 8] = field.to_le_bits(); + assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]); + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L260-L266 + + + +### to_be_bits + +Transforms the field into an array of bits, Big Endian. + +```rust title="to_be_bits" showLineNumbers +pub fn to_be_bits(self: Self) -> [u1; N] {} +``` +> Source code: noir_stdlib/src/field/mod.nr#L48-L50 + + +example: + +```rust title="to_be_bits_example" showLineNumbers +fn test_to_be_bits() { + let field = 2; + let bits: [u1; 8] = field.to_be_bits(); + assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]); + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L251-L257 + + + +### to_le_bytes + +Transforms into an array of bytes, Little Endian + +```rust title="to_le_bytes" showLineNumbers +pub fn to_le_bytes(self: Self) -> [u8; N] { +``` +> Source code: noir_stdlib/src/field/mod.nr#L61-L63 + + +example: + +```rust title="to_le_bytes_example" showLineNumbers +fn test_to_le_bytes() { + let field = 2; + let bits: [u8; 8] = field.to_le_bytes(); + assert_eq(bits, [2, 0, 0, 0, 0, 0, 0, 0]); + assert_eq(Field::from_le_bytes::<8>(bits), field); + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L279-L286 + + +### to_be_bytes + +Transforms into an array of bytes, Big Endian + +```rust title="to_be_bytes" showLineNumbers +pub fn to_be_bytes(self: Self) -> [u8; N] { +``` +> Source code: noir_stdlib/src/field/mod.nr#L94-L96 + + +example: + +```rust title="to_be_bytes_example" showLineNumbers +fn test_to_be_bytes() { + let field = 2; + let bits: [u8; 8] = field.to_be_bytes(); + assert_eq(bits, [0, 0, 0, 0, 0, 0, 0, 2]); + assert_eq(Field::from_be_bytes::<8>(bits), field); + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L269-L276 + + + +### to_le_radix + +Decomposes into an array over the specified base, Little Endian + +```rust title="to_le_radix" showLineNumbers +pub fn to_le_radix(self: Self, radix: u32) -> [u8; N] { + // Brillig does not need an immediate radix + if !crate::runtime::is_unconstrained() { + crate::assert_constant(radix); + } + self.__to_le_radix(radix) + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L118-L126 + + + +example: + +```rust title="to_le_radix_example" showLineNumbers +fn test_to_le_radix() { + let field = 2; + let bits: [u8; 8] = field.to_le_radix(256); + assert_eq(bits, [2, 0, 0, 0, 0, 0, 0, 0]); + assert_eq(Field::from_le_bytes::<8>(bits), field); + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L299-L306 + + + +### to_be_radix + +Decomposes into an array over the specified base, Big Endian + +```rust title="to_be_radix" showLineNumbers +pub fn to_be_radix(self: Self, radix: u32) -> [u8; N] { + // Brillig does not need an immediate radix + if !crate::runtime::is_unconstrained() { + crate::assert_constant(radix); + } + self.__to_be_radix(radix) + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L128-L136 + + +example: + +```rust title="to_be_radix_example" showLineNumbers +fn test_to_be_radix() { + let field = 2; + let bits: [u8; 8] = field.to_be_radix(256); + assert_eq(bits, [0, 0, 0, 0, 0, 0, 0, 2]); + assert_eq(Field::from_be_bytes::<8>(bits), field); + } +``` +> Source code: noir_stdlib/src/field/mod.nr#L289-L296 + + + +### pow_32 + +Returns the value to the power of the specified exponent + +```rust +fn pow_32(self, exponent: Field) -> Field +``` + +example: + +```rust +fn main() { + let field = 2 + let pow = field.pow_32(4); + assert(pow == 16); +} +``` + +### assert_max_bit_size + +Adds a constraint to specify that the field can be represented with `bit_size` number of bits + +```rust title="assert_max_bit_size" showLineNumbers +pub fn assert_max_bit_size(self) { +``` +> Source code: noir_stdlib/src/field/mod.nr#L10-L12 + + +example: + +```rust +fn main() { + let field = 2 + field.assert_max_bit_size(32); +} +``` + +### sgn0 + +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. + +```rust +fn sgn0(self) -> u1 +``` + + +### lt + +Returns true if the field is less than the other field + +```rust +pub fn lt(self, another: Field) -> bool +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/function_types.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/function_types.md new file mode 100644 index 00000000000..f6121af17e2 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/function_types.md @@ -0,0 +1,26 @@ +--- +title: Function types +sidebar_position: 10 +--- + +Noir supports higher-order functions. The syntax for a function type is as follows: + +```rust +fn(arg1_type, arg2_type, ...) -> return_type +``` + +Example: + +```rust +fn assert_returns_100(f: fn() -> Field) { // f takes no args and returns a Field + assert(f() == 100); +} + +fn main() { + assert_returns_100(|| 100); // ok + assert_returns_100(|| 150); // fails +} +``` + +A function type also has an optional capture environment - this is necessary to support closures. +See [Lambdas](../lambdas.md) for more details. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/index.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/index.md new file mode 100644 index 00000000000..0f2db2b2d75 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/index.md @@ -0,0 +1,126 @@ +--- +title: Data Types +description: + Get a clear understanding of the two categories of Noir data types - primitive types and compound + types. Learn about their characteristics, differences, and how to use them in your Noir + programming. +keywords: + [ + noir, + data types, + primitive types, + compound types, + private types, + public types, + ] +--- + +Every value in Noir has a type, which determines which operations are valid for it. + +All values in Noir are fundamentally composed of `Field` elements. For a more approachable +developing experience, abstractions are added on top to introduce different data types in Noir. + +Noir has two category of data types: primitive types (e.g. `Field`, integers, `bool`) and compound +types that group primitive types (e.g. arrays, tuples, structs). Each value can either be private or +public. + +## Private & Public Types + +A **private value** is known only to the Prover, while a **public value** is known by both the +Prover and Verifier. Mark values as `private` when the value should only be known to the prover. All +primitive types (including individual fields of compound types) in Noir are private by default, and +can be marked public when certain values are intended to be revealed to the Verifier. + +> **Note:** For public values defined in Noir programs paired with smart contract verifiers, once +> the proofs are verified on-chain the values can be considered known to everyone that has access to +> that blockchain. + +Public data types are treated no differently to private types apart from the fact that their values +will be revealed in proofs generated. Simply changing the value of a public type will not change the +circuit (where the same goes for changing values of private types as well). + +_Private values_ are also referred to as _witnesses_ sometimes. + +> **Note:** The terms private and public when applied to a type (e.g. `pub Field`) have a different +> meaning than when applied to a function (e.g. `pub fn foo() {}`). +> +> The former is a visibility modifier for the Prover to interpret if a value should be made known to +> the Verifier, while the latter is a visibility modifier for the compiler to interpret if a +> function should be made accessible to external Noir programs like in other languages. + +### pub Modifier + +All data types in Noir are private by default. Types are explicitly declared as public using the +`pub` modifier: + +```rust +fn main(x : Field, y : pub Field) -> pub Field { + x + y +} +``` + +In this example, `x` is **private** while `y` and `x + y` (the return value) are **public**. Note +that visibility is handled **per variable**, so it is perfectly valid to have one input that is +private and another that is public. + +> **Note:** Public types can only be declared through parameters on `main`. + +## Type Aliases + +A type alias is a new name for an existing type. Type aliases are declared with the keyword `type`: + +```rust +type Id = u8; + +fn main() { + let id: Id = 1; + let zero: u8 = 0; + assert(zero + 1 == id); +} +``` + +Type aliases can also be used with [generics](../generics.md): + +```rust +type Id = Size; + +fn main() { + let id: Id = 1; + let zero: u32 = 0; + assert(zero + 1 == id); +} +``` + +Type aliases can even refer to other aliases. An error will be issued if they form a cycle: + +```rust +// Ok! +type A = B; +type B = Field; + +type Bad1 = Bad2; + +// error: Dependency cycle found +type Bad2 = Bad1; +// ^^^^^^^^^^^ 'Bad2' recursively depends on itself: Bad2 -> Bad1 -> Bad2 +``` + +By default, like functions, type aliases are private to the module they exist in. You can use `pub` +to make the type alias public or `pub(crate)` to make it public to just its crate: + +```rust +// This type alias is now public +pub type Id = u8; +``` + +## Wildcard Type +Noir can usually infer the type of the variable from the context, so specifying the type of a variable is only required when it cannot be inferred. However, specifying a complex type can be tedious, especially when it has multiple generic arguments. Often some of the generic types can be inferred from the context, and Noir only needs a hint to properly infer the other types. We can partially specify a variable's type by using `_` as a marker, indicating where we still want the compiler to infer the type. + +```rust +let a: [_; 4] = foo(b); +``` + + +### BigInt + +You can achieve BigInt functionality using the [Noir BigInt](https://github.com/shuklaayush/noir-bigint) library. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/integers.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/integers.md new file mode 100644 index 00000000000..a1d59bf3166 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/integers.md @@ -0,0 +1,156 @@ +--- +title: Integers +description: Explore the Integer data type in Noir. Learn about its methods, see real-world examples, and grasp how to efficiently use Integers in your Noir code. +keywords: [noir, integer types, methods, examples, arithmetic] +sidebar_position: 1 +--- + +An integer type is a range constrained field type. +The Noir frontend supports both unsigned and signed integer types. +The allowed sizes are 1, 8, 16, 32 and 64 bits. + +:::info + +When an integer is defined in Noir without a specific type, it will default to `Field`. + +The one exception is for loop indices which default to `u64` since comparisons on `Field`s are not possible. + +::: + +## Unsigned Integers + +An unsigned integer type is specified first with the letter `u` (indicating its unsigned nature) followed by its bit size (e.g. `8`): + +```rust +fn main() { + let x: u8 = 1; + let y: u8 = 1; + let z = x + y; + assert (z == 2); +} +``` + +The bit size determines the maximum value the integer type can store. For example, a `u8` variable can store a value in the range of 0 to 255 (i.e. $\\2^{8}-1\\$). + +## Signed Integers + +A signed integer type is specified first with the letter `i` (which stands for integer) followed by its bit size (e.g. `8`): + +```rust +fn main() { + let x: i8 = -1; + let y: i8 = -1; + let z = x + y; + assert (z == -2); +} +``` + +The bit size determines the maximum and minimum range of value the integer type can store. For example, an `i8` variable can store a value in the range of -128 to 127 (i.e. $\\-2^{7}\\$ to $\\2^{7}-1\\$). + +## 128 bits Unsigned Integers + +The built-in structure `U128` allows you to use 128-bit unsigned integers almost like a native integer type. However, there are some differences to keep in mind: +- You cannot cast between a native integer and `U128` +- There is a higher performance cost when using `U128`, compared to a native type. + +Conversion between unsigned integer types and U128 are done through the use of `from_integer` and `to_integer` functions. `from_integer` also accepts the `Field` type as input. + +```rust +fn main() { + let x = U128::from_integer(23); + let y = U128::from_hex("0x7"); + let z = x + y; + assert(z.to_integer() == 30); +} +``` + +`U128` is implemented with two 64 bits limbs, representing the low and high bits, which explains the performance cost. You should expect `U128` to be twice more costly for addition and four times more costly for multiplication. +You can construct a U128 from its limbs: +```rust +fn main(x: u64, y: u64) { + let x = U128::from_u64s_be(x,y); + assert(z.hi == x as Field); + assert(z.lo == y as Field); +} +``` + +Note that the limbs are stored as Field elements in order to avoid unnecessary conversions. +Apart from this, most operations will work as usual: + +```rust +fn main(x: U128, y: U128) { + // multiplication + let c = x * y; + // addition and subtraction + let c = c - x + y; + // division + let c = x / y; + // bit operation; + let c = x & y | y; + // bit shift + let c = x << y; + // comparisons; + let c = x < y; + let c = x == y; +} +``` + +## Overflows + +Computations that exceed the type boundaries will result in overflow errors. This happens with both signed and unsigned integers. For example, attempting to prove: + +```rust +fn main(x: u8, y: u8) { + let z = x + y; +} +``` + +With: + +```toml +x = "255" +y = "1" +``` + +Would result in: + +``` +$ nargo execute +error: Assertion failed: 'attempt to add with overflow' +┌─ ~/src/main.nr:9:13 +│ +│ let z = x + y; +│ ----- +│ += Call stack: + ... +``` + +A similar error would happen with signed integers: + +```rust +fn main() { + let x: i8 = -118; + let y: i8 = -11; + let z = x + y; +} +``` + +### Wrapping methods + +Although integer overflow is expected to error, some use-cases rely on wrapping. For these use-cases, the standard library provides `wrapping` variants of certain common operations: + +```rust +fn wrapping_add(x: T, y: T) -> T; +fn wrapping_sub(x: T, y: T) -> T; +fn wrapping_mul(x: T, y: T) -> T; +``` + +Example of how it is used: + +```rust + +fn main(x: u8, y: u8) -> pub u8 { + std::wrapping_add(x, y) +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/references.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/references.md new file mode 100644 index 00000000000..a5293d11cfb --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/references.md @@ -0,0 +1,23 @@ +--- +title: References +sidebar_position: 9 +--- + +Noir supports first-class references. References are a bit like pointers: they point to a specific address that can be followed to access the data stored at that address. You can use Rust-like syntax to use pointers in Noir: the `&` operator references the variable, the `*` operator dereferences it. + +Example: + +```rust +fn main() { + let mut x = 2; + + // you can reference x as &mut and pass it to multiplyBy2 + multiplyBy2(&mut x); +} + +// you can access &mut here +fn multiplyBy2(x: &mut Field) { + // and dereference it with * + *x = *x * 2; +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/slices.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/slices.mdx new file mode 100644 index 00000000000..cfee564a302 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/slices.mdx @@ -0,0 +1,358 @@ +--- +title: Slices +description: Explore the Slice data type in Noir. Understand its methods, see real-world examples, and learn how to effectively use Slices in your Noir programs. +keywords: [noir, slice type, methods, examples, subarrays] +sidebar_position: 5 +--- + +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +A slice is a dynamically-sized view into a sequence of elements. They can be resized at runtime, but because they don't own the data, they cannot be returned from a circuit. You can treat slices as arrays without a constrained size. + +```rust +fn main() -> pub u32 { + let mut slice: [Field] = &[0; 2]; + + let mut new_slice = slice.push_back(6); + new_slice.len() +} +``` + +To write a slice literal, use a preceding ampersand as in: `&[0; 2]` or +`&[1, 2, 3]`. + +It is important to note that slices are not references to arrays. In Noir, +`&[..]` is more similar to an immutable, growable vector. + +View the corresponding test file [here][test-file]. + +[test-file]: https://github.com/noir-lang/noir/blob/f387ec1475129732f72ba294877efdf6857135ac/crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr + +## Methods + +For convenience, the STD provides some ready-to-use, common methods for slices: + +### push_back + +Pushes a new element to the end of the slice, returning a new slice with a length one greater than the original unmodified slice. + +```rust +fn push_back(_self: [T], _elem: T) -> [T] +``` + +example: + +```rust +fn main() -> pub Field { + let mut slice: [Field] = &[0; 2]; + + let mut new_slice = slice.push_back(6); + new_slice.len() +} +``` + +View the corresponding test file [here][test-file]. + +### push_front + +Returns a new array with the specified element inserted at index 0. The existing elements indexes are incremented by 1. + +```rust +fn push_front(_self: Self, _elem: T) -> Self +``` + +Example: + +```rust +let mut new_slice: [Field] = &[]; +new_slice = new_slice.push_front(20); +assert(new_slice[0] == 20); // returns true +``` + +View the corresponding test file [here][test-file]. + +### pop_front + +Returns a tuple of two items, the first element of the array and the rest of the array. + +```rust +fn pop_front(_self: Self) -> (T, Self) +``` + +Example: + +```rust +let (first_elem, rest_of_slice) = slice.pop_front(); +``` + +View the corresponding test file [here][test-file]. + +### pop_back + +Returns a tuple of two items, the beginning of the array with the last element omitted and the last element. + +```rust +fn pop_back(_self: Self) -> (Self, T) +``` + +Example: + +```rust +let (popped_slice, last_elem) = slice.pop_back(); +``` + +View the corresponding test file [here][test-file]. + +### append + +Loops over a slice and adds it to the end of another. + +```rust +fn append(mut self, other: Self) -> Self +``` + +Example: + +```rust +let append = &[1, 2].append(&[3, 4, 5]); +``` + +### insert + +Inserts an element at a specified index and shifts all following elements by 1. + +```rust +fn insert(_self: Self, _index: Field, _elem: T) -> Self +``` + +Example: + +```rust +new_slice = rest_of_slice.insert(2, 100); +assert(new_slice[2] == 100); +``` + +View the corresponding test file [here][test-file]. + +### remove + +Remove an element at a specified index, shifting all elements after it to the left, returning the altered slice and the removed element. + +```rust +fn remove(_self: Self, _index: Field) -> (Self, T) +``` + +Example: + +```rust +let (remove_slice, removed_elem) = slice.remove(3); +``` + +### len + +Returns the length of a slice + +```rust +fn len(self) -> Field +``` + +Example: + +```rust +fn main() { + let slice = &[42, 42]; + assert(slice.len() == 2); +} +``` + +### as_array + +Converts this slice into an array. + +Make sure to specify the size of the resulting array. +Panics if the resulting array length is different than the slice's length. + +```rust +fn as_array(self) -> [T; N] +``` + +Example: + +```rust +fn main() { + let slice = &[5, 6]; + + // Always specify the length of the resulting array! + let array: [Field; 2] = slice.as_array(); + + assert(array[0] == slice[0]); + assert(array[1] == slice[1]); +} +``` + +### map + +Applies a function to each element of the slice, returning a new slice containing the mapped elements. + +```rust +fn map(self, f: fn[Env](T) -> U) -> [U] +``` + +example + +```rust +let a = &[1, 2, 3]; +let b = a.map(|a| a * 2); // b is now &[2, 4, 6] +``` + +### fold + +Applies a function to each element of the slice, returning the final accumulated value. The first +parameter is the initial value. + +```rust +fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U +``` + +This is a left fold, so the given function will be applied to the accumulator and first element of +the slice, then the second, and so on. For a given call the expected result would be equivalent to: + +```rust +let a1 = &[1]; +let a2 = &[1, 2]; +let a3 = &[1, 2, 3]; + +let f = |a, b| a - b; +a1.fold(10, f) //=> f(10, 1) +a2.fold(10, f) //=> f(f(10, 1), 2) +a3.fold(10, f) //=> f(f(f(10, 1), 2), 3) +``` + +example: + +```rust + +fn main() { + let slice = &[2, 2, 2, 2, 2]; + let folded = slice.fold(0, |a, b| a + b); + assert(folded == 10); +} + +``` + +### reduce + +Same as fold, but uses the first element as the starting element. + +```rust +fn reduce(self, f: fn[Env](T, T) -> T) -> T +``` + +example: + +```rust +fn main() { + let slice = &[2, 2, 2, 2, 2]; + let reduced = slice.reduce(|a, b| a + b); + assert(reduced == 10); +} +``` + +### filter + +Returns a new slice containing only elements for which the given predicate returns true. + +```rust +fn filter(self, f: fn[Env](T) -> bool) -> Self +``` + +example: + +```rust +fn main() { + let slice = &[1, 2, 3, 4, 5]; + let odds = slice.filter(|x| x % 2 == 1); + assert_eq(odds, &[1, 3, 5]); +} +``` + +### join + +Flatten each element in the slice into one value, separated by `separator`. + +Note that although slices implement `Append`, `join` cannot be used on slice +elements since nested slices are prohibited. + +```rust +fn join(self, separator: T) -> T where T: Append +``` + +example: + +```rust +struct Accumulator { + total: Field, +} + +// "Append" two accumulators by adding them +impl Append for Accumulator { + fn empty() -> Self { + Self { total: 0 } + } + + fn append(self, other: Self) -> Self { + Self { total: self.total + other.total } + } +} + +fn main() { + let slice = &[1, 2, 3, 4, 5].map(|total| Accumulator { total }); + + let result = slice.join(Accumulator::empty()); + assert_eq(result, Accumulator { total: 15 }); + + // We can use a non-empty separator to insert additional elements to sum: + let separator = Accumulator { total: 10 }; + let result = slice.join(separator); + assert_eq(result, Accumulator { total: 55 }); +} +``` + +### all + +Returns true if all the elements satisfy the given predicate + +```rust +fn all(self, predicate: fn[Env](T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let slice = &[2, 2, 2, 2, 2]; + let all = slice.all(|a| a == 2); + assert(all); +} +``` + +### any + +Returns true if any of the elements satisfy the given predicate + +```rust +fn any(self, predicate: fn[Env](T) -> bool) -> bool +``` + +example: + +```rust +fn main() { + let slice = &[2, 2, 2, 2, 5]; + let any = slice.any(|a| a == 5); + assert(any); +} + +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/strings.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/strings.md new file mode 100644 index 00000000000..1fdee42425e --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/strings.md @@ -0,0 +1,79 @@ +--- +title: Strings +description: + Discover the String data type in Noir. Learn about its methods, see real-world examples, and understand how to effectively manipulate and use Strings in Noir. +keywords: + [ + noir, + string type, + methods, + examples, + concatenation, + ] +sidebar_position: 3 +--- + + +The string type is a fixed length value defined with `str`. + +You can use strings in `assert()` functions or print them with +`println()`. See more about [Logging](../../standard_library/logging.md). + +```rust + +fn main(message : pub str<11>, hex_as_string : str<4>) { + println(message); + assert(message == "hello world"); + assert(hex_as_string == "0x41"); +} +``` + +You can convert a `str` to a byte array by calling `as_bytes()` +or a vector by calling `as_bytes_vec()`. + +```rust +fn main() { + let message = "hello world"; + let message_bytes = message.as_bytes(); + let mut message_vec = message.as_bytes_vec(); + assert(message_bytes.len() == 11); + assert(message_bytes[0] == 104); + assert(message_bytes[0] == message_vec.get(0)); +} +``` + +## Escape characters + +You can use escape characters for your strings: + +| Escape Sequence | Description | +|-----------------|-----------------| +| `\r` | Carriage Return | +| `\n` | Newline | +| `\t` | Tab | +| `\0` | Null Character | +| `\"` | Double Quote | +| `\\` | Backslash | + +Example: + +```rust +let s = "Hello \"world" // prints "Hello "world" +let s = "hey \tyou"; // prints "hey you" +``` + +## Raw strings + +A raw string begins with the letter `r` and is optionally delimited by a number of hashes `#`. + +Escape characters are *not* processed within raw strings. All contents are interpreted literally. + +Example: + +```rust +let s = r"Hello world"; +let s = r#"Simon says "hello world""#; + +// Any number of hashes may be used (>= 1) as long as the string also terminates with the same number of hashes +let s = r#####"One "#, Two "##, Three "###, Four "####, Five will end the string."#####; +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/structs.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/structs.md new file mode 100644 index 00000000000..29951ae843a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/structs.md @@ -0,0 +1,96 @@ +--- +title: Structs +description: + Explore the Struct data type in Noir. Learn about its methods, see real-world examples, and grasp how to effectively define and use Structs in your Noir programs. +keywords: + [ + noir, + struct type, + methods, + examples, + data structures, + ] +sidebar_position: 8 +--- + +A struct also allows for grouping multiple values of different types. Unlike tuples, we can also +name each field. + +> **Note:** The usage of _field_ here refers to each element of the struct and is unrelated to the +> field type of Noir. + +Defining a struct requires giving it a name and listing each field within as `: ` pairs: + +```rust +struct Animal { + hands: Field, + legs: Field, + eyes: u8, +} +``` + +An instance of a struct can then be created with actual values in `: ` pairs in any +order. Struct fields are accessible using their given names: + +```rust +fn main() { + let legs = 4; + + let dog = Animal { + eyes: 2, + hands: 0, + legs, + }; + + let zero = dog.hands; +} +``` + +Structs can also be destructured in a pattern, binding each field to a new variable: + +```rust +fn main() { + let Animal { hands, legs: feet, eyes } = get_octopus(); + + let ten = hands + feet + eyes as u8; +} + +fn get_octopus() -> Animal { + let octopus = Animal { + hands: 0, + legs: 8, + eyes: 2, + }; + + octopus +} +``` + +The new variables can be bound with names different from the original struct field names, as +showcased in the `legs --> feet` binding in the example above. + +### Visibility + +By default, like functions, structs are private to the module they exist in. You can use `pub` +to make the struct public or `pub(crate)` to make it public to just its crate: + +```rust +// This struct is now public +pub struct Animal { + hands: Field, + legs: Field, + eyes: u8, +} +``` + +The same applies to struct fields: by default they are private to the module they exist in, +but they can be made `pub` or `pub(crate)`: + +```rust +// This struct is now public +pub struct Animal { + hands: Field, // private to its module + pub(crate) legs: Field, // accessible from the entire crate + pub eyes: u8, // accessible from anywhere +} +``` \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/tuples.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/tuples.md new file mode 100644 index 00000000000..2ec5c9c4113 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/data_types/tuples.md @@ -0,0 +1,48 @@ +--- +title: Tuples +description: + Dive into the Tuple data type in Noir. Understand its methods, practical examples, and best practices for efficiently using Tuples in your Noir code. +keywords: + [ + noir, + tuple type, + methods, + examples, + multi-value containers, + ] +sidebar_position: 7 +--- + +A tuple collects multiple values like an array, but with the added ability to collect values of +different types: + +```rust +fn main() { + let tup: (u8, u64, Field) = (255, 500, 1000); +} +``` + +One way to access tuple elements is via destructuring using pattern matching: + +```rust +fn main() { + let tup = (1, 2); + + let (one, two) = tup; + + let three = one + two; +} +``` + +Another way to access tuple elements is via direct member access, using a period (`.`) followed by +the index of the element we want to access. Index `0` corresponds to the first tuple element, `1` to +the second and so on: + +```rust +fn main() { + let tup = (5, 6, 7, 8); + + let five = tup.0; + let eight = tup.3; +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/functions.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/functions.md new file mode 100644 index 00000000000..f656cdfd97a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/functions.md @@ -0,0 +1,226 @@ +--- +title: Functions +description: + Learn how to declare functions and methods in Noir, a programming language with Rust semantics. + This guide covers parameter declaration, return types, call expressions, and more. +keywords: [Noir, Rust, functions, methods, parameter declaration, return types, call expressions] +sidebar_position: 1 +--- + +Functions in Noir follow the same semantics of Rust, though Noir does not support early returns. + +To declare a function the `fn` keyword is used. + +```rust +fn foo() {} +``` + +By default, functions are visible only within the package they are defined. To make them visible outside of that package (for example, as part of a [library](../modules_packages_crates/crates_and_packages.md#libraries)), you should mark them as `pub`: + +```rust +pub fn foo() {} +``` + +You can also restrict the visibility of the function to only the crate it was defined in, by specifying `pub(crate)`: + +```rust +pub(crate) fn foo() {} //foo can only be called within its crate +``` + +All parameters in a function must have a type and all types are known at compile time. The parameter +is pre-pended with a colon and the parameter type. Multiple parameters are separated using a comma. + +```rust +fn foo(x : Field, y : Field){} +``` + +The return type of a function can be stated by using the `->` arrow notation. The function below +states that the foo function must return a `Field`. If the function returns no value, then the arrow +is omitted. + +```rust +fn foo(x : Field, y : Field) -> Field { + x + y +} +``` + +Note that a `return` keyword is unneeded in this case - the last expression in a function's body is +returned. + +## Main function + +If you're writing a binary, the `main` function is the starting point of your program. You can pass all types of expressions to it, as long as they have a fixed size at compile time: + +```rust +fn main(x : Field) // this is fine: passing a Field +fn main(x : [Field; 2]) // this is also fine: passing a Field with known size at compile-time +fn main(x : (Field, bool)) // 👌: passing a (Field, bool) tuple means size 2 +fn main(x : str<5>) // this is fine, as long as you pass a string of size 5 + +fn main(x : Vec) // can't compile, has variable size +fn main(x : [Field]) // can't compile, has variable size +fn main(....// i think you got it by now +``` + +Keep in mind [tests](../../tooling/testing.md) don't differentiate between `main` and any other function. The following snippet passes tests, but won't compile or prove: + +```rust +fn main(x : [Field]) { + assert(x[0] == 1); +} + +#[test] +fn test_one() { + main(&[1, 2]); +} +``` + +```bash +$ nargo test +[testing] Running 1 test functions +[testing] Testing test_one... ok +[testing] All tests passed + +$ nargo check +The application panicked (crashed). +Message: Cannot have variable sized arrays as a parameter to main +``` + +## Call Expressions + +Calling a function in Noir is executed by using the function name and passing in the necessary +arguments. + +Below we show how to call the `foo` function from the `main` function using a call expression: + +```rust +fn main(x : Field, y : Field) { + let z = foo(x); +} + +fn foo(x : Field) -> Field { + x + x +} +``` + +## Methods + +You can define methods in Noir on any struct type in scope. + +```rust +struct MyStruct { + foo: Field, + bar: Field, +} + +impl MyStruct { + fn new(foo: Field) -> MyStruct { + MyStruct { + foo, + bar: 2, + } + } + + fn sum(self) -> Field { + self.foo + self.bar + } +} + +fn main() { + let s = MyStruct::new(40); + assert(s.sum() == 42); +} +``` + +Methods are just syntactic sugar for functions, so if we wanted to we could also call `sum` as +follows: + +```rust +assert(MyStruct::sum(s) == 42); +``` + +It is also possible to specialize which method is chosen depending on the [generic](./generics.md) type that is used. In this example, the `foo` function returns different values depending on its type: + +```rust +struct Foo {} + +impl Foo { + fn foo(self) -> Field { 1 } +} + +impl Foo { + fn foo(self) -> Field { 2 } +} + +fn main() { + let f1: Foo = Foo{}; + let f2: Foo = Foo{}; + assert(f1.foo() + f2.foo() == 3); +} +``` + +Also note that impls with the same method name defined in them cannot overlap. For example, if we already have `foo` defined for `Foo` and `Foo` like we do above, we cannot also define `foo` in an `impl Foo` since it would be ambiguous which version of `foo` to choose. + +```rust +// Including this impl in the same project as the above snippet would +// cause an overlapping impls error +impl Foo { + fn foo(self) -> Field { 3 } +} +``` + +## Lambdas + +Lambdas are anonymous functions. They follow the syntax of Rust - `|arg1, arg2, ..., argN| return_expression`. + +```rust +let add_50 = |val| val + 50; +assert(add_50(100) == 150); +``` + +See [Lambdas](./lambdas.md) for more details. + +## Attributes + +Attributes are metadata that can be applied to a function, using the following syntax: `#[attribute(value)]`. + +Supported attributes include: + +- **builtin**: the function is implemented by the compiler, for efficiency purposes. +- **deprecated**: mark the function as _deprecated_. Calling the function will generate a warning: `warning: use of deprecated function` +- **field**: Used to enable conditional compilation of code depending on the field size. See below for more details +- **oracle**: mark the function as _oracle_; meaning it is an external unconstrained function, implemented in noir_js. See [Unconstrained](./unconstrained.md) and [NoirJS](../../reference/NoirJS/noir_js/index.md) for more details. +- **test**: mark the function as unit tests. See [Tests](../../tooling/testing.md) for more details + +### Field Attribute + +The field attribute defines which field the function is compatible for. The function is conditionally compiled, under the condition that the field attribute matches the Noir native field. +The field can be defined implicitly, by using the name of the elliptic curve usually associated to it - for instance bn254, bls12_381 - or explicitly by using the field (prime) order, in decimal or hexadecimal form. +As a result, it is possible to define multiple versions of a function with each version specialized for a different field attribute. This can be useful when a function requires different parameters depending on the underlying elliptic curve. + +Example: we define the function `foo()` three times below. Once for the default Noir bn254 curve, once for the field $\mathbb F_{23}$, which will normally never be used by Noir, and once again for the bls12_381 curve. + +```rust +#[field(bn254)] +fn foo() -> u32 { + 1 +} + +#[field(23)] +fn foo() -> u32 { + 2 +} + +// This commented code would not compile as foo would be defined twice because it is the same field as bn254 +// #[field(21888242871839275222246405745257275088548364400416034343698204186575808495617)] +// fn foo() -> u32 { +// 2 +// } + +#[field(bls12_381)] +fn foo() -> u32 { + 3 +} +``` + +If the field name is not known to Noir, it will discard the function. Field names are case insensitive. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/generics.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/generics.md new file mode 100644 index 00000000000..c180a0ce7e6 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/generics.md @@ -0,0 +1,251 @@ +--- +title: Generics +description: Learn how to use Generics in Noir +keywords: [Noir, Rust, generics, functions, structs] +sidebar_position: 7 +--- + +Generics allow you to use the same functions with multiple different concrete data types. You can +read more about the concept of generics in the Rust documentation +[here](https://doc.rust-lang.org/book/ch10-01-syntax.html). + +Here is a trivial example showing the identity function that supports any type. In Rust, it is +common to refer to the most general type as `T`. We follow the same convention in Noir. + +```rust +fn id(x: T) -> T { + x +} +``` + +## Numeric Generics + +If we want to be generic over array lengths (which are type-level integers), we can use numeric +generics. Using these looks similar to using regular generics, but introducing them into scope +requires declaring them with `let MyGenericName: IntegerType`. This can be done anywhere a normal +generic is declared. Instead of types, these generics resolve to integers at compile-time. +Here's an example of a struct that is generic over the size of the array it contains internally: + +```rust +struct BigInt { + limbs: [u32; N], +} + +impl BigInt { + // `N` is in scope of all methods in the impl + fn first(first: BigInt, second: BigInt) -> Self { + assert(first.limbs != second.limbs); + first + + fn second(first: BigInt, second: Self) -> Self { + assert(first.limbs != second.limbs); + second + } +} +``` + +## In Structs + +Generics are useful for specifying types in structs. For example, we can specify that a field in a +struct will be of a certain generic type. In this case `value` is of type `T`. + +```rust +struct RepeatedValue { + value: T, + count: Field, +} + +impl RepeatedValue { + fn print(self) { + for _i in 0 .. self.count { + println(self.value); + } + } +} + +fn main() { + let repeated = RepeatedValue { value: "Hello!", count: 2 }; + repeated.print(); +} +``` + +The `print` function will print `Hello!` an arbitrary number of times, twice in this case. + +## Calling functions on generic parameters + +Since a generic type `T` can represent any type, how can we call functions on the underlying type? +In other words, how can we go from "any type `T`" to "any type `T` that has certain methods available?" + +This is what [traits](../concepts/traits.md) are for in Noir. Here's an example of a function generic over +any type `T` that implements the `Eq` trait for equality: + +```rust +fn first_element_is_equal(array1: [T; N], array2: [T; N]) -> bool + where T: Eq +{ + if (array1.len() == 0) | (array2.len() == 0) { + true + } else { + array1[0] == array2[0] + } +} + +fn main() { + assert(first_element_is_equal([1, 2, 3], [1, 5, 6])); + + // We can use first_element_is_equal for arrays of any type + // as long as we have an Eq impl for the types we pass in + let array = [MyStruct::new(), MyStruct::new()]; + assert(array_eq(array, array, MyStruct::eq)); +} + +impl Eq for MyStruct { + fn eq(self, other: MyStruct) -> bool { + self.foo == other.foo + } +} +``` + +You can find more details on traits and trait implementations on the [traits page](../concepts/traits.md). + +## Manually Specifying Generics with the Turbofish Operator + +There are times when the compiler cannot reasonably infer what type should be used for a generic, or when the developer themselves may want to manually distinguish generic type parameters. This is where the `::<>` turbofish operator comes into play. + +The `::<>` operator can follow a variable or path and can be used to manually specify generic arguments within the angle brackets. +The name "turbofish" comes from that `::<>` looks like a little fish. + +Examples: +```rust +fn main() { + let mut slice = []; + slice = slice.push_back(1); + slice = slice.push_back(2); + // Without turbofish a type annotation would be needed on the left hand side + let array = slice.as_array::<2>(); +} +``` + + +```rust +trait MyTrait { + fn ten() -> Self; +} + +impl MyTrait for Field { + fn ten() -> Self { 10 } +} + +struct Foo { + inner: T +} + +impl Foo { + fn generic_method(_self: Self) -> U where U: MyTrait { + U::ten() + } +} + +fn example() { + let foo: Foo = Foo { inner: 1 }; + // Using a type other than `Field` here (e.g. u32) would fail as + // there is no matching impl for `u32: MyTrait`. + // + // Substituting the `10` on the left hand side of this assert + // with `10 as u32` would also fail with a type mismatch as we + // are expecting a `Field` from the right hand side. + assert(10 as u32 == foo.generic_method::()); +} +``` + +## Arithmetic Generics + +In addition to numeric generics, Noir also allows a limited form of arithmetic on generics. +When you have a numeric generic such as `N`, you can use the following operators on it in a +type position: `+`, `-`, `*`, `/`, and `%`. + +Note that type checking arithmetic generics is a best effort guess from the compiler and there +are many cases of types that are equal that the compiler may not see as such. For example, +we know that `T * (N + M)` should be equal to `T*N + T*M` but the compiler does not currently +apply the distributive law and thus sees these as different types. + +Even with this limitation though, the compiler can handle common cases decently well: + +```rust +trait Serialize { + fn serialize(self) -> [Field; N]; +} + +impl Serialize<1> for Field { + fn serialize(self) -> [Field; 1] { + [self] + } +} + +impl Serialize for [T; N] + where T: Serialize { .. } + +impl Serialize for (T, U) + where T: Serialize, U: Serialize { .. } + +fn main() { + let data = (1, [2, 3, 4]); + assert_eq(data.serialize().len(), 4); +} +``` + +Note that if there is any over or underflow the types will fail to unify: + +```rust title="underflow-example" showLineNumbers +fn pop(array: [Field; N]) -> [Field; N - 1] { + let mut result: [Field; N - 1] = std::mem::zeroed(); + for i in 0..N - 1 { + result[i] = array[i]; + } + result +} + +fn main() { + // error: Could not determine array length `(0 - 1)` + pop([]); +} +``` +> Source code: test_programs/compile_failure/arithmetic_generics_underflow/src/main.nr#L1-L14 + + +This also applies if there is underflow in an intermediate calculation: + +```rust title="intermediate-underflow-example" showLineNumbers +fn main() { + // From main it looks like there's nothing sketchy going on + seems_fine([]); +} + +// Since `seems_fine` says it can receive and return any length N +fn seems_fine(array: [Field; N]) -> [Field; N] { + // But inside `seems_fine` we pop from the array which + // requires the length to be greater than zero. + + // error: Could not determine array length `(0 - 1)` + push_zero(pop(array)) +} + +fn pop(array: [Field; N]) -> [Field; N - 1] { + let mut result: [Field; N - 1] = std::mem::zeroed(); + for i in 0..N - 1 { + result[i] = array[i]; + } + result +} + +fn push_zero(array: [Field; N]) -> [Field; N + 1] { + let mut result: [Field; N + 1] = std::mem::zeroed(); + for i in 0..N { + result[i] = array[i]; + } + // index N is already zeroed + result +} +``` +> Source code: test_programs/compile_failure/arithmetic_generics_intermediate_underflow/src/main.nr#L1-L32 + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/globals.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/globals.md new file mode 100644 index 00000000000..6b8314399a2 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/globals.md @@ -0,0 +1,82 @@ +--- +title: Global Variables +description: + Learn about global variables in Noir. Discover how + to declare, modify, and use them in your programs. +keywords: [noir programming language, globals, global variables, constants] +sidebar_position: 8 +--- + +## Globals + + +Noir supports global variables. The global's type can be inferred by the compiler entirely: + +```rust +global N = 5; // Same as `global N: Field = 5` + +global TUPLE = (3, 2); + +fn main() { + assert(N == 5); + assert(N == TUPLE.0 + TUPLE.1); +} +``` + +:::info + +Globals can be defined as any expression, so long as they don't depend on themselves - otherwise there would be a dependency cycle! For example: + +```rust +global T = foo(T); // dependency error +``` + +::: + + +If they are initialized to a literal integer, globals can be used to specify an array's length: + +```rust +global N: u32 = 2; + +fn main(y : [Field; N]) { + assert(y[0] == y[1]) +} +``` + +A global from another module can be imported or referenced externally like any other name: + +```rust +global N = 20; + +fn main() { + assert(my_submodule::N != N); +} + +mod my_submodule { + global N: Field = 10; +} +``` + +When a global is used, Noir replaces the name with its definition on each occurrence. +This means globals defined using function calls will repeat the call each time they're used: + +```rust +global RESULT = foo(); + +fn foo() -> [Field; 100] { ... } +``` + +This is usually fine since Noir will generally optimize any function call that does not +refer to a program input into a constant. It should be kept in mind however, if the called +function performs side-effects like `println`, as these will still occur on each use. + +### Visibility + +By default, like functions, globals are private to the module they exist in. You can use `pub` +to make the global public or `pub(crate)` to make it public to just its crate: + +```rust +// This global is now public +pub global N = 5; +``` \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/lambdas.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/lambdas.md new file mode 100644 index 00000000000..be3c7e0b5ca --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/lambdas.md @@ -0,0 +1,81 @@ +--- +title: Lambdas +description: Learn how to use anonymous functions in Noir programming language. +keywords: [Noir programming language, lambda, closure, function, anonymous function] +sidebar_position: 9 +--- + +## Introduction + +Lambdas are anonymous functions. The syntax is `|arg1, arg2, ..., argN| return_expression`. + +```rust +let add_50 = |val| val + 50; +assert(add_50(100) == 150); +``` + +A block can be used as the body of a lambda, allowing you to declare local variables inside it: + +```rust +let cool = || { + let x = 100; + let y = 100; + x + y +} + +assert(cool() == 200); +``` + +## Closures + +Inside the body of a lambda, you can use variables defined in the enclosing function. Such lambdas are called **closures**. In this example `x` is defined inside `main` and is accessed from within the lambda: + +```rust +fn main() { + let x = 100; + let closure = || x + 150; + assert(closure() == 250); +} +``` + +## Passing closures to higher-order functions + +It may catch you by surprise that the following code fails to compile: + +```rust +fn foo(f: fn () -> Field) -> Field { + f() +} + +fn main() { + let (x, y) = (50, 50); + assert(foo(|| x + y) == 100); // error :( +} +``` + +The reason is that the closure's capture environment affects its type - we have a closure that captures two Fields and `foo` +expects a regular function as an argument - those are incompatible. +:::note + +Variables contained within the `||` are the closure's parameters, and the expression that follows it is the closure's body. The capture environment is comprised of any variables used in the closure's body that are not parameters. + +E.g. in |x| x + y, y would be a captured variable, but x would not be, since it is a parameter of the closure. + +::: +The syntax for the type of a closure is `fn[env](args) -> ret_type`, where `env` is the capture environment of the closure - +in this example that's `(Field, Field)`. + +The best solution in our case is to make `foo` generic over the environment type of its parameter, so that it can be called +with closures with any environment, as well as with regular functions: + +```rust +fn foo(f: fn[Env]() -> Field) -> Field { + f() +} + +fn main() { + let (x, y) = (50, 50); + assert(foo(|| x + y) == 100); // compiles fine + assert(foo(|| 60) == 60); // compiles fine +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/mutability.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/mutability.md new file mode 100644 index 00000000000..fdeef6a87c5 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/mutability.md @@ -0,0 +1,121 @@ +--- +title: Mutability +description: + Learn about mutable variables in Noir. Discover how + to declare, modify, and use them in your programs. +keywords: [noir programming language, mutability in noir, mutable variables] +sidebar_position: 8 +--- + +Variables in noir can be declared mutable via the `mut` keyword. Mutable variables can be reassigned +to via an assignment expression. + +```rust +let x = 2; +x = 3; // error: x must be mutable to be assigned to + +let mut y = 3; +let y = 4; // OK +``` + +The `mut` modifier can also apply to patterns: + +```rust +let (a, mut b) = (1, 2); +a = 11; // error: a must be mutable to be assigned to +b = 12; // OK + +let mut (c, d) = (3, 4); +c = 13; // OK +d = 14; // OK + +// etc. +let MyStruct { x: mut y } = MyStruct { x: a }; +// y is now in scope +``` + +Note that mutability in noir is local and everything is passed by value, so if a called function +mutates its parameters then the parent function will keep the old value of the parameters. + +```rust +fn main() -> pub Field { + let x = 3; + helper(x); + x // x is still 3 +} + +fn helper(mut x: i32) { + x = 4; +} +``` + +## Non-local mutability + +Non-local mutability can be achieved through the mutable reference type `&mut T`: + +```rust +fn set_to_zero(x: &mut Field) { + *x = 0; +} + +fn main() { + let mut y = 42; + set_to_zero(&mut y); + assert(*y == 0); +} +``` + +When creating a mutable reference, the original variable being referred to (`y` in this +example) must also be mutable. Since mutable references are a reference type, they must +be explicitly dereferenced via `*` to retrieve the underlying value. Note that this yields +a copy of the value, so mutating this copy will not change the original value behind the +reference: + +```rust +fn main() { + let mut x = 1; + let x_ref = &mut x; + + let mut y = *x_ref; + let y_ref = &mut y; + + x = 2; + *x_ref = 3; + + y = 4; + *y_ref = 5; + + assert(x == 3); + assert(*x_ref == 3); + assert(y == 5); + assert(*y_ref == 5); +} +``` + +Note that types in Noir are actually deeply immutable so the copy that occurs when +dereferencing is only a conceptual copy - no additional constraints will occur. + +Mutable references can also be stored within structs. Note that there is also +no lifetime parameter on these unlike rust. This is because the allocated memory +always lasts the entire program - as if it were an array of one element. + +```rust +struct Foo { + x: &mut Field +} + +impl Foo { + fn incr(mut self) { + *self.x += 1; + } +} + +fn main() { + let foo = Foo { x: &mut 0 }; + foo.incr(); + assert(*foo.x == 1); +} +``` + +In general, you should avoid non-local & shared mutability unless it is needed. Sticking +to only local mutability will improve readability and potentially improve compiler optimizations as well. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/ops.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/ops.md new file mode 100644 index 00000000000..c35c36c38a9 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/ops.md @@ -0,0 +1,98 @@ +--- +title: Logical Operations +description: + Learn about the supported arithmetic and logical operations in the Noir programming language. + Discover how to perform operations on private input types, integers, and booleans. +keywords: + [ + Noir programming language, + supported operations, + arithmetic operations, + logical operations, + predicate operators, + bitwise operations, + short-circuiting, + backend, + ] +sidebar_position: 3 +--- + +# Operations + +## Table of Supported Operations + +| Operation | Description | Requirements | +| :-------- | :------------------------------------------------------------: | -------------------------------------: | +| + | Adds two private input types together | Types must be private input | +| - | Subtracts two private input types together | Types must be private input | +| \* | Multiplies two private input types together | Types must be private input | +| / | Divides two private input types together | Types must be private input | +| ^ | XOR two private input types together | Types must be integer | +| & | AND two private input types together | Types must be integer | +| \| | OR two private input types together | Types must be integer | +| \<\< | Left shift an integer by another integer amount | Types must be integer, shift must be u8 | +| >> | Right shift an integer by another integer amount | Types must be integer, shift must be u8 | +| ! | Bitwise not of a value | Type must be integer or boolean | +| \< | returns a bool if one value is less than the other | Upper bound must have a known bit size | +| \<= | returns a bool if one value is less than or equal to the other | Upper bound must have a known bit size | +| > | returns a bool if one value is more than the other | Upper bound must have a known bit size | +| >= | returns a bool if one value is more than or equal to the other | Upper bound must have a known bit size | +| == | returns a bool if one value is equal to the other | Both types must not be constants | +| != | returns a bool if one value is not equal to the other | Both types must not be constants | + +### Predicate Operators + +`<,<=, !=, == , >, >=` are known as predicate/comparison operations because they compare two values. +This differs from the operations such as `+` where the operands are used in _computation_. + +### Bitwise Operations Example + +```rust +fn main(x : Field) { + let y = x as u32; + let z = y & y; +} +``` + +`z` is implicitly constrained to be the result of `y & y`. The `&` operand is used to denote bitwise +`&`. + +> `x & x` would not compile as `x` is a `Field` and not an integer type. + +### Logical Operators + +Noir has no support for the logical operators `||` and `&&`. This is because encoding the +short-circuiting that these operators require can be inefficient for Noir's backend. Instead you can +use the bitwise operators `|` and `&` which operate identically for booleans, just without the +short-circuiting. + +```rust +let my_val = 5; + +let mut flag = 1; +if (my_val > 6) | (my_val == 0) { + flag = 0; +} +assert(flag == 1); + +if (my_val != 10) & (my_val < 50) { + flag = 0; +} +assert(flag == 0); +``` + +### Shorthand operators + +Noir shorthand operators for most of the above operators, namely `+=, -=, *=, /=, %=, &=, |=, ^=, <<=`, and `>>=`. These allow for more concise syntax. For example: + +```rust +let mut i = 0; +i = i + 1; +``` + +could be written as: + +```rust +let mut i = 0; +i += 1; +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/oracles.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/oracles.mdx new file mode 100644 index 00000000000..77a2ac1550a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/oracles.mdx @@ -0,0 +1,29 @@ +--- +title: Oracles +description: Dive into how Noir supports Oracles via RPC calls, and learn how to declare an Oracle in Noir with our comprehensive guide. +keywords: + - Noir + - Oracles + - RPC Calls + - Unconstrained Functions + - Programming + - Blockchain +sidebar_position: 6 +--- + +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +Noir has support for Oracles via RPC calls. This means Noir will make an RPC call and use the return value for proof generation. + +Since Oracles are not resolved by Noir, they are [`unconstrained` functions](./unconstrained.md) + +You can declare an Oracle through the `#[oracle()]` flag. Example: + +```rust +#[oracle(get_number_sequence)] +unconstrained fn get_number_sequence(_size: Field) -> [Field] {} +``` + +The timeout for when using an external RPC oracle resolver can be set with the `NARGO_FOREIGN_CALL_TIMEOUT` environment variable. This timeout is in units of milliseconds. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/shadowing.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/shadowing.md new file mode 100644 index 00000000000..5ce6130d201 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/shadowing.md @@ -0,0 +1,44 @@ +--- +title: Shadowing +sidebar_position: 12 +--- + +Noir allows for inheriting variables' values and re-declaring them with the same name similar to Rust, known as shadowing. + +For example, the following function is valid in Noir: + +```rust +fn main() { + let x = 5; + + { + let x = x * 2; + assert (x == 10); + } + + assert (x == 5); +} +``` + +In this example, a variable x is first defined with the value 5. + +The local scope that follows shadows the original x, i.e. creates a local mutable x based on the value of the original x. It is given a value of 2 times the original x. + +When we return to the main scope, x once again refers to just the original x, which stays at the value of 5. + +## Temporal mutability + +One way that shadowing is useful, in addition to ergonomics across scopes, is for temporarily mutating variables. + +```rust +fn main() { + let age = 30; + // age = age + 5; // Would error as `age` is immutable by default. + + let mut age = age + 5; // Temporarily mutates `age` with a new value. + + let age = age; // Locks `age`'s mutability again. + + assert (age == 35); +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/traits.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/traits.md new file mode 100644 index 00000000000..9da00a77587 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/traits.md @@ -0,0 +1,501 @@ +--- +title: Traits +description: + Traits in Noir can be used to abstract out a common interface for functions across + several data types. +keywords: [noir programming language, traits, interfaces, generic, protocol] +sidebar_position: 14 +--- + +## Overview + +Traits in Noir are a useful abstraction similar to interfaces or protocols in other languages. Each trait defines +the interface of several methods contained within the trait. Types can then implement this trait by providing +implementations for these methods. For example in the program: + +```rust +struct Rectangle { + width: Field, + height: Field, +} + +impl Rectangle { + fn area(self) -> Field { + self.width * self.height + } +} + +fn log_area(r: Rectangle) { + println(r.area()); +} +``` + +We have a function `log_area` to log the area of a `Rectangle`. Now how should we change the program if we want this +function to work on `Triangle`s as well?: + +```rust +struct Triangle { + width: Field, + height: Field, +} + +impl Triangle { + fn area(self) -> Field { + self.width * self.height / 2 + } +} +``` + +Making `log_area` generic over all types `T` would be invalid since not all types have an `area` method. Instead, we can +introduce a new `Area` trait and make `log_area` generic over all types `T` that implement `Area`: + +```rust +trait Area { + fn area(self) -> Field; +} + +fn log_area(shape: T) where T: Area { + println(shape.area()); +} +``` + +We also need to explicitly implement `Area` for `Rectangle` and `Triangle`. We can do that by changing their existing +impls slightly. Note that the parameter types and return type of each of our `area` methods must match those defined +by the `Area` trait. + +```rust +impl Area for Rectangle { + fn area(self) -> Field { + self.width * self.height + } +} + +impl Area for Triangle { + fn area(self) -> Field { + self.width * self.height / 2 + } +} +``` + +Now we have a working program that is generic over any type of Shape that is used! Others can even use this program +as a library with their own types - such as `Circle` - as long as they also implement `Area` for these types. + +## Where Clauses + +As seen in `log_area` above, when we want to create a function or method that is generic over any type that implements +a trait, we can add a where clause to the generic function. + +```rust +fn log_area(shape: T) where T: Area { + println(shape.area()); +} +``` + +It is also possible to apply multiple trait constraints on the same variable at once by combining traits with the `+` +operator. Similarly, we can have multiple trait constraints by separating each with a comma: + +```rust +fn foo(elements: [T], thing: U) where + T: Default + Add + Eq, + U: Bar, +{ + let mut sum = T::default(); + + for element in elements { + sum += element; + } + + if sum == T::default() { + thing.bar(); + } +} +``` + +## Generic Implementations + +You can add generics to a trait implementation by adding the generic list after the `impl` keyword: + +```rust +trait Second { + fn second(self) -> Field; +} + +impl Second for (T, Field) { + fn second(self) -> Field { + self.1 + } +} +``` + +You can also implement a trait for every type this way: + +```rust +trait Debug { + fn debug(self); +} + +impl Debug for T { + fn debug(self) { + println(self); + } +} + +fn main() { + 1.debug(); +} +``` + +### Generic Trait Implementations With Where Clauses + +Where clauses can be placed on trait implementations themselves to restrict generics in a similar way. +For example, while `impl Foo for T` implements the trait `Foo` for every type, `impl Foo for T where T: Bar` +will implement `Foo` only for types that also implement `Bar`. This is often used for implementing generic types. +For example, here is the implementation for array equality: + +```rust +impl Eq for [T; let N: u32] where T: Eq { + // Test if two arrays have the same elements. + // Because both arrays must have length N, we know their lengths already match. + fn eq(self, other: Self) -> bool { + let mut result = true; + + for i in 0 .. self.len() { + // The T: Eq constraint is needed to call == on the array elements here + result &= self[i] == other[i]; + } + + result + } +} +``` + +Where clauses can also be placed on struct implementations. +For example, here is a method utilizing a generic type that implements the equality trait. + +```rust +struct Foo { + a: u32, + b: T, +} + +impl Foo where T: Eq { + fn eq(self, other: Self) -> bool { + (self.a == other.a) & self.b.eq(other.b) + } +} +``` + +## Generic Traits + +Traits themselves can also be generic by placing the generic arguments after the trait name. These generics are in +scope of every item within the trait. + +```rust +trait Into { + // Convert `self` to type `T` + fn into(self) -> T; +} +``` + +When implementing generic traits the generic arguments of the trait must be specified. This is also true anytime +when referencing a generic trait (e.g. in a `where` clause). + +```rust +struct MyStruct { + array: [Field; 2], +} + +impl Into<[Field; 2]> for MyStruct { + fn into(self) -> [Field; 2] { + self.array + } +} + +fn as_array(x: T) -> [Field; 2] + where T: Into<[Field; 2]> +{ + x.into() +} + +fn main() { + let array = [1, 2]; + let my_struct = MyStruct { array }; + + assert_eq(as_array(my_struct), array); +} +``` + +### Associated Types and Constants + +Traits also support associated types and constraints which can be thought of as additional generics that are referred to by name. + +Here's an example of a trait with an associated type `Foo` and a constant `Bar`: + +```rust +trait MyTrait { + type Foo; + + let Bar: u32; +} +``` + +Now when we're implementing `MyTrait` we also have to provide values for `Foo` and `Bar`: + +```rust +impl MyTrait for Field { + type Foo = i32; + + let Bar: u32 = 11; +} +``` + +Since associated constants can also be used in a type position, its values are limited to only other +expression kinds allowed in numeric generics. + +Note that currently all associated types and constants must be explicitly specified in a trait constraint. +If we leave out any, we'll get an error that we're missing one: + +```rust +// Error! Constraint is missing associated constant for `Bar` +fn foo(x: T) where T: MyTrait { + ... +} +``` + +Because all associated types and constants must be explicitly specified, they are essentially named generics, +although this is set to change in the future. Future versions of Noir will allow users to elide associated types +in trait constraints similar to Rust. When this is done, you may still refer to their value with the `::AssociatedType` +syntax: + +```rust +// Only valid in future versions of Noir: +fn foo(x: T) where T: MyTrait { + let _: ::Foo = ...; +} +``` + +The type as trait syntax is possible in Noir today but is less useful when each type must be explicitly specified anyway: + +```rust +fn foo(x: T) where T: MyTrait { + // Works, but could just use F directly + let _: >::Foo = ...; + + let _: F = ...; +} +``` + +## Trait Methods With No `self` + +A trait can contain any number of methods, each of which have access to the `Self` type which represents each type +that eventually implements the trait. Similarly, the `self` variable is available as well but is not required to be used. +For example, we can define a trait to create a default value for a type. This trait will need to return the `Self` type +but doesn't need to take any parameters: + +```rust +trait Default { + fn default() -> Self; +} +``` + +Implementing this trait can be done similarly to any other trait: + +```rust +impl Default for Field { + fn default() -> Field { + 0 + } +} + +struct MyType {} + +impl Default for MyType { + fn default() -> Field { + MyType {} + } +} +``` + +However, since there is no `self` parameter, we cannot call it via the method call syntax `object.method()`. +Instead, we'll need to refer to the function directly. This can be done either by referring to the +specific impl `MyType::default()` or referring to the trait itself `Default::default()`. In the later +case, type inference determines the impl that is selected. + +```rust +let my_struct = MyStruct::default(); + +let x: Field = Default::default(); +let result = x + Default::default(); +``` + +:::warning + +```rust +let _ = Default::default(); +``` + +If type inference cannot select which impl to use because of an ambiguous `Self` type, an impl will be +arbitrarily selected. This occurs most often when the result of a trait function call with no parameters +is unused. To avoid this, when calling a trait function with no `self` or `Self` parameters or return type, +always refer to it via the implementation type's namespace - e.g. `MyType::default()`. +This is set to change to an error in future Noir versions. + +::: + +## Default Method Implementations + +A trait can also have default implementations of its methods by giving a body to the desired functions. +Note that this body must be valid for all types that may implement the trait. As a result, the only +valid operations on `self` will be operations valid for any type or other operations on the trait itself. + +```rust +trait Numeric { + fn add(self, other: Self) -> Self; + + // Default implementation of double is (self + self) + fn double(self) -> Self { + self.add(self) + } +} +``` + +When implementing a trait with default functions, a type may choose to implement only the required functions: + +```rust +impl Numeric for Field { + fn add(self, other: Field) -> Field { + self + other + } +} +``` + +Or it may implement the optional methods as well: + +```rust +impl Numeric for u32 { + fn add(self, other: u32) -> u32 { + self + other + } + + fn double(self) -> u32 { + self * 2 + } +} +``` + +## Impl Specialization + +When implementing traits for a generic type it is possible to implement the trait for only a certain combination +of generics. This can be either as an optimization or because those specific generics are required to implement the trait. + +```rust +trait Sub { + fn sub(self, other: Self) -> Self; +} + +struct NonZero { + value: T, +} + +impl Sub for NonZero { + fn sub(self, other: Self) -> Self { + let value = self.value - other.value; + assert(value != 0); + NonZero { value } + } +} +``` + +## Overlapping Implementations + +Overlapping implementations are disallowed by Noir to ensure Noir's decision on which impl to select is never ambiguous. +This means if a trait `Foo` is already implemented +by a type `Bar` for all `T`, then we cannot also have a separate impl for `Bar` (or any other +type argument). Similarly, if there is an impl for all `T` such as `impl Debug for T`, we cannot create +any more impls to `Debug` for other types since it would be ambiguous which impl to choose for any given +method call. + +```rust +trait Trait {} + +// Previous impl defined here +impl Trait for (A, B) {} + +// error: Impl for type `(Field, Field)` overlaps with existing impl +impl Trait for (Field, Field) {} +``` + +## Trait Coherence + +Another restriction on trait implementations is coherence. This restriction ensures other crates cannot create +impls that may overlap with other impls, even if several unrelated crates are used as dependencies in the same +program. + +The coherence restriction is: to implement a trait, either the trait itself or the object type must be declared +in the crate the impl is in. + +In practice this often comes up when using types provided by libraries. If a library provides a type `Foo` that does +not implement a trait in the standard library such as `Default`, you may not `impl Default for Foo` in your own crate. +While restrictive, this prevents later issues or silent changes in the program if the `Foo` library later added its +own impl for `Default`. If you are a user of the `Foo` library in this scenario and need a trait not implemented by the +library your choices are to either submit a patch to the library or use the newtype pattern. + +### The Newtype Pattern + +The newtype pattern gets around the coherence restriction by creating a new wrapper type around the library type +that we cannot create `impl`s for. Since the new wrapper type is defined in our current crate, we can create +impls for any trait we need on it. + +```rust +struct Wrapper { + foo: some_library::Foo, +} + +impl Default for Wrapper { + fn default() -> Wrapper { + Wrapper { + foo: some_library::Foo::new(), + } + } +} +``` + +Since we have an impl for our own type, the behavior of this code will not change even if `some_library` is updated +to provide its own `impl Default for Foo`. The downside of this pattern is that it requires extra wrapping and +unwrapping of values when converting to and from the `Wrapper` and `Foo` types. + +### Trait Inheritance + +Sometimes, you might need one trait to use another trait’s functionality (like "inheritance" in some other languages). In this case, you can specify this relationship by listing any child traits after the parent trait's name and a colon. Now, whenever the parent trait is implemented it will require the child traits to be implemented as well. A parent trait is also called a "super trait." + +```rust +trait Person { + fn name(self) -> String; +} + +// Person is a supertrait of Student. +// Implementing Student requires you to also impl Person. +trait Student: Person { + fn university(self) -> String; +} + +trait Programmer { + fn fav_language(self) -> String; +} + +// CompSciStudent (computer science student) is a subtrait of both Programmer +// and Student. Implementing CompSciStudent requires you to impl both supertraits. +trait CompSciStudent: Programmer + Student { + fn git_username(self) -> String; +} +``` + +### Visibility + +By default, like functions, traits are private to the module they exist in. You can use `pub` +to make the trait public or `pub(crate)` to make it public to just its crate: + +```rust +// This trait is now public +pub trait Trait {} +``` \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/unconstrained.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/unconstrained.md new file mode 100644 index 00000000000..b5221b8d2dd --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/concepts/unconstrained.md @@ -0,0 +1,104 @@ +--- +title: Unconstrained Functions +description: "Learn about what unconstrained functions in Noir are, how to use them and when you'd want to." + +keywords: [Noir programming language, unconstrained, open] +sidebar_position: 5 +--- + +Unconstrained functions are functions which do not constrain any of the included computation and allow for non-deterministic computation. + +## Why? + +Zero-knowledge (ZK) domain-specific languages (DSL) enable developers to generate ZK proofs from their programs by compiling code down to the constraints of an NP complete language (such as R1CS or PLONKish languages). However, the hard bounds of a constraint system can be very limiting to the functionality of a ZK DSL. + +Enabling a circuit language to perform unconstrained execution is a powerful tool. Said another way, unconstrained execution lets developers generate witnesses from code that does not generate any constraints. Being able to execute logic outside of a circuit is critical for both circuit performance and constructing proofs on information that is external to a circuit. + +Fetching information from somewhere external to a circuit can also be used to enable developers to improve circuit efficiency. + +A ZK DSL does not just prove computation, but proves that some computation was handled correctly. Thus, it is necessary that when we switch from performing some operation directly inside of a circuit to inside of an unconstrained environment that the appropriate constraints are still laid down elsewhere in the circuit. + +## Example + +An in depth example might help drive the point home. This example comes from the excellent [post](https://discord.com/channels/1113924620781883405/1124022445054111926/1128747641853972590) by Tom in the Noir Discord. + +Let's look at how we can optimize a function to turn a `u72` into an array of `u8`s. + +```rust +fn main(num: u72) -> pub [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8)) as u72 & 0xff) as u8; + } + + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 91 +Backend circuit size: 3619 +``` + +A lot of the operations in this function are optimized away by the compiler (all the bit-shifts turn into divisions by constants). However we can save a bunch of gates by casting to u8 a bit earlier. This automatically truncates the bit-shifted value to fit in a u8 which allows us to remove the AND against 0xff. This saves us ~480 gates in total. + +```rust +fn main(num: u72) -> pub [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8)) as u8; + } + + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 75 +Backend circuit size: 3143 +``` + +Those are some nice savings already but we can do better. This code is all constrained so we're proving every step of calculating out using num, but we don't actually care about how we calculate this, just that it's correct. This is where brillig comes in. + +It turns out that truncating a u72 into a u8 is hard to do inside a snark, each time we do as u8 we lay down 4 ACIR opcodes which get converted into multiple gates. It's actually much easier to calculate num from out than the other way around. All we need to do is multiply each element of out by a constant and add them all together, both relatively easy operations inside a snark. + +We can then run `u72_to_u8` as unconstrained brillig code in order to calculate out, then use that result in our constrained function and assert that if we were to do the reverse calculation we'd get back num. This looks a little like the below: + +```rust +fn main(num: u72) -> pub [u8; 8] { + let out = unsafe { + u72_to_u8(num) + }; + + let mut reconstructed_num: u72 = 0; + for i in 0..8 { + reconstructed_num += (out[i] as u72 << (56 - (8 * i))); + } + assert(num == reconstructed_num); + out +} + +unconstrained fn u72_to_u8(num: u72) -> [u8; 8] { + let mut out: [u8; 8] = [0; 8]; + for i in 0..8 { + out[i] = (num >> (56 - (i * 8))) as u8; + } + out +} +``` + +``` +Total ACIR opcodes generated for language PLONKCSat { width: 3 }: 78 +Backend circuit size: 2902 +``` + +This ends up taking off another ~250 gates from our circuit! We've ended up with more ACIR opcodes than before but they're easier for the backend to prove (resulting in fewer gates). + +Note that in order to invoke unconstrained functions we need to wrap them in an `unsafe` block, +to make it clear that the call is unconstrained. + +Generally we want to use brillig whenever there's something that's easy to verify but hard to compute within the circuit. For example, if you wanted to calculate a square root of a number it'll be a much better idea to calculate this in brillig and then assert that if you square the result you get back your number. + +## Break and Continue + +In addition to loops over runtime bounds, `break` and `continue` are also available in unconstrained code. See [break and continue](../concepts/control_flow.md#break-and-continue) diff --git a/noir/noir-repo/docs/docs/getting_started/hello_noir/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/_category_.json similarity index 60% rename from noir/noir-repo/docs/docs/getting_started/hello_noir/_category_.json rename to noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/_category_.json index 976a2325de0..1debcfe7675 100644 --- a/noir/noir-repo/docs/docs/getting_started/hello_noir/_category_.json +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/_category_.json @@ -1,4 +1,5 @@ { + "label": "Modules, Packages and Crates", "position": 2, "collapsible": true, "collapsed": true diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/crates_and_packages.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/crates_and_packages.md new file mode 100644 index 00000000000..95ee9f52ab2 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/crates_and_packages.md @@ -0,0 +1,43 @@ +--- +title: Crates and Packages +description: Learn how to use Crates and Packages in your Noir project +keywords: [Nargo, dependencies, package management, crates, package] +sidebar_position: 0 +--- + +## Crates + +A crate is the smallest amount of code that the Noir compiler considers at a time. +Crates can contain modules, and the modules may be defined in other files that get compiled with the crate, as we’ll see in the coming sections. + +### Crate Types + +A Noir crate can come in several forms: binaries, libraries or contracts. + +#### Binaries + +_Binary crates_ are programs which you can compile to an ACIR circuit which you can then create proofs against. Each must have a function called `main` that defines the ACIR circuit which is to be proved. + +#### Libraries + +_Library crates_ don't have a `main` function and they don't compile down to ACIR. Instead they define functionality intended to be shared with multiple projects, and eventually included in a binary crate. + +#### Contracts + +Contract crates are similar to binary crates in that they compile to ACIR which you can create proofs against. They are different in that they do not have a single `main` function, but are a collection of functions to be deployed to the [Aztec network](https://aztec.network). You can learn more about the technical details of Aztec in the [monorepo](https://github.com/AztecProtocol/aztec-packages) or contract [examples](https://github.com/AztecProtocol/aztec-packages/tree/master/noir-projects/noir-contracts/contracts). + +### Crate Root + +Every crate has a root, which is the source file that the compiler starts, this is also known as the root module. The Noir compiler does not enforce any conditions on the name of the file which is the crate root, however if you are compiling via Nargo the crate root must be called `lib.nr` or `main.nr` for library or binary crates respectively. + +## Packages + +A Nargo _package_ is a collection of one of more crates that provides a set of functionality. A package must include a Nargo.toml file. + +A package _must_ contain either a library or a binary crate, but not both. + +### Differences from Cargo Packages + +One notable difference between Rust's Cargo and Noir's Nargo is that while Cargo allows a package to contain an unlimited number of binary crates and a single library crate, Nargo currently only allows a package to contain a single crate. + +In future this restriction may be lifted to allow a Nargo package to contain both a binary and library crate or multiple binary crates. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/dependencies.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/dependencies.md new file mode 100644 index 00000000000..24e02de08fe --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/dependencies.md @@ -0,0 +1,124 @@ +--- +title: Dependencies +description: + Learn how to specify and manage dependencies in Nargo, allowing you to upload packages to GitHub + and use them easily in your project. +keywords: [Nargo, dependencies, GitHub, package management, versioning] +sidebar_position: 1 +--- + +Nargo allows you to upload packages to GitHub and use them as dependencies. + +## Specifying a dependency + +Specifying a dependency requires a tag to a specific commit and the git url to the url containing +the package. + +Currently, there are no requirements on the tag contents. If requirements are added, it would follow +semver 2.0 guidelines. + +> Note: Without a `tag` , there would be no versioning and dependencies would change each time you +> compile your project. + +For example, to add the [ecrecover-noir library](https://github.com/colinnielsen/ecrecover-noir) to your project, add it to `Nargo.toml`: + +```toml +# Nargo.toml + +[dependencies] +ecrecover = {tag = "v0.8.0", git = "https://github.com/colinnielsen/ecrecover-noir"} +``` + +If the module is in a subdirectory, you can define a subdirectory in your git repository, for example: + +```toml +# Nargo.toml + +[dependencies] +easy_private_token_contract = {tag ="v0.1.0-alpha62", git = "https://github.com/AztecProtocol/aztec-packages", directory = "noir-contracts/contracts/easy_private_token_contract"} +``` + +## Specifying a local dependency + +You can also specify dependencies that are local to your machine. + +For example, this file structure has a library and binary crate + +```tree +├── binary_crate +│   ├── Nargo.toml +│   └── src +│   └── main.nr +└── lib_a + ├── Nargo.toml + └── src + └── lib.nr +``` + +Inside of the binary crate, you can specify: + +```toml +# Nargo.toml + +[dependencies] +lib_a = { path = "../lib_a" } +``` + +## Importing dependencies + +You can import a dependency to a Noir file using the following syntax. For example, to import the +ecrecover-noir library and local lib_a referenced above: + +```rust +use ecrecover; +use lib_a; +``` + +You can also import only the specific parts of dependency that you want to use, like so: + +```rust +use std::hash::sha256; +use std::scalar_mul::fixed_base_embedded_curve; +``` + +Lastly, as demonstrated in the +[elliptic curve example](../standard_library/cryptographic_primitives/ec_primitives.md#examples), you +can import multiple items in the same line by enclosing them in curly braces: + +```rust +use std::ec::tecurve::affine::{Curve, Point}; +``` + +We don't have a way to consume libraries from inside a [workspace](./workspaces.md) as external dependencies right now. + +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. + +## Dependencies of Dependencies + +Note that when you import a dependency, you also get access to all of the dependencies of that package. + +For example, the [phy_vector](https://github.com/resurgencelabs/phy_vector) library imports an [fraction](https://github.com/resurgencelabs/fraction) library. If you're importing the phy_vector library, then you can access the functions in fractions library like so: + +```rust +use phy_vector; + +fn main(x : Field, y : pub Field) { + //... + let f = phy_vector::fraction::toFraction(true, 2, 1); + //... +} +``` + +## Available Libraries + +Noir does not currently have an official package manager. You can find a list of available Noir libraries in the [awesome-noir repo here](https://github.com/noir-lang/awesome-noir#libraries). + +Some libraries that are available today include: + +- [Standard Library](https://github.com/noir-lang/noir/tree/master/noir_stdlib) - the Noir Standard Library +- [Ethereum Storage Proof Verification](https://github.com/aragonzkresearch/noir-trie-proofs) - a library that contains the primitives necessary for RLP decoding (in the form of look-up table construction) and Ethereum state and storage proof verification (or verification of any trie proof involving 32-byte long keys) +- [BigInt](https://github.com/shuklaayush/noir-bigint) - a library that provides a custom BigUint56 data type, allowing for computations on large unsigned integers +- [ECrecover](https://github.com/colinnielsen/ecrecover-noir/tree/main) - a library to verify an ECDSA signature and return the source Ethereum address +- [Sparse Merkle Tree Verifier](https://github.com/vocdoni/smtverifier-noir/tree/main) - a library for verification of sparse Merkle trees +- [Signed Int](https://github.com/resurgencelabs/signed_int) - a library for accessing a custom Signed Integer data type, allowing access to negative numbers on Noir +- [Fraction](https://github.com/resurgencelabs/fraction) - a library for accessing fractional number data type in Noir, allowing results that aren't whole numbers diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/modules.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/modules.md new file mode 100644 index 00000000000..14aa1f0579a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/modules.md @@ -0,0 +1,221 @@ +--- +title: Modules +description: + Learn how to organize your files using modules in Noir, following the same convention as Rust's + module system. Examples included. +keywords: [Noir, Rust, modules, organizing files, sub-modules] +sidebar_position: 2 +--- + +Noir's module system follows the same convention as the _newer_ version of Rust's module system. + +## Purpose of Modules + +Modules are used to organize files. Without modules all of your code would need to live in a single +file. In Noir, the compiler does not automatically scan all of your files to detect modules. This +must be done explicitly by the developer. + +## Examples + +### Importing a module in the crate root + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::hello_world(); +} +``` + +Filename : `src/foo.nr` + +```rust +fn from_foo() {} +``` + +In the above snippet, the crate root is the `src/main.nr` file. The compiler sees the module +declaration `mod foo` which prompts it to look for a foo.nr file. + +Visually this module hierarchy looks like the following : + +``` +crate + ├── main + │ + └── foo + └── from_foo + +``` + +The module filename may also be the name of the module as a directory with the contents in a +file named `mod.nr` within that directory. The above example can alternatively be expressed like this: + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::hello_world(); +} +``` + +Filename : `src/foo/mod.nr` + +```rust +fn from_foo() {} +``` + +Note that it's an error to have both files `src/foo.nr` and `src/foo/mod.nr` in the filesystem. + +### Importing a module throughout the tree + +All modules are accessible from the `crate::` namespace. + +``` +crate + ├── bar + ├── foo + └── main + +``` + +In the above snippet, if `bar` would like to use functions in `foo`, it can do so by `use crate::foo::function_name`. + +### Sub-modules + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::from_foo(); +} +``` + +Filename : `src/foo.nr` + +```rust +mod bar; +fn from_foo() {} +``` + +Filename : `src/foo/bar.nr` + +```rust +fn from_bar() {} +``` + +In the above snippet, we have added an extra module to the module tree; `bar`. `bar` is a submodule +of `foo` hence we declare bar in `foo.nr` with `mod bar`. Since `foo` is not the crate root, the +compiler looks for the file associated with the `bar` module in `src/foo/bar.nr` + +Visually the module hierarchy looks as follows: + +``` +crate + ├── main + │ + └── foo + ├── from_foo + └── bar + └── from_bar +``` + +Similar to importing a module in the crate root, modules can be placed in a `mod.nr` file, like this: + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::from_foo(); +} +``` + +Filename : `src/foo/mod.nr` + +```rust +mod bar; +fn from_foo() {} +``` + +Filename : `src/foo/bar/mod.nr` + +```rust +fn from_bar() {} +``` + +### Referencing a parent module + +Given a submodule, you can refer to its parent module using the `super` keyword. + +Filename : `src/main.nr` + +```rust +mod foo; + +fn main() { + foo::from_foo(); +} +``` + +Filename : `src/foo.nr` + +```rust +mod bar; + +fn from_foo() {} +``` + +Filename : `src/foo/bar.nr` + +```rust +// Same as bar::from_foo +use super::from_foo; + +fn from_bar() { + from_foo(); // invokes super::from_foo(), which is bar::from_foo() + super::from_foo(); // also invokes bar::from_foo() +} +``` + +### `use` visibility + +`use` declarations are private to the containing module, by default. However, like functions, +they can be marked as `pub` or `pub(crate)`. Such a use declaration serves to _re-export_ a name. +A public `use` declaration can therefore redirect some public name to a different target definition: +even a definition with a private canonical path, inside a different module. + +An example of re-exporting: + +```rust +mod some_module { + pub use foo::{bar, baz}; + mod foo { + pub fn bar() {} + pub fn baz() {} + } +} + +fn main() { + some_module::bar(); + some_module::baz(); +} +``` + +In this example, the module `some_module` re-exports two public names defined in `foo`. + +### Visibility + +By default, like functions, modules are private to the module (or crate) they exist in. You can use `pub` +to make the module public or `pub(crate)` to make it public to just its crate: + +```rust +// This module is now public and can be seen by other crates. +pub mod foo; +``` \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/workspaces.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/workspaces.md new file mode 100644 index 00000000000..513497f12bf --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/modules_packages_crates/workspaces.md @@ -0,0 +1,42 @@ +--- +title: Workspaces +sidebar_position: 3 +--- + +Workspaces are a feature of nargo that allow you to manage multiple related Noir packages in a single repository. A workspace is essentially a group of related projects that share common build output directories and configurations. + +Each Noir project (with it's own Nargo.toml file) can be thought of as a package. Each package is expected to contain exactly one "named circuit", being the "name" defined in Nargo.toml with the program logic defined in `./src/main.nr`. + +For a project with the following structure: + +```tree +├── crates +│ ├── a +│ │ ├── Nargo.toml +│ │ └── Prover.toml +│ │ └── src +│ │ └── main.nr +│ └── b +│ ├── Nargo.toml +│ └── Prover.toml +│ └── src +│ └── main.nr +│ +└── Nargo.toml +``` + +You can define a workspace in Nargo.toml like so: + +```toml +[workspace] +members = ["crates/a", "crates/b"] +default-member = "crates/a" +``` + +`members` indicates which packages are included in the workspace. As such, all member packages of a workspace will be processed when the `--workspace` flag is used with various commands or if a `default-member` is not specified. + +`default-member` indicates which package various commands process by default. + +Libraries can be defined in a workspace. Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. + +Inside a workspace, these are consumed as `{ path = "../to_lib" }` dependencies in Nargo.toml. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bigint.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bigint.md new file mode 100644 index 00000000000..05c3011634f --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bigint.md @@ -0,0 +1,127 @@ +--- +title: Big Integers +description: How to use big integers from Noir standard library +keywords: + [ + Big Integer, + Noir programming language, + Noir libraries, + ] +--- + +The BigInt module in the standard library exposes some class of integers which do not fit (well) into a Noir native field. It implements modulo arithmetic, modulo a 'big' prime number. + +:::note + +The module can currently be considered as `Field`s with fixed modulo sizes used by a set of elliptic curves, in addition to just the native curve. [More work](https://github.com/noir-lang/noir/issues/510) is needed to achieve arbitrarily sized big integers. + +:::note + +`nargo` can be built with `--profile release-pedantic` to enable extra overflow checks which may affect `BigInt` results in some cases. +Consider the [`noir-bignum`](https://github.com/noir-lang/noir-bignum) library for an optimized alternative approach. + +::: + +Currently 6 classes of integers (i.e 'big' prime numbers) are available in the module, namely: + +- BN254 Fq: Bn254Fq +- BN254 Fr: Bn254Fr +- Secp256k1 Fq: Secpk1Fq +- Secp256k1 Fr: Secpk1Fr +- Secp256r1 Fr: Secpr1Fr +- Secp256r1 Fq: Secpr1Fq + +Where XXX Fq and XXX Fr denote respectively the order of the base and scalar field of the (usual) elliptic curve XXX. +For instance the big integer 'Secpk1Fq' in the standard library refers to integers modulo $2^{256}-2^{32}-977$. + +Feel free to explore the source code for the other primes: + +```rust title="big_int_definition" showLineNumbers +pub struct BigInt { + pointer: u32, + modulus: u32, +} +``` +> Source code: noir_stdlib/src/bigint.nr#L28-L33 + + +## Example usage + +A common use-case is when constructing a big integer from its bytes representation, and performing arithmetic operations on it: + +```rust title="big_int_example" showLineNumbers +fn big_int_example(x: u8, y: u8) { + let a = Secpk1Fq::from_le_bytes(&[x, y, 0, 45, 2]); + let b = Secpk1Fq::from_le_bytes(&[y, x, 9]); + let c = (a + b) * b / a; + let d = c.to_le_bytes(); + println(d[0]); +} +``` +> Source code: test_programs/execution_success/bigint/src/main.nr#L74-L82 + + +## Methods + +The available operations for each big integer are: + +### from_le_bytes + +Construct a big integer from its little-endian bytes representation. Example: + +```rust + // Construct a big integer from a slice of bytes + let a = Secpk1Fq::from_le_bytes(&[x, y, 0, 45, 2]); + // Construct a big integer from an array of 32 bytes + let a = Secpk1Fq::from_le_bytes_32([1;32]); + ``` + +Sure, here's the formatted version of the remaining methods: + +### to_le_bytes + +Return the little-endian bytes representation of a big integer. Example: + +```rust +let bytes = a.to_le_bytes(); +``` + +### add + +Add two big integers. Example: + +```rust +let sum = a + b; +``` + +### sub + +Subtract two big integers. Example: + +```rust +let difference = a - b; +``` + +### mul + +Multiply two big integers. Example: + +```rust +let product = a * b; +``` + +### div + +Divide two big integers. Note that division is field division and not euclidean division. Example: + +```rust +let quotient = a / b; +``` + +### eq + +Compare two big integers. Example: + +```rust +let are_equal = a == b; +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/black_box_fns.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/black_box_fns.md new file mode 100644 index 00000000000..d6079ab182c --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/black_box_fns.md @@ -0,0 +1,32 @@ +--- +title: Black Box Functions +description: Black box functions are functions in Noir that rely on backends implementing support for specialized constraints. +keywords: [noir, black box functions] +--- + +Black box functions are functions in Noir that rely on backends implementing support for specialized constraints. This makes certain zk-snark unfriendly computations cheaper than if they were implemented in Noir. + +The ACVM spec defines a set of blackbox functions which backends will be expected to implement. This allows backends to use optimized implementations of these constraints if they have them, however they may also fallback to less efficient naive implementations if not. + +## Function list + +Here is a list of the current black box functions: + +- [AES128](./cryptographic_primitives/ciphers.mdx#aes128) +- [SHA256](./cryptographic_primitives/hashes.mdx#sha256) +- [Schnorr signature verification](./cryptographic_primitives/schnorr.mdx) +- [Blake2s](./cryptographic_primitives/hashes.mdx#blake2s) +- [Blake3](./cryptographic_primitives/hashes.mdx#blake3) +- [Pedersen Hash](./cryptographic_primitives/hashes.mdx#pedersen_hash) +- [Pedersen Commitment](./cryptographic_primitives/hashes.mdx#pedersen_commitment) +- [ECDSA signature verification](./cryptographic_primitives/ecdsa_sig_verification.mdx) +- [Embedded curve operations (MSM, addition, ...)](./cryptographic_primitives/embedded_curve_ops.mdx) +- AND +- XOR +- RANGE +- [Keccak256](./cryptographic_primitives/hashes.mdx#keccak256) +- [Recursive proof verification](./recursion.mdx) + +Most black box functions are included as part of the Noir standard library, however `AND`, `XOR` and `RANGE` are used as part of the Noir language syntax. For instance, using the bitwise operator `&` will invoke the `AND` black box function. + +You can view the black box functions defined in the ACVM code [here](https://github.com/noir-lang/noir/blob/master/acvm-repo/acir/src/circuit/black_box_functions.rs). diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bn254.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bn254.md new file mode 100644 index 00000000000..3294f005dbb --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/bn254.md @@ -0,0 +1,46 @@ +--- +title: Bn254 Field Library +--- + +Noir provides a module in standard library with some optimized functions for bn254 Fr in `std::field::bn254`. + +## decompose + +```rust +fn decompose(x: Field) -> (Field, Field) {} +``` + +Decomposes a single field into two fields, low and high. The low field contains the lower 16 bytes of the input field and the high field contains the upper 16 bytes of the input field. Both field results are range checked to 128 bits. + + +## assert_gt + +```rust +fn assert_gt(a: Field, b: Field) {} +``` + +Asserts that a > b. This will generate less constraints than using `assert(gt(a, b))`. + +## assert_lt + +```rust +fn assert_lt(a: Field, b: Field) {} +``` + +Asserts that a < b. This will generate less constraints than using `assert(lt(a, b))`. + +## gt + +```rust +fn gt(a: Field, b: Field) -> bool {} +``` + +Returns true if a > b. + +## lt + +```rust +fn lt(a: Field, b: Field) -> bool {} +``` + +Returns true if a < b. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/boundedvec.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/boundedvec.md new file mode 100644 index 00000000000..509b214bf3a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/boundedvec.md @@ -0,0 +1,419 @@ +--- +title: Bounded Vectors +keywords: [noir, vector, bounded vector, slice] +sidebar_position: 1 +--- + +A `BoundedVec` is a growable storage similar to a `Vec` except that it +is bounded with a maximum possible length. Unlike `Vec`, `BoundedVec` is not implemented +via slices and thus is not subject to the same restrictions slices are (notably, nested +slices - and thus nested vectors as well - are disallowed). + +Since a BoundedVec is backed by a normal array under the hood, growing the BoundedVec by +pushing an additional element is also more efficient - the length only needs to be increased +by one. + +For these reasons `BoundedVec` should generally be preferred over `Vec` when there +is a reasonable maximum bound that can be placed on the vector. + +Example: + +```rust +let mut vector: BoundedVec = BoundedVec::new(); +for i in 0..5 { + vector.push(i); +} +assert(vector.len() == 5); +assert(vector.max_len() == 10); +``` + +## Methods + +### new + +```rust +pub fn new() -> Self +``` + +Creates a new, empty vector of length zero. + +Since this container is backed by an array internally, it still needs an initial value +to give each element. To resolve this, each element is zeroed internally. This value +is guaranteed to be inaccessible unless `get_unchecked` is used. + +Example: + +```rust +let empty_vector: BoundedVec = BoundedVec::new(); +assert(empty_vector.len() == 0); +``` + +Note that whenever calling `new` the maximum length of the vector should always be specified +via a type signature: + +```rust title="new_example" showLineNumbers +fn good() -> BoundedVec { + // Ok! MaxLen is specified with a type annotation + let v1: BoundedVec = BoundedVec::new(); + let v2 = BoundedVec::new(); + + // Ok! MaxLen is known from the type of `good`'s return value + v2 +} + +fn bad() { + // Error: Type annotation needed + // The compiler can't infer `MaxLen` from this code. + let mut v3 = BoundedVec::new(); + v3.push(5); +} +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L11-L27 + + +This defaulting of `MaxLen` (and numeric generics in general) to zero may change in future noir versions +but for now make sure to use type annotations when using bounded vectors. Otherwise, you will receive a constraint failure at runtime when the vec is pushed to. + +### get + +```rust +pub fn get(self, index: u64) -> T { +``` + +Retrieves an element from the vector at the given index, starting from zero. + +If the given index is equal to or greater than the length of the vector, this +will issue a constraint failure. + +Example: + +```rust +fn foo(v: BoundedVec) { + let first = v.get(0); + let last = v.get(v.len() - 1); + assert(first != last); +} +``` + +### get_unchecked + +```rust +pub fn get_unchecked(self, index: u64) -> T { +``` + +Retrieves an element from the vector at the given index, starting from zero, without +performing a bounds check. + +Since this function does not perform a bounds check on length before accessing the element, +it is unsafe! Use at your own risk! + +Example: + +```rust title="get_unchecked_example" showLineNumbers +fn sum_of_first_three(v: BoundedVec) -> u32 { + // Always ensure the length is larger than the largest + // index passed to get_unchecked + assert(v.len() > 2); + let first = v.get_unchecked(0); + let second = v.get_unchecked(1); + let third = v.get_unchecked(2); + first + second + third +} +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L54-L64 + + +### set + +```rust +pub fn set(&mut self: Self, index: u64, value: T) { +``` + +Writes an element to the vector at the given index, starting from zero. + +If the given index is equal to or greater than the length of the vector, this will issue a constraint failure. + +Example: + +```rust +fn foo(v: BoundedVec) { + let first = v.get(0); + assert(first != 42); + v.set(0, 42); + let new_first = v.get(0); + assert(new_first == 42); +} +``` + +### set_unchecked + +```rust +pub fn set_unchecked(&mut self: Self, index: u64, value: T) -> T { +``` + +Writes an element to the vector at the given index, starting from zero, without performing a bounds check. + +Since this function does not perform a bounds check on length before accessing the element, it is unsafe! Use at your own risk! + +Example: + +```rust title="set_unchecked_example" showLineNumbers +fn set_unchecked_example() { + let mut vec: BoundedVec = BoundedVec::new(); + vec.extend_from_array([1, 2]); + + // Here we're safely writing within the valid range of `vec` + // `vec` now has the value [42, 2] + vec.set_unchecked(0, 42); + + // We can then safely read this value back out of `vec`. + // Notice that we use the checked version of `get` which would prevent reading unsafe values. + assert_eq(vec.get(0), 42); + + // We've now written past the end of `vec`. + // As this index is still within the maximum potential length of `v`, + // it won't cause a constraint failure. + vec.set_unchecked(2, 42); + println(vec); + + // This will write past the end of the maximum potential length of `vec`, + // it will then trigger a constraint failure. + vec.set_unchecked(5, 42); + println(vec); +} +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L67-L91 + + + +### push + +```rust +pub fn push(&mut self, elem: T) { +``` + +Pushes an element to the end of the vector. This increases the length +of the vector by one. + +Panics if the new length of the vector will be greater than the max length. + +Example: + +```rust title="bounded-vec-push-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + + v.push(1); + v.push(2); + + // Panics with failed assertion "push out of bounds" + v.push(3); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L95-L103 + + +### pop + +```rust +pub fn pop(&mut self) -> T +``` + +Pops the element at the end of the vector. This will decrease the length +of the vector by one. + +Panics if the vector is empty. + +Example: + +```rust title="bounded-vec-pop-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + v.push(1); + v.push(2); + + let two = v.pop(); + let one = v.pop(); + + assert(two == 2); + assert(one == 1); + // error: cannot pop from an empty vector + // let _ = v.pop(); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L108-L120 + + +### len + +```rust +pub fn len(self) -> u64 { +``` + +Returns the current length of this vector + +Example: + +```rust title="bounded-vec-len-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + assert(v.len() == 0); + + v.push(100); + assert(v.len() == 1); + + v.push(200); + v.push(300); + v.push(400); + assert(v.len() == 4); + + let _ = v.pop(); + let _ = v.pop(); + assert(v.len() == 2); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L125-L140 + + +### max_len + +```rust +pub fn max_len(_self: BoundedVec) -> u64 { +``` + +Returns the maximum length of this vector. This is always +equal to the `MaxLen` parameter this vector was initialized with. + +Example: + +```rust title="bounded-vec-max-len-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + + assert(v.max_len() == 5); + v.push(10); + assert(v.max_len() == 5); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L145-L151 + + +### storage + +```rust +pub fn storage(self) -> [T; MaxLen] { +``` + +Returns the internal array within this vector. +Since arrays in Noir are immutable, mutating the returned storage array will not mutate +the storage held internally by this vector. + +Note that uninitialized elements may be zeroed out! + +Example: + +```rust title="bounded-vec-storage-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + + assert(v.storage() == [0, 0, 0, 0, 0]); + + v.push(57); + assert(v.storage() == [57, 0, 0, 0, 0]); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L156-L163 + + +### extend_from_array + +```rust +pub fn extend_from_array(&mut self, array: [T; Len]) +``` + +Pushes each element from the given array to this vector. + +Panics if pushing each element would cause the length of this vector +to exceed the maximum length. + +Example: + +```rust title="bounded-vec-extend-from-array-example" showLineNumbers +let mut vec: BoundedVec = BoundedVec::new(); + vec.extend_from_array([2, 4]); + + assert(vec.len == 2); + assert(vec.get(0) == 2); + assert(vec.get(1) == 4); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L168-L175 + + +### extend_from_bounded_vec + +```rust +pub fn extend_from_bounded_vec(&mut self, vec: BoundedVec) +``` + +Pushes each element from the other vector to this vector. The length of +the other vector is left unchanged. + +Panics if pushing each element would cause the length of this vector +to exceed the maximum length. + +Example: + +```rust title="bounded-vec-extend-from-bounded-vec-example" showLineNumbers +let mut v1: BoundedVec = BoundedVec::new(); + let mut v2: BoundedVec = BoundedVec::new(); + + v2.extend_from_array([1, 2, 3]); + v1.extend_from_bounded_vec(v2); + + assert(v1.storage() == [1, 2, 3, 0, 0]); + assert(v2.storage() == [1, 2, 3, 0, 0, 0, 0]); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L180-L189 + + +### from_array + +```rust +pub fn from_array(array: [T; Len]) -> Self +``` + +Creates a new vector, populating it with values derived from an array input. +The maximum length of the vector is determined based on the type signature. + +Example: +```rust +let bounded_vec: BoundedVec = BoundedVec::from_array([1, 2, 3]) +``` + +### map + +```rust +pub fn map(self, f: fn[Env](T) -> U) -> BoundedVec +``` + +Creates a new vector of equal size by calling a closure on each element in this vector. + +Example: + +```rust title="bounded-vec-map-example" showLineNumbers +let vec: BoundedVec = BoundedVec::from_array([1, 2, 3, 4]); + let result = vec.map(|value| value * 2); +``` +> Source code: noir_stdlib/src/collections/bounded_vec.nr#L495-L498 + + +### any + +```rust +pub fn any(self, predicate: fn[Env](T) -> bool) -> bool +``` + +Returns true if the given predicate returns true for any element +in this vector. + +Example: + +```rust title="bounded-vec-any-example" showLineNumbers +let mut v: BoundedVec = BoundedVec::new(); + v.extend_from_array([2, 4, 6]); + + let all_even = !v.any(|elem: u32| elem % 2 != 0); + assert(all_even); +``` +> Source code: test_programs/noir_test_success/bounded_vec/src/main.nr#L256-L262 + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/hashmap.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/hashmap.md new file mode 100644 index 00000000000..395cc312705 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/hashmap.md @@ -0,0 +1,587 @@ +--- +title: HashMap +keywords: [noir, map, hash, hashmap] +sidebar_position: 1 +--- + +`HashMap` is used to efficiently store and look up key-value pairs. + +`HashMap` is a bounded type which can store anywhere from zero to `MaxLen` total elements. +Note that due to hash collisions, the actual maximum number of elements stored by any particular +hashmap is likely lower than `MaxLen`. This is true even with cryptographic hash functions since +every hash value will be performed modulo `MaxLen`. + +Example: + +```rust +// Create a mapping from Fields to u32s with a maximum length of 12 +// using a poseidon2 hasher +use std::hash::poseidon2::Poseidon2Hasher; +let mut map: HashMap> = HashMap::default(); + +map.insert(1, 2); +map.insert(3, 4); + +let two = map.get(1).unwrap(); +``` + +## Methods + +### default + +```rust title="default" showLineNumbers +impl Default for HashMap +where + B: BuildHasher + Default, + H: Hasher + Default, +{ + /// Constructs an empty HashMap. + /// + /// Example: + /// + /// ```noir + /// let hashmap: HashMap> = HashMap::default(); + /// assert(hashmap.is_empty()); + /// ``` + fn default() -> Self { +``` +> Source code: noir_stdlib/src/collections/map.nr#L681-L696 + + +Creates a fresh, empty HashMap. + +When using this function, always make sure to specify the maximum size of the hash map. + +This is the same `default` from the `Default` implementation given further below. It is +repeated here for convenience since it is the recommended way to create a hashmap. + +Example: + +```rust title="default_example" showLineNumbers +let hashmap: HashMap> = HashMap::default(); + assert(hashmap.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L207-L210 + + +Because `HashMap` has so many generic arguments that are likely to be the same throughout +your program, it may be helpful to create a type alias: + +```rust title="type_alias" showLineNumbers +type MyMap = HashMap>; +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L201-L203 + + +### with_hasher + +```rust title="with_hasher" showLineNumbers +pub fn with_hasher(_build_hasher: B) -> Self + where + B: BuildHasher, + { +``` +> Source code: noir_stdlib/src/collections/map.nr#L103-L108 + + +Creates a hashmap with an existing `BuildHasher`. This can be used to ensure multiple +hashmaps are created with the same hasher instance. + +Example: + +```rust title="with_hasher_example" showLineNumbers +let my_hasher: BuildHasherDefault = Default::default(); + let hashmap: HashMap> = + HashMap::with_hasher(my_hasher); + assert(hashmap.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L211-L216 + + +### get + +```rust title="get" showLineNumbers +pub fn get(self, key: K) -> Option + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher, + { +``` +> Source code: noir_stdlib/src/collections/map.nr#L465-L472 + + +Retrieves a value from the hashmap, returning `Option::none()` if it was not found. + +Example: + +```rust title="get_example" showLineNumbers +fn get_example(map: HashMap>) { + let x = map.get(12); + + if x.is_some() { + assert(x.unwrap() == 42); + } +} +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L296-L304 + + +### insert + +```rust title="insert" showLineNumbers +pub fn insert(&mut self, key: K, value: V) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher, + { +``` +> Source code: noir_stdlib/src/collections/map.nr#L507-L514 + + +Inserts a new key-value pair into the map. If the key was already in the map, its +previous value will be overridden with the newly provided one. + +Example: + +```rust title="insert_example" showLineNumbers +let mut map: HashMap> = HashMap::default(); + map.insert(12, 42); + assert(map.len() == 1); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L217-L221 + + +### remove + +```rust title="remove" showLineNumbers +pub fn remove(&mut self, key: K) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher, + { +``` +> Source code: noir_stdlib/src/collections/map.nr#L563-L570 + + +Removes the given key-value pair from the map. If the key was not already present +in the map, this does nothing. + +Example: + +```rust title="remove_example" showLineNumbers +map.remove(12); + assert(map.is_empty()); + + // If a key was not present in the map, remove does nothing + map.remove(12); + assert(map.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L224-L231 + + +### is_empty + +```rust title="is_empty" showLineNumbers +pub fn is_empty(self) -> bool { +``` +> Source code: noir_stdlib/src/collections/map.nr#L167-L169 + + +True if the length of the hash map is empty. + +Example: + +```rust title="is_empty_example" showLineNumbers +assert(map.is_empty()); + + map.insert(1, 2); + assert(!map.is_empty()); + + map.remove(1); + assert(map.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L232-L240 + + +### len + +```rust title="len" showLineNumbers +pub fn len(self) -> u32 { +``` +> Source code: noir_stdlib/src/collections/map.nr#L424-L426 + + +Returns the current length of this hash map. + +Example: + +```rust title="len_example" showLineNumbers +// This is equivalent to checking map.is_empty() + assert(map.len() == 0); + + map.insert(1, 2); + map.insert(3, 4); + map.insert(5, 6); + assert(map.len() == 3); + + // 3 was already present as a key in the hash map, so the length is unchanged + map.insert(3, 7); + assert(map.len() == 3); + + map.remove(1); + assert(map.len() == 2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L241-L256 + + +### capacity + +```rust title="capacity" showLineNumbers +pub fn capacity(_self: Self) -> u32 { +``` +> Source code: noir_stdlib/src/collections/map.nr#L446-L448 + + +Returns the maximum capacity of this hashmap. This is always equal to the capacity +specified in the hashmap's type. + +Unlike hashmaps in general purpose programming languages, hashmaps in Noir have a +static capacity that does not increase as the map grows larger. Thus, this capacity +is also the maximum possible element count that can be inserted into the hashmap. +Due to hash collisions (modulo the hashmap length), it is likely the actual maximum +element count will be lower than the full capacity. + +Example: + +```rust title="capacity_example" showLineNumbers +let empty_map: HashMap> = + HashMap::default(); + assert(empty_map.len() == 0); + assert(empty_map.capacity() == 42); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L257-L262 + + +### clear + +```rust title="clear" showLineNumbers +pub fn clear(&mut self) { +``` +> Source code: noir_stdlib/src/collections/map.nr#L123-L125 + + +Clears the hashmap, removing all key-value pairs from it. + +Example: + +```rust title="clear_example" showLineNumbers +assert(!map.is_empty()); + map.clear(); + assert(map.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L263-L267 + + +### contains_key + +```rust title="contains_key" showLineNumbers +pub fn contains_key(self, key: K) -> bool + where + K: Hash + Eq, + B: BuildHasher, + H: Hasher, + { +``` +> Source code: noir_stdlib/src/collections/map.nr#L143-L150 + + +True if the hashmap contains the given key. Unlike `get`, this will not also return +the value associated with the key. + +Example: + +```rust title="contains_key_example" showLineNumbers +if map.contains_key(7) { + let value = map.get(7); + assert(value.is_some()); + } else { + println("No value for key 7!"); + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L268-L275 + + +### entries + +```rust title="entries" showLineNumbers +pub fn entries(self) -> BoundedVec<(K, V), N> { +``` +> Source code: noir_stdlib/src/collections/map.nr#L191-L193 + + +Returns a vector of each key-value pair present in the hashmap. + +The length of the returned vector is always equal to the length of the hashmap. + +Example: + +```rust title="entries_example" showLineNumbers +let entries = map.entries(); + + // The length of a hashmap may not be compile-time known, so we + // need to loop over its capacity instead + for i in 0..map.capacity() { + if i < entries.len() { + let (key, value) = entries.get(i); + println(f"{key} -> {value}"); + } + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L307-L318 + + +### keys + +```rust title="keys" showLineNumbers +pub fn keys(self) -> BoundedVec { +``` +> Source code: noir_stdlib/src/collections/map.nr#L227-L229 + + +Returns a vector of each key present in the hashmap. + +The length of the returned vector is always equal to the length of the hashmap. + +Example: + +```rust title="keys_example" showLineNumbers +let keys = map.keys(); + + for i in 0..keys.max_len() { + if i < keys.len() { + let key = keys.get_unchecked(i); + let value = map.get(key).unwrap_unchecked(); + println(f"{key} -> {value}"); + } + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L319-L329 + + +### values + +```rust title="values" showLineNumbers +pub fn values(self) -> BoundedVec { +``` +> Source code: noir_stdlib/src/collections/map.nr#L262-L264 + + +Returns a vector of each value present in the hashmap. + +The length of the returned vector is always equal to the length of the hashmap. + +Example: + +```rust title="values_example" showLineNumbers +let values = map.values(); + + for i in 0..values.max_len() { + if i < values.len() { + let value = values.get_unchecked(i); + println(f"Found value {value}"); + } + } +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L330-L339 + + +### iter_mut + +```rust title="iter_mut" showLineNumbers +pub fn iter_mut(&mut self, f: fn(K, V) -> (K, V)) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher, + { +``` +> Source code: noir_stdlib/src/collections/map.nr#L297-L304 + + +Iterates through each key-value pair of the HashMap, setting each key-value pair to the +result returned from the given function. + +Note that since keys can be mutated, the HashMap needs to be rebuilt as it is iterated +through. If this is not desired, use `iter_values_mut` if only values need to be mutated, +or `entries` if neither keys nor values need to be mutated. + +The iteration order is left unspecified. As a result, if two keys are mutated to become +equal, which of the two values that will be present for the key in the resulting map is also unspecified. + +Example: + +```rust title="iter_mut_example" showLineNumbers +// Add 1 to each key in the map, and double the value associated with that key. + map.iter_mut(|k, v| (k + 1, v * 2)); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L343-L346 + + +### iter_keys_mut + +```rust title="iter_keys_mut" showLineNumbers +pub fn iter_keys_mut(&mut self, f: fn(K) -> K) + where + K: Eq + Hash, + B: BuildHasher, + H: Hasher, + { +``` +> Source code: noir_stdlib/src/collections/map.nr#L335-L342 + + +Iterates through the HashMap, mutating each key to the result returned from +the given function. + +Note that since keys can be mutated, the HashMap needs to be rebuilt as it is iterated +through. If only iteration is desired and the keys are not intended to be mutated, +prefer using `entries` instead. + +The iteration order is left unspecified. As a result, if two keys are mutated to become +equal, which of the two values that will be present for the key in the resulting map is also unspecified. + +Example: + +```rust title="iter_keys_mut_example" showLineNumbers +// Double each key, leaving the value associated with that key untouched + map.iter_keys_mut(|k| k * 2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L347-L350 + + +### iter_values_mut + +```rust title="iter_values_mut" showLineNumbers +pub fn iter_values_mut(&mut self, f: fn(V) -> V) { +``` +> Source code: noir_stdlib/src/collections/map.nr#L367-L369 + + +Iterates through the HashMap, applying the given function to each value and mutating the +value to equal the result. This function is more efficient than `iter_mut` and `iter_keys_mut` +because the keys are untouched and the underlying hashmap thus does not need to be reordered. + +Example: + +```rust title="iter_values_mut_example" showLineNumbers +// Halve each value + map.iter_values_mut(|v| v / 2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L351-L354 + + +### retain + +```rust title="retain" showLineNumbers +pub fn retain(&mut self, f: fn(K, V) -> bool) { +``` +> Source code: noir_stdlib/src/collections/map.nr#L388-L390 + + +Retains only the key-value pairs for which the given function returns true. +Any key-value pairs for which the function returns false will be removed from the map. + +Example: + +```rust title="retain_example" showLineNumbers +map.retain(|k, v| (k != 0) & (v != 0)); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L279-L281 + + +## Trait Implementations + +### default + +```rust title="default" showLineNumbers +impl Default for HashMap +where + B: BuildHasher + Default, + H: Hasher + Default, +{ + /// Constructs an empty HashMap. + /// + /// Example: + /// + /// ```noir + /// let hashmap: HashMap> = HashMap::default(); + /// assert(hashmap.is_empty()); + /// ``` + fn default() -> Self { +``` +> Source code: noir_stdlib/src/collections/map.nr#L681-L696 + + +Constructs an empty HashMap. + +Example: + +```rust title="default_example" showLineNumbers +let hashmap: HashMap> = HashMap::default(); + assert(hashmap.is_empty()); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L207-L210 + + +### eq + +```rust title="eq" showLineNumbers +impl Eq for HashMap +where + K: Eq + Hash, + V: Eq, + B: BuildHasher, + H: Hasher, +{ + /// Checks if two HashMaps are equal. + /// + /// Example: + /// + /// ```noir + /// let mut map1: HashMap> = HashMap::default(); + /// let mut map2: HashMap> = HashMap::default(); + /// + /// map1.insert(1, 2); + /// map1.insert(3, 4); + /// + /// map2.insert(3, 4); + /// map2.insert(1, 2); + /// + /// assert(map1 == map2); + /// ``` + fn eq(self, other: HashMap) -> bool { +``` +> Source code: noir_stdlib/src/collections/map.nr#L629-L654 + + +Checks if two HashMaps are equal. + +Example: + +```rust title="eq_example" showLineNumbers +let mut map1: HashMap> = HashMap::default(); + let mut map2: HashMap> = HashMap::default(); + + map1.insert(1, 2); + map1.insert(3, 4); + + map2.insert(3, 4); + map2.insert(1, 2); + + assert(map1 == map2); +``` +> Source code: test_programs/execution_success/hashmap/src/main.nr#L282-L293 + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/index.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/index.md new file mode 100644 index 00000000000..ea84c6d5c21 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/index.md @@ -0,0 +1,5 @@ +--- +title: Containers +description: Container types provided by Noir's standard library for storing and retrieving data +keywords: [containers, data types, vec, hashmap] +--- diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/vec.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/vec.mdx new file mode 100644 index 00000000000..475011922f8 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/containers/vec.mdx @@ -0,0 +1,170 @@ +--- +title: Vectors +description: Delve into the Vec data type in Noir. Learn about its methods, practical examples, and best practices for using Vectors in your Noir code. +keywords: [noir, vector type, methods, examples, dynamic arrays] +sidebar_position: 6 +--- + +import Experimental from '@site/src/components/Notes/_experimental.mdx'; + + + +A vector is a collection type similar to Rust's `Vec` type. In Noir, it is a convenient way to use slices as mutable arrays. + +Example: + +```rust +let mut vector: Vec = Vec::new(); +for i in 0..5 { + vector.push(i); +} +assert(vector.len() == 5); +``` + +## Methods + +### new + +Creates a new, empty vector. + +```rust +pub fn new() -> Self +``` + +Example: + +```rust +let empty_vector: Vec = Vec::new(); +assert(empty_vector.len() == 0); +``` + +### from_slice + +Creates a vector containing each element from a given slice. Mutations to the resulting vector will not affect the original slice. + +```rust +pub fn from_slice(slice: [T]) -> Self +``` + +Example: + +```rust +let slice: [Field] = &[1, 2, 3]; +let vector_from_slice = Vec::from_slice(slice); +assert(vector_from_slice.len() == 3); +``` + +### len + +Returns the number of elements in the vector. + +```rust +pub fn len(self) -> Field +``` + +Example: + +```rust +let empty_vector: Vec = Vec::new(); +assert(empty_vector.len() == 0); +``` + +### get + +Retrieves an element from the vector at a given index. Panics if the index points beyond the vector's end. + +```rust +pub fn get(self, index: Field) -> T +``` + +Example: + +```rust +let vector: Vec = Vec::from_slice(&[10, 20, 30]); +assert(vector.get(1) == 20); +``` + +### set + +```rust +pub fn set(&mut self: Self, index: u64, value: T) { +``` + +Writes an element to the vector at the given index, starting from zero. + +Panics if the index points beyond the vector's end. + +Example: + +```rust +let vector: Vec = Vec::from_slice(&[10, 20, 30]); +assert(vector.get(1) == 20); +vector.set(1, 42); +assert(vector.get(1) == 42); +``` + +### push + +Adds a new element to the vector's end, returning a new vector with a length one greater than the original unmodified vector. + +```rust +pub fn push(&mut self, elem: T) +``` + +Example: + +```rust +let mut vector: Vec = Vec::new(); +vector.push(10); +assert(vector.len() == 1); +``` + +### pop + +Removes an element from the vector's end, returning a new vector with a length one less than the original vector, along with the removed element. Panics if the vector's length is zero. + +```rust +pub fn pop(&mut self) -> T +``` + +Example: + +```rust +let mut vector = Vec::from_slice(&[10, 20]); +let popped_elem = vector.pop(); +assert(popped_elem == 20); +assert(vector.len() == 1); +``` + +### insert + +Inserts an element at a specified index, shifting subsequent elements to the right. + +```rust +pub fn insert(&mut self, index: Field, elem: T) +``` + +Example: + +```rust +let mut vector = Vec::from_slice(&[10, 30]); +vector.insert(1, 20); +assert(vector.get(1) == 20); +``` + +### remove + +Removes an element at a specified index, shifting subsequent elements to the left, and returns the removed element. + +```rust +pub fn remove(&mut self, index: Field) -> T +``` + +Example: + +```rust +let mut vector = Vec::from_slice(&[10, 20, 30]); +let removed_elem = vector.remove(1); +assert(removed_elem == 20); +assert(vector.len() == 2); +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ciphers.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ciphers.mdx new file mode 100644 index 00000000000..d6a5e1a79eb --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ciphers.mdx @@ -0,0 +1,32 @@ +--- +title: Ciphers +description: + Learn about the implemented ciphers ready to use for any Noir project +keywords: + [ciphers, Noir project, aes128, encrypt] +sidebar_position: 0 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; + +## aes128 + +Given a plaintext as an array of bytes, returns the corresponding aes128 ciphertext (CBC mode). Input padding is automatically performed using PKCS#7, so that the output length is `input.len() + (16 - input.len() % 16)`. + +```rust title="aes128" showLineNumbers +pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8] {} +``` +> Source code: noir_stdlib/src/aes128.nr#L2-L4 + + +```rust +fn main() { + let input: [u8; 4] = [0, 12, 3, 15] // Random bytes, will be padded to 16 bytes. + let iv: [u8; 16] = [0; 16]; // Initialisation vector + let key: [u8; 16] = [0; 16] // AES key + let ciphertext = std::aes128::aes128_encrypt(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()); // In this case, the output length will be 16 bytes. +} +``` + + + \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ec_primitives.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ec_primitives.md new file mode 100644 index 00000000000..f262d8160d6 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ec_primitives.md @@ -0,0 +1,102 @@ +--- +title: Elliptic Curve Primitives +keywords: [cryptographic primitives, Noir project] +sidebar_position: 4 +--- + +Data structures and methods on them that allow you to carry out computations involving elliptic +curves over the (mathematical) field corresponding to `Field`. For the field currently at our +disposal, applications would involve a curve embedded in BN254, e.g. the +[Baby Jubjub curve](https://eips.ethereum.org/EIPS/eip-2494). + +## Data structures + +### Elliptic curve configurations + +(`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::Curve`), i.e. the specific elliptic +curve you want to use, which would be specified using any one of the methods +`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::new` which take the coefficients in the +defining equation together with a generator point as parameters. You can find more detail in the +comments in +[`noir_stdlib/src/ec/mod.nr`](https://github.com/noir-lang/noir/blob/master/noir_stdlib/src/ec/mod.nr), but +the gist of it is that the elliptic curves of interest are usually expressed in one of the standard +forms implemented here (Twisted Edwards, Montgomery and Short Weierstraß), and in addition to that, +you could choose to use `affine` coordinates (Cartesian coordinates - the usual (x,y) - possibly +together with a point at infinity) or `curvegroup` coordinates (some form of projective coordinates +requiring more coordinates but allowing for more efficient implementations of elliptic curve +operations). Conversions between all of these forms are provided, and under the hood these +conversions are done whenever an operation is more efficient in a different representation (or a +mixed coordinate representation is employed). + +### Points + +(`std::ec::{tecurve,montcurve,swcurve}::{affine,curvegroup}::Point`), i.e. points lying on the +elliptic curve. For a curve configuration `c` and a point `p`, it may be checked that `p` +does indeed lie on `c` by calling `c.contains(p1)`. + +## Methods + +(given a choice of curve representation, e.g. use `std::ec::tecurve::affine::Curve` and use +`std::ec::tecurve::affine::Point`) + +- The **zero element** is given by `Point::zero()`, and we can verify whether a point `p: Point` is + zero by calling `p.is_zero()`. +- **Equality**: Points `p1: Point` and `p2: Point` may be checked for equality by calling + `p1.eq(p2)`. +- **Addition**: For `c: Curve` and points `p1: Point` and `p2: Point` on the curve, adding these two + points is accomplished by calling `c.add(p1,p2)`. +- **Negation**: For a point `p: Point`, `p.negate()` is its negation. +- **Subtraction**: For `c` and `p1`, `p2` as above, subtracting `p2` from `p1` is accomplished by + calling `c.subtract(p1,p2)`. +- **Scalar multiplication**: For `c` as above, `p: Point` a point on the curve and `n: Field`, + scalar multiplication is given by `c.mul(n,p)`. If instead `n :: [u1; N]`, i.e. `n` is a bit + array, the `bit_mul` method may be used instead: `c.bit_mul(n,p)` +- **Multi-scalar multiplication**: For `c` as above and arrays `n: [Field; N]` and `p: [Point; N]`, + multi-scalar multiplication is given by `c.msm(n,p)`. +- **Coordinate representation conversions**: The `into_group` method converts a point or curve + configuration in the affine representation to one in the CurveGroup representation, and + `into_affine` goes in the other direction. +- **Curve representation conversions**: `tecurve` and `montcurve` curves and points are equivalent + and may be converted between one another by calling `into_montcurve` or `into_tecurve` on their + configurations or points. `swcurve` is more general and a curve c of one of the other two types + may be converted to this representation by calling `c.into_swcurve()`, whereas a point `p` lying + on the curve given by `c` may be mapped to its corresponding `swcurve` point by calling + `c.map_into_swcurve(p)`. +- **Map-to-curve methods**: The Elligator 2 method of mapping a field element `n: Field` into a + `tecurve` or `montcurve` with configuration `c` may be called as `c.elligator2_map(n)`. For all of + the curve configurations, the SWU map-to-curve method may be called as `c.swu_map(z,n)`, where + `z: Field` depends on `Field` and `c` and must be chosen by the user (the conditions it needs to + satisfy are specified in the comments + [here](https://github.com/noir-lang/noir/blob/master/noir_stdlib/src/ec/mod.nr)). + +## Examples + +The +[ec_baby_jubjub test](https://github.com/noir-lang/noir/blob/master/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr) +illustrates all of the above primitives on various forms of the Baby Jubjub curve. A couple of more +interesting examples in Noir would be: + +Public-key cryptography: Given an elliptic curve and a 'base point' on it, determine the public key +from the private key. This is a matter of using scalar multiplication. In the case of Baby Jubjub, +for example, this code would do: + +```rust +use std::ec::tecurve::affine::{Curve, Point}; + +fn bjj_pub_key(priv_key: Field) -> Point +{ + + let bjj = Curve::new(168700, 168696, G::new(995203441582195749578291179787384436505546430278305826713579947235728471134,5472060717959818805561601436314318772137091100104008585924551046643952123905)); + + let base_pt = Point::new(5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203); + + bjj.mul(priv_key,base_pt) +} +``` + +This would come in handy in a Merkle proof. + +- EdDSA signature verification: This is a matter of combining these primitives with a suitable hash + function. See + [feat(stdlib): EdDSA sig verification noir#1136](https://github.com/noir-lang/noir/pull/1136) for + the case of Baby Jubjub and the Poseidon hash function. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx new file mode 100644 index 00000000000..8d96027b42c --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/ecdsa_sig_verification.mdx @@ -0,0 +1,98 @@ +--- +title: ECDSA Signature Verification +description: Learn about the cryptographic primitives regarding ECDSA over the secp256k1 and secp256r1 curves +keywords: [cryptographic primitives, Noir project, ecdsa, secp256k1, secp256r1, signatures] +sidebar_position: 3 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; + +Noir supports ECDSA signatures verification over the secp256k1 and secp256r1 curves. + +## ecdsa_secp256k1::verify_signature + +Verifier for ECDSA Secp256k1 signatures. +See ecdsa_secp256k1::verify_signature_slice for a version that accepts slices directly. + +```rust title="ecdsa_secp256k1" showLineNumbers +pub fn verify_signature( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8; N], +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256k1.nr#L2-L9 + + +example: + +```rust +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + let valid_signature = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} +``` + + + +## ecdsa_secp256k1::verify_signature_slice + +Verifier for ECDSA Secp256k1 signatures where the message is a slice. + +```rust title="ecdsa_secp256k1_slice" showLineNumbers +pub fn verify_signature_slice( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8], +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256k1.nr#L13-L20 + + + + +## ecdsa_secp256r1::verify_signature + +Verifier for ECDSA Secp256r1 signatures. +See ecdsa_secp256r1::verify_signature_slice for a version that accepts slices directly. + +```rust title="ecdsa_secp256r1" showLineNumbers +pub fn verify_signature( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8; N], +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256r1.nr#L2-L9 + + +example: + +```rust +fn main(hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(valid_signature); +} +``` + + + +## ecdsa_secp256r1::verify_signature + +Verifier for ECDSA Secp256r1 signatures where the message is a slice. + +```rust title="ecdsa_secp256r1_slice" showLineNumbers +pub fn verify_signature_slice( + public_key_x: [u8; 32], + public_key_y: [u8; 32], + signature: [u8; 64], + message_hash: [u8], +) -> bool +``` +> Source code: noir_stdlib/src/ecdsa_secp256r1.nr#L13-L20 + + + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/eddsa.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/eddsa.mdx new file mode 100644 index 00000000000..b283de693c8 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/eddsa.mdx @@ -0,0 +1,37 @@ +--- +title: EdDSA Verification +description: Learn about the cryptographic primitives regarding EdDSA +keywords: [cryptographic primitives, Noir project, eddsa, signatures] +sidebar_position: 5 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; + +## eddsa::eddsa_poseidon_verify + +Verifier for EdDSA signatures + +```rust +fn eddsa_poseidon_verify(public_key_x : Field, public_key_y : Field, signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, message: Field) -> bool +``` + +It is also possible to specify the hash algorithm used for the signature by using the `eddsa_verify` function by passing a type implementing the Hasher trait with the turbofish operator. +For instance, if you want to use Poseidon2 instead, you can do the following: +```rust +use std::hash::poseidon2::Poseidon2Hasher; + +eddsa_verify::(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg); +``` + + + +## eddsa::eddsa_to_pub + +Private to public key conversion. + +Returns `(pub_key_x, pub_key_y)` + +```rust +fn eddsa_to_pub(secret : Field) -> (Field, Field) +``` + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx new file mode 100644 index 00000000000..4b5bba7802e --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/embedded_curve_ops.mdx @@ -0,0 +1,95 @@ +--- +title: Scalar multiplication +description: See how you can perform scalar multiplication in Noir +keywords: [cryptographic primitives, Noir project, scalar multiplication] +sidebar_position: 1 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; + +The following functions perform operations over the embedded curve whose coordinates are defined by the configured noir field. +For the BN254 scalar field, this is BabyJubJub or Grumpkin. + +:::note +Suffixes `_low` and `_high` denote low and high limbs of a scalar. +::: + +## embedded_curve_ops::multi_scalar_mul + +Performs multi scalar multiplication over the embedded curve. +The function accepts arbitrary amount of point-scalar pairs on the input, it multiplies the individual pairs over +the curve and returns a sum of the resulting points. + +Points represented as x and y coordinates [x1, y1, x2, y2, ...], scalars as low and high limbs [low1, high1, low2, high2, ...]. + +```rust title="multi_scalar_mul" showLineNumbers +pub fn multi_scalar_mul( + points: [EmbeddedCurvePoint; N], + scalars: [EmbeddedCurveScalar; N], +) -> EmbeddedCurvePoint +``` +> Source code: noir_stdlib/src/embedded_curve_ops.nr#L103-L108 + + +example + +```rust +fn main(point_x: Field, point_y: Field, scalar_low: Field, scalar_high: Field) { + let point = std::embedded_curve_ops::multi_scalar_mul([point_x, point_y], [scalar_low, scalar_high]); + println(point); +} +``` + +## embedded_curve_ops::fixed_base_scalar_mul + +Performs fixed base scalar multiplication over the embedded curve (multiplies input scalar with a generator point). +The function accepts a single scalar on the input represented as 2 fields. + +```rust title="fixed_base_scalar_mul" showLineNumbers +pub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint +``` +> Source code: noir_stdlib/src/embedded_curve_ops.nr#L126-L128 + + +example + +```rust +fn main(scalar_low: Field, scalar_high: Field) { + let point = std::embedded_curve_ops::fixed_base_scalar_mul(scalar_low, scalar_high); + println(point); +} +``` + +## embedded_curve_ops::embedded_curve_add + +Adds two points on the embedded curve. +This function takes two `EmbeddedCurvePoint` structures as parameters, representing points on the curve, and returns a new `EmbeddedCurvePoint` structure that represents their sum. + +### Parameters: +- `point1` (`EmbeddedCurvePoint`): The first point to add. +- `point2` (`EmbeddedCurvePoint`): The second point to add. + +### Returns: +- `EmbeddedCurvePoint`: The resulting point after the addition of `point1` and `point2`. + +```rust title="embedded_curve_add" showLineNumbers +pub fn embedded_curve_add( + point1: EmbeddedCurvePoint, + point2: EmbeddedCurvePoint, +) -> EmbeddedCurvePoint { +``` +> Source code: noir_stdlib/src/embedded_curve_ops.nr#L142-L147 + + +example + +```rust +fn main() { + let point1 = EmbeddedCurvePoint { x: 1, y: 2 }; + let point2 = EmbeddedCurvePoint { x: 3, y: 4 }; + let result = std::embedded_curve_ops::embedded_curve_add(point1, point2); + println!("Resulting Point: ({}, {})", result.x, result.y); +} +``` + + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/hashes.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/hashes.mdx new file mode 100644 index 00000000000..7cb95779586 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/hashes.mdx @@ -0,0 +1,253 @@ +--- +title: Hash methods +description: + Learn about the cryptographic primitives ready to use for any Noir project, including sha256, + blake2s, pedersen, mimc_bn254 and mimc +keywords: + [cryptographic primitives, Noir project, sha256, blake2s, pedersen, mimc_bn254, mimc, hash] +sidebar_position: 0 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; + +## sha256 + +Given an array of bytes, returns the resulting sha256 hash. +Specify a message_size to hash only the first `message_size` bytes of the input. + +```rust title="sha256" showLineNumbers +pub fn sha256(input: [u8; N]) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash/sha256.nr#L7-L9 + + +example: +```rust title="sha256_var" showLineNumbers +let digest = std::hash::sha256_var([x as u8], 1); +``` +> Source code: test_programs/execution_success/sha256/src/main.nr#L15-L17 + + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::sha256::sha256_var(x, 4); +} +``` + + + + +## blake2s + +Given an array of bytes, returns an array with the Blake2 hash + +```rust title="blake2s" showLineNumbers +pub fn blake2s(input: [u8; N]) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash/mod.nr#L20-L22 + + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::blake2s(x); +} +``` + + + +## blake3 + +Given an array of bytes, returns an array with the Blake3 hash + +```rust title="blake3" showLineNumbers +pub fn blake3(input: [u8; N]) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash/mod.nr#L26-L28 + + +example: + +```rust +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::blake3(x); +} +``` + + + +## pedersen_hash + +Given an array of Fields, returns the Pedersen hash. + +```rust title="pedersen_hash" showLineNumbers +pub fn pedersen_hash(input: [Field; N]) -> Field +``` +> Source code: noir_stdlib/src/hash/mod.nr#L51-L53 + + +example: + +```rust title="pedersen-hash" showLineNumbers +fn main(x: Field, y: Field, expected_hash: Field) { + let hash = std::hash::pedersen_hash([x, y]); + assert_eq(hash, expected_hash); +} +``` +> Source code: test_programs/execution_success/pedersen_hash/src/main.nr#L1-L6 + + + + +## pedersen_commitment + +Given an array of Fields, returns the Pedersen commitment. + +```rust title="pedersen_commitment" showLineNumbers +pub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint { +``` +> Source code: noir_stdlib/src/hash/mod.nr#L31-L33 + + +example: + +```rust title="pedersen-commitment" showLineNumbers +fn main(x: Field, y: Field, expected_commitment: std::embedded_curve_ops::EmbeddedCurvePoint) { + let commitment = std::hash::pedersen_commitment([x, y]); + assert_eq(commitment.x, expected_commitment.x); + assert_eq(commitment.y, expected_commitment.y); +} +``` +> Source code: test_programs/execution_success/pedersen_commitment/src/main.nr#L1-L7 + + + + +## keccak256 + +Given an array of bytes (`u8`), returns the resulting keccak hash as an array of +32 bytes (`[u8; 32]`). Specify a message_size to hash only the first +`message_size` bytes of the input. + +```rust title="keccak256" showLineNumbers +pub fn keccak256(input: [u8; N], message_size: u32) -> [u8; 32] +``` +> Source code: noir_stdlib/src/hash/mod.nr#L117-L119 + + +example: + +```rust title="keccak256" showLineNumbers +fn main(x: Field, result: [u8; 32]) { + // We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field + // The padding is taken care of by the program + let digest = std::hash::keccak256([x as u8], 1); + assert(digest == result); + + //#1399: variable message size + let message_size = 4; + let hash_a = std::hash::keccak256([1, 2, 3, 4], message_size); + let hash_b = std::hash::keccak256([1, 2, 3, 4, 0, 0, 0, 0], message_size); + + assert(hash_a == hash_b); + + let message_size_big = 8; + let hash_c = std::hash::keccak256([1, 2, 3, 4, 0, 0, 0, 0], message_size_big); + + assert(hash_a != hash_c); +} +``` +> Source code: test_programs/execution_success/keccak256/src/main.nr#L1-L20 + + + + +## poseidon + +Given an array of Fields, returns a new Field with the Poseidon Hash. Mind that you need to specify +how many inputs are there to your Poseidon function. + +```rust +// example for hash_1, hash_2 accepts an array of length 2, etc +fn hash_1(input: [Field; 1]) -> Field +``` + +example: + +```rust title="poseidon" showLineNumbers +use std::hash::poseidon; + +fn main(x1: [Field; 2], y1: pub Field, x2: [Field; 4], y2: pub Field) { + let hash1 = poseidon::bn254::hash_2(x1); + assert(hash1 == y1); + + let hash2 = poseidon::bn254::hash_4(x2); + assert(hash2 == y2); +} +``` +> Source code: test_programs/execution_success/poseidon_bn254_hash/src/main.nr#L1-L11 + + +## poseidon 2 + +Given an array of Fields, returns a new Field with the Poseidon2 Hash. Contrary to the Poseidon +function, there is only one hash and you can specify a message_size to hash only the first +`message_size` bytes of the input, + +```rust +// example for hashing the first three elements of the input +Poseidon2::hash(input, 3); +``` + +example: + +```rust title="poseidon2" showLineNumbers +use std::hash::poseidon2; + +fn main(inputs: [Field; 4], expected_hash: Field) { + let hash = poseidon2::Poseidon2::hash(inputs, inputs.len()); + assert_eq(hash, expected_hash); +} +``` +> Source code: test_programs/execution_success/poseidon2/src/main.nr#L1-L8 + + +## mimc_bn254 and mimc + +`mimc_bn254` is `mimc`, but with hardcoded parameters for the BN254 curve. You can use it by +providing an array of Fields, and it returns a Field with the hash. You can use the `mimc` method if +you're willing to input your own constants: + +```rust +fn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field +``` + +otherwise, use the `mimc_bn254` method: + +```rust +fn mimc_bn254(array: [Field; N]) -> Field +``` + +example: + +```rust + +fn main() { + let x = [163, 117, 178, 149]; // some random bytes + let hash = std::hash::mimc::mimc_bn254(x); +} +``` + +## hash_to_field + +```rust +fn hash_to_field(_input : [Field]) -> Field {} +``` + +Calculates the `blake2s` hash of the inputs and returns the hash modulo the field modulus to return +a value which can be represented as a `Field`. + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/index.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/index.md new file mode 100644 index 00000000000..650f30165d5 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/index.md @@ -0,0 +1,14 @@ +--- +title: Cryptographic Primitives +description: + Learn about the cryptographic primitives ready to use for any Noir project +keywords: + [ + cryptographic primitives, + Noir project, + ] +--- + +The Noir team is progressively adding new cryptographic primitives to the standard library. Reach out for news or if you would be interested in adding more of these calculations in Noir. + +Some methods are available thanks to the Aztec backend, not being performed using Noir. When using other backends, these methods may or may not be supplied. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/schnorr.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/schnorr.mdx new file mode 100644 index 00000000000..030452645c5 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/cryptographic_primitives/schnorr.mdx @@ -0,0 +1,64 @@ +--- +title: Schnorr Signatures +description: Learn how you can verify Schnorr signatures using Noir +keywords: [cryptographic primitives, Noir project, schnorr, signatures] +sidebar_position: 2 +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; + +## schnorr::verify_signature + +Verifier for Schnorr signatures over the embedded curve (for BN254 it is Grumpkin). +See schnorr::verify_signature_slice for a version that works directly on slices. + +```rust title="schnorr_verify" showLineNumbers +pub fn verify_signature( + public_key_x: Field, + public_key_y: Field, + signature: [u8; 64], + message: [u8; N], +) -> bool +``` +> Source code: noir_stdlib/src/schnorr.nr#L4-L11 + + +where `_signature` can be generated like so using the npm package +[@noir-lang/barretenberg](https://www.npmjs.com/package/@noir-lang/barretenberg) + +```js +const { BarretenbergWasm } = require('@noir-lang/barretenberg/dest/wasm'); +const { Schnorr } = require('@noir-lang/barretenberg/dest/crypto/schnorr'); + +... + +const barretenberg = await BarretenbergWasm.new(); +const schnorr = new Schnorr(barretenberg); +const pubKey = schnorr.computePublicKey(privateKey); +const message = ... +const signature = Array.from( + schnorr.constructSignature(hash, privateKey).toBuffer() +); + +... +``` + + + +## schnorr::verify_signature_slice + +Verifier for Schnorr signatures over the embedded curve (for BN254 it is Grumpkin) +where the message is a slice. + +```rust title="schnorr_verify_slice" showLineNumbers +pub fn verify_signature_slice( + public_key_x: Field, + public_key_y: Field, + signature: [u8; 64], + message: [u8], +) -> bool +``` +> Source code: noir_stdlib/src/schnorr.nr#L15-L22 + + + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/fmtstr.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/fmtstr.md new file mode 100644 index 00000000000..19809d60261 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/fmtstr.md @@ -0,0 +1,17 @@ +--- +title: fmtstr +--- + +`fmtstr` is the type resulting from using format string (`f"..."`). + +## Methods + +### quoted_contents + +```rust title="quoted_contents" showLineNumbers +pub comptime fn quoted_contents(self) -> Quoted {} +``` +> Source code: noir_stdlib/src/meta/format_string.nr#L3-L5 + + +Returns the format string contents (that is, without the leading and trailing double quotes) as a `Quoted` value. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/is_unconstrained.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/is_unconstrained.md new file mode 100644 index 00000000000..51bb1bda8f1 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/is_unconstrained.md @@ -0,0 +1,69 @@ +--- +title: Is Unconstrained Function +description: + The is_unconstrained function returns wether the context at that point of the program is unconstrained or not. +keywords: + [ + unconstrained + ] +--- + +It's very common for functions in circuits to take unconstrained hints of an expensive computation and then verify it. This is done by running the hint in an unconstrained context and then verifying the result in a constrained context. + +When a function is marked as unconstrained, any subsequent functions that it calls will also be run in an unconstrained context. However, if we are implementing a library function, other users might call it within an unconstrained context or a constrained one. Generally, in an unconstrained context we prefer just computing the result instead of taking a hint of it and verifying it, since that'd mean doing the same computation twice: + +```rust + +fn my_expensive_computation(){ + ... +} + +unconstrained fn my_expensive_computation_hint(){ + my_expensive_computation() +} + +pub fn external_interface(){ + my_expensive_computation_hint(); + // verify my_expensive_computation: If external_interface is called from unconstrained, this is redundant + ... +} + +``` + +In order to improve the performance in an unconstrained context you can use the function at `std::runtime::is_unconstrained() -> bool`: + + +```rust +use dep::std::runtime::is_unconstrained; + +fn my_expensive_computation(){ + ... +} + +unconstrained fn my_expensive_computation_hint(){ + my_expensive_computation() +} + +pub fn external_interface(){ + if is_unconstrained() { + my_expensive_computation(); + } else { + my_expensive_computation_hint(); + // verify my_expensive_computation + ... + } +} + +``` + +The is_unconstrained result is resolved at compile time, so in unconstrained contexts the compiler removes the else branch, and in constrained contexts the compiler removes the if branch, reducing the amount of compute necessary to run external_interface. + +Note that using `is_unconstrained` in a `comptime` context will also return `true`: + +``` +fn main() { + comptime { + assert(is_unconstrained()); + } +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/logging.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/logging.md new file mode 100644 index 00000000000..db75ef9f86f --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/logging.md @@ -0,0 +1,78 @@ +--- +title: Logging +description: + Learn how to use the println statement for debugging in Noir with this tutorial. Understand the + basics of logging in Noir and how to implement it in your code. +keywords: + [ + noir logging, + println statement, + print statement, + debugging in noir, + noir std library, + logging tutorial, + basic logging in noir, + noir logging implementation, + noir debugging techniques, + rust, + ] +--- + +The standard library provides two familiar statements you can use: `println` and `print`. Despite being a limited implementation of rust's `println!` and `print!` macros, these constructs can be useful for debugging. + +You can print the output of both statements in your Noir code by using the `nargo execute` command or the `--show-output` flag when using `nargo test` (provided there are print statements in your tests). + +It is recommended to use `nargo execute` if you want to debug failing constraints with `println` or `print` statements. This is due to every input in a test being a constant rather than a witness, so we issue an error during compilation while we only print during execution (which comes after compilation). Neither `println`, nor `print` are callable for failed constraints caught at compile time. + +Both `print` and `println` are generic functions which can work on integers, fields, strings, and even structs or expressions. Note however, that slices are currently unsupported. For example: + +```rust +struct Person { + age: Field, + height: Field, +} + +fn main(age: Field, height: Field) { + let person = Person { + age: age, + height: height, + }; + println(person); + println(age + height); + println("Hello world!"); +} +``` + +You can print different types in the same statement (including strings) with a type called `fmtstr`. It can be specified in the same way as a normal string, just prepended with an "f" character: + +```rust + let fmt_str = f"i: {i}, j: {j}"; + println(fmt_str); + + let s = myStruct { y: x, x: y }; + println(s); + + println(f"i: {i}, s: {s}"); + + println(x); + println([x, y]); + + let foo = fooStruct { my_struct: s, foo: 15 }; + println(f"s: {s}, foo: {foo}"); + + println(15); // prints 0x0f, implicit Field + println(-1 as u8); // prints 255 + println(-1 as i8); // prints -1 +``` + +Examples shown above are interchangeable between the two `print` statements: + +```rust +let person = Person { age : age, height : height }; + +println(person); +print(person); + +println("Hello world!"); // Prints with a newline at the end of the input +print("Hello world!"); // Prints the input and keeps cursor on the same line +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/mem.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/mem.md new file mode 100644 index 00000000000..95d36ac2a72 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/mem.md @@ -0,0 +1,52 @@ +--- +title: Memory Module +description: + This module contains functions which manipulate memory in a low-level way +keywords: + [ + mem, memory, zeroed, transmute, checked_transmute + ] +--- + +# `std::mem::zeroed` + +```rust +fn zeroed() -> T +``` + +Returns a zeroed value of any type. +This function is generally unsafe to use as the zeroed bit pattern is not guaranteed to be valid for all types. +It can however, be useful in cases when the value is guaranteed not to be used such as in a BoundedVec library implementing a growable vector, up to a certain length, backed by an array. +The array can be initialized with zeroed values which are guaranteed to be inaccessible until the vector is pushed to. +Similarly, enumerations in noir can be implemented using this method by providing zeroed values for the unused variants. + +This function currently supports the following types: + +- Field +- Bool +- Uint +- Array +- Slice +- String +- Tuple +- Functions + +Using it on other types could result in unexpected behavior. + +# `std::mem::checked_transmute` + +```rust +fn checked_transmute(value: T) -> U +``` + +Transmutes a value of one type into the same value but with a new type `U`. + +This function is safe to use since both types are asserted to be equal later during compilation after the concrete values for generic types become known. +This function is useful for cases where the compiler may fails a type check that is expected to pass where +a user knows the two types to be equal. For example, when using arithmetic generics there are cases the compiler +does not see as equal, such as `[Field; N*(A + B)]` and `[Field; N*A + N*B]`, which users may know to be equal. +In these cases, `checked_transmute` can be used to cast the value to the desired type while also preserving safety +by checking this equality once `N`, `A`, `B` are fully resolved. + +Note that since this safety check is performed after type checking rather than during, no error is issued if the function +containing `checked_transmute` is never called. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/merkle_trees.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/merkle_trees.md new file mode 100644 index 00000000000..6a9ebf72ada --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/merkle_trees.md @@ -0,0 +1,58 @@ +--- +title: Merkle Trees +description: Learn about Merkle Trees in Noir with this tutorial. Explore the basics of computing a merkle root using a proof, with examples. +keywords: + [ + Merkle trees in Noir, + Noir programming language, + check membership, + computing root from leaf, + Noir Merkle tree implementation, + Merkle tree tutorial, + Merkle tree code examples, + Noir libraries, + pedersen hash., + ] +--- + +## compute_merkle_root + +Returns the root of the tree from the provided leaf and its hash path, using a [Pedersen hash](./cryptographic_primitives/hashes.mdx#pedersen_hash). + +```rust +fn compute_merkle_root(leaf : Field, index : Field, hash_path: [Field]) -> Field +``` + +example: + +```rust +/** + // these values are for this example only + index = "0" + priv_key = "0x000000000000000000000000000000000000000000000000000000616c696365" + secret = "0x1929ea3ab8d9106a899386883d9428f8256cfedb3c4f6b66bf4aa4d28a79988f" + note_hash_path = [ + "0x1e61bdae0f027b1b2159e1f9d3f8d00fa668a952dddd822fda80dc745d6f65cc", + "0x0e4223f3925f98934393c74975142bd73079ab0621f4ee133cee050a3c194f1a", + "0x2fd7bb412155bf8693a3bd2a3e7581a679c95c68a052f835dddca85fa1569a40" + ] + */ +fn main(index: Field, priv_key: Field, secret: Field, note_hash_path: [Field; 3]) { + + let pubkey = std::scalar_mul::fixed_base_embedded_curve(priv_key); + let pubkey_x = pubkey[0]; + let pubkey_y = pubkey[1]; + let note_commitment = std::hash::pedersen(&[pubkey_x, pubkey_y, secret]); + + let root = std::merkle::compute_merkle_root(note_commitment[0], index, note_hash_path.as_slice()); + println(root); +} +``` + +To check merkle tree membership: + +1. Include a merkle root as a program input. +2. Compute the merkle root of a given leaf, index and hash path. +3. Assert the merkle roots are equal. + +For more info about merkle trees, see the Wikipedia [page](https://en.wikipedia.org/wiki/Merkle_tree). diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/ctstring.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/ctstring.md new file mode 100644 index 00000000000..b76f873ca03 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/ctstring.md @@ -0,0 +1,100 @@ +--- +title: CtString +--- + +`std::meta::ctstring` contains methods on the built-in `CtString` type which is +a compile-time, dynamically-sized string type. Compared to `str` and `fmtstr`, +`CtString` is useful because its size does not need to be specified in its type. This +can be used for formatting items at compile-time or general string handling in `comptime` +code. + +Since `fmtstr`s can be converted into `CtString`s, you can make use of their formatting +abilities in CtStrings by formatting in `fmtstr`s then converting the result to a CtString +afterward. + +## Traits + +### AsCtString + +```rust title="as-ctstring" showLineNumbers +pub trait AsCtString { + comptime fn as_ctstring(self) -> CtString; +} +``` +> Source code: noir_stdlib/src/meta/ctstring.nr#L43-L47 + + +Converts an object into a compile-time string. + +Implementations: + +```rust +impl AsCtString for str { ... } +impl AsCtString for fmtstr { ... } +``` + +## Methods + +### new + +```rust title="new" showLineNumbers +pub comptime fn new() -> Self { +``` +> Source code: noir_stdlib/src/meta/ctstring.nr#L4-L6 + + +Creates an empty `CtString`. + +### append_str + +```rust title="append_str" showLineNumbers +pub comptime fn append_str(self, s: str) -> Self { +``` +> Source code: noir_stdlib/src/meta/ctstring.nr#L11-L13 + + +Returns a new CtString with the given str appended onto the end. + +### append_fmtstr + +```rust title="append_fmtstr" showLineNumbers +pub comptime fn append_fmtstr(self, s: fmtstr) -> Self { +``` +> Source code: noir_stdlib/src/meta/ctstring.nr#L17-L19 + + +Returns a new CtString with the given fmtstr appended onto the end. + +### as_quoted_str + +```rust title="as_quoted_str" showLineNumbers +pub comptime fn as_quoted_str(self) -> Quoted { +``` +> Source code: noir_stdlib/src/meta/ctstring.nr#L26-L28 + + +Returns a quoted string literal from this string's contents. + +There is no direct conversion from a `CtString` to a `str` since +the size would not be known. To get around this, this function can +be used in combination with macro insertion (`!`) to insert this string +literal at this function's call site. + +Example: + +```rust title="as_quoted_str_example" showLineNumbers +let my_ctstring = "foo bar".as_ctstring(); + let my_str = my_ctstring.as_quoted_str!(); + + assert_eq(crate::meta::type_of(my_str), quote { str<7> }.as_type()); +``` +> Source code: noir_stdlib/src/meta/ctstring.nr#L92-L97 + + +## Trait Implementations + +```rust +impl Eq for CtString +impl Hash for CtString +impl Append for CtString +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/expr.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/expr.md new file mode 100644 index 00000000000..b6d395c6700 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/expr.md @@ -0,0 +1,380 @@ +--- +title: Expr +--- + +`std::meta::expr` contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. + +## Methods + +### as_array + +```rust title="as_array" showLineNumbers +pub comptime fn as_array(self) -> Option<[Expr]> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L10-L12 + + +If this expression is an array, this returns a slice of each element in the array. + +### as_assert + +```rust title="as_assert" showLineNumbers +pub comptime fn as_assert(self) -> Option<(Expr, Option)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L16-L18 + + +If this expression is an assert, this returns the assert expression and the optional message. + +### as_assert_eq + +```rust title="as_assert_eq" showLineNumbers +pub comptime fn as_assert_eq(self) -> Option<(Expr, Expr, Option)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L23-L25 + + +If this expression is an assert_eq, this returns the left-hand-side and right-hand-side +expressions, together with the optional message. + +### as_assign + +```rust title="as_assign" showLineNumbers +pub comptime fn as_assign(self) -> Option<(Expr, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L30-L32 + + +If this expression is an assignment, this returns a tuple with the left hand side +and right hand side in order. + +### as_binary_op + +```rust title="as_binary_op" showLineNumbers +pub comptime fn as_binary_op(self) -> Option<(Expr, BinaryOp, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L37-L39 + + +If this expression is a binary operator operation ` `, +return the left-hand side, operator, and the right-hand side of the operation. + +### as_block + +```rust title="as_block" showLineNumbers +pub comptime fn as_block(self) -> Option<[Expr]> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L44-L46 + + +If this expression is a block `{ stmt1; stmt2; ...; stmtN }`, return +a slice containing each statement. + +### as_bool + +```rust title="as_bool" showLineNumbers +pub comptime fn as_bool(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L50-L52 + + +If this expression is a boolean literal, return that literal. + +### as_cast + +```rust title="as_cast" showLineNumbers +#[builtin(expr_as_cast)] + pub comptime fn as_cast(self) -> Option<(Expr, UnresolvedType)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L56-L59 + + +If this expression is a cast expression (`expr as type`), returns the casted +expression and the type to cast to. + +### as_comptime + +```rust title="as_comptime" showLineNumbers +pub comptime fn as_comptime(self) -> Option<[Expr]> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L64-L66 + + +If this expression is a `comptime { stmt1; stmt2; ...; stmtN }` block, +return each statement in the block. + +### as_constructor + +```rust title="as_constructor" showLineNumbers +pub comptime fn as_constructor(self) -> Option<(UnresolvedType, [(Quoted, Expr)])> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L71-L73 + + +If this expression is a constructor `Type { field1: expr1, ..., fieldN: exprN }`, +return the type and the fields. + +### as_for + +```rust title="as_for" showLineNumbers +pub comptime fn as_for(self) -> Option<(Quoted, Expr, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L78-L80 + + +If this expression is a for statement over a single expression, return the identifier, +the expression and the for loop body. + +### as_for_range + +```rust title="as_for" showLineNumbers +pub comptime fn as_for(self) -> Option<(Quoted, Expr, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L78-L80 + + +If this expression is a for statement over a range, return the identifier, +the range start, the range end and the for loop body. + +### as_function_call + +```rust title="as_function_call" showLineNumbers +pub comptime fn as_function_call(self) -> Option<(Expr, [Expr])> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L92-L94 + + +If this expression is a function call `foo(arg1, ..., argN)`, return +the function and a slice of each argument. + +### as_if + +```rust title="as_if" showLineNumbers +pub comptime fn as_if(self) -> Option<(Expr, Expr, Option)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L100-L102 + + +If this expression is an `if condition { then_branch } else { else_branch }`, +return the condition, then branch, and else branch. If there is no else branch, +`None` is returned for that branch instead. + +### as_index + +```rust title="as_index" showLineNumbers +pub comptime fn as_index(self) -> Option<(Expr, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L107-L109 + + +If this expression is an index into an array `array[index]`, return the +array and the index. + +### as_integer + +```rust title="as_integer" showLineNumbers +pub comptime fn as_integer(self) -> Option<(Field, bool)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L114-L116 + + +If this expression is an integer literal, return the integer as a field +as well as whether the integer is negative (true) or not (false). + +### as_lambda + +```rust title="as_lambda" showLineNumbers +pub comptime fn as_lambda( + self, + ) -> Option<([(Expr, Option)], Option, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L120-L124 + + +If this expression is a lambda, returns the parameters, return type and body. + +### as_let + +```rust title="as_let" showLineNumbers +pub comptime fn as_let(self) -> Option<(Expr, Option, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L129-L131 + + +If this expression is a let statement, returns the let pattern as an `Expr`, +the optional type annotation, and the assigned expression. + +### as_member_access + +```rust title="as_member_access" showLineNumbers +pub comptime fn as_member_access(self) -> Option<(Expr, Quoted)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L136-L138 + + +If this expression is a member access `foo.bar`, return the struct/tuple +expression and the field. The field will be represented as a quoted value. + +### as_method_call + +```rust title="as_method_call" showLineNumbers +pub comptime fn as_method_call(self) -> Option<(Expr, Quoted, [UnresolvedType], [Expr])> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L143-L145 + + +If this expression is a method call `foo.bar::(arg1, ..., argN)`, return +the receiver, method name, a slice of each generic argument, and a slice of each argument. + +### as_repeated_element_array + +```rust title="as_repeated_element_array" showLineNumbers +pub comptime fn as_repeated_element_array(self) -> Option<(Expr, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L150-L152 + + +If this expression is a repeated element array `[elem; length]`, return +the repeated element and the length expressions. + +### as_repeated_element_slice + +```rust title="as_repeated_element_slice" showLineNumbers +pub comptime fn as_repeated_element_slice(self) -> Option<(Expr, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L157-L159 + + +If this expression is a repeated element slice `[elem; length]`, return +the repeated element and the length expressions. + +### as_slice + +```rust title="as_slice" showLineNumbers +pub comptime fn as_slice(self) -> Option<[Expr]> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L164-L166 + + +If this expression is a slice literal `&[elem1, ..., elemN]`, +return each element of the slice. + +### as_tuple + +```rust title="as_tuple" showLineNumbers +pub comptime fn as_tuple(self) -> Option<[Expr]> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L171-L173 + + +If this expression is a tuple `(field1, ..., fieldN)`, +return each element of the tuple. + +### as_unary_op + +```rust title="as_unary_op" showLineNumbers +pub comptime fn as_unary_op(self) -> Option<(UnaryOp, Expr)> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L178-L180 + + +If this expression is a unary operation ` `, +return the unary operator as well as the right-hand side expression. + +### as_unsafe + +```rust title="as_unsafe" showLineNumbers +pub comptime fn as_unsafe(self) -> Option<[Expr]> {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L185-L187 + + +If this expression is an `unsafe { stmt1; ...; stmtN }` block, +return each statement inside in a slice. + +### has_semicolon + +```rust title="has_semicolon" showLineNumbers +pub comptime fn has_semicolon(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L206-L208 + + +`true` if this expression is trailed by a semicolon. E.g. + +``` +comptime { + let expr1 = quote { 1 + 2 }.as_expr().unwrap(); + let expr2 = quote { 1 + 2; }.as_expr().unwrap(); + + assert(expr1.as_binary_op().is_some()); + assert(expr2.as_binary_op().is_some()); + + assert(!expr1.has_semicolon()); + assert(expr2.has_semicolon()); +} +``` + +### is_break + +```rust title="is_break" showLineNumbers +pub comptime fn is_break(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L212-L214 + + +`true` if this expression is `break`. + +### is_continue + +```rust title="is_continue" showLineNumbers +pub comptime fn is_continue(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L218-L220 + + +`true` if this expression is `continue`. + +### modify + +```rust title="modify" showLineNumbers +pub comptime fn modify(self, f: fn[Env](Expr) -> Option) -> Expr { +``` +> Source code: noir_stdlib/src/meta/expr.nr#L229-L231 + + +Applies a mapping function to this expression and to all of its sub-expressions. +`f` will be applied to each sub-expression first, then applied to the expression itself. + +This happens recursively for every expression within `self`. + +For example, calling `modify` on `(&[1], &[2, 3])` with an `f` that returns `Option::some` +for expressions that are integers, doubling them, would return `(&[2], &[4, 6])`. + +### quoted + +```rust title="quoted" showLineNumbers +pub comptime fn quoted(self) -> Quoted { +``` +> Source code: noir_stdlib/src/meta/expr.nr#L266-L268 + + +Returns this expression as a `Quoted` value. It's the same as `quote { $self }`. + +### resolve + +```rust title="resolve" showLineNumbers +pub comptime fn resolve(self, in_function: Option) -> TypedExpr {} +``` +> Source code: noir_stdlib/src/meta/expr.nr#L282-L284 + + +Resolves and type-checks this expression and returns the result as a `TypedExpr`. + +The `in_function` argument specifies where the expression is resolved: +- If it's `none`, the expression is resolved in the function where `resolve` was called +- If it's `some`, the expression is resolved in the given function + +If any names used by this expression are not in scope or if there are any type errors, +this will give compiler errors as if the expression was written directly into +the current `comptime` function. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/function_def.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/function_def.md new file mode 100644 index 00000000000..b7f2ebdb889 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/function_def.md @@ -0,0 +1,166 @@ +--- +title: FunctionDefinition +--- + +`std::meta::function_def` contains methods on the built-in `FunctionDefinition` type representing +a function definition in the source program. + +## Methods + +### add_attribute + +```rust title="add_attribute" showLineNumbers +pub comptime fn add_attribute(self, attribute: str) {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L3-L5 + + +Adds an attribute to the function. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +### body + +```rust title="body" showLineNumbers +pub comptime fn body(self) -> Expr {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L8-L10 + + +Returns the body of the function as an expression. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +### has_named_attribute + +```rust title="has_named_attribute" showLineNumbers +pub comptime fn has_named_attribute(self, name: str) -> bool {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L13-L15 + + +Returns true if this function has a custom attribute with the given name. + +### is_unconstrained + +```rust title="is_unconstrained" showLineNumbers +pub comptime fn is_unconstrained(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L18-L20 + + +Returns true if this function is unconstrained. + +### module + +```rust title="module" showLineNumbers +pub comptime fn module(self) -> Module {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L23-L25 + + +Returns the module where the function is defined. + +### name + +```rust title="name" showLineNumbers +pub comptime fn name(self) -> Quoted {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L28-L30 + + +Returns the name of the function. + +### parameters + +```rust title="parameters" showLineNumbers +pub comptime fn parameters(self) -> [(Quoted, Type)] {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L33-L35 + + +Returns each parameter of the function as a tuple of (parameter pattern, parameter type). + +### return_type + +```rust title="return_type" showLineNumbers +pub comptime fn return_type(self) -> Type {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L38-L40 + + +The return type of the function. + +### set_body + +```rust title="set_body" showLineNumbers +pub comptime fn set_body(self, body: Expr) {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L43-L45 + + +Mutate the function body to a new expression. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +### set_parameters + +```rust title="set_parameters" showLineNumbers +pub comptime fn set_parameters(self, parameters: [(Quoted, Type)]) {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L48-L50 + + +Mutates the function's parameters to a new set of parameters. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +Expects a slice of (parameter pattern, parameter type) for each parameter. Requires +each parameter pattern to be a syntactically valid parameter. + +### set_return_type + +```rust title="set_return_type" showLineNumbers +pub comptime fn set_return_type(self, return_type: Type) {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L53-L55 + + +Mutates the function's return type to a new type. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +### set_return_public + +```rust title="set_return_public" showLineNumbers +pub comptime fn set_return_public(self, public: bool) {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L58-L60 + + +Mutates the function's return visibility to public (if `true` is given) or private (if `false` is given). +This is only valid on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +### set_unconstrained + +```rust title="set_unconstrained" showLineNumbers +pub comptime fn set_unconstrained(self, value: bool) {} +``` +> Source code: noir_stdlib/src/meta/function_def.nr#L66-L68 + + +Mutates the function to be unconstrained (if `true` is given) or not (if `false` is given). +This is only valid on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +## Trait Implementations + +```rust +impl Eq for FunctionDefinition +impl Hash for FunctionDefinition +``` + +Note that each function is assigned a unique ID internally and this is what is used for +equality and hashing. So even functions with identical signatures and bodies may not +be equal in this sense if they were originally different items in the source program. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/index.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/index.md new file mode 100644 index 00000000000..65572d5e815 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/index.md @@ -0,0 +1,224 @@ +--- +title: Metaprogramming +description: Noir's Metaprogramming API +keywords: [metaprogramming, comptime, macros, macro, quote, unquote] +--- + +`std::meta` is the entry point for Noir's metaprogramming API. This consists of `comptime` functions +and types used for inspecting and modifying Noir programs. + +## Functions + +### type_of + +```rust title="type_of" showLineNumbers +pub comptime fn type_of(x: T) -> Type {} +``` +> Source code: noir_stdlib/src/meta/mod.nr#L27-L29 + + +Returns the type of a variable at compile-time. + +Example: +```rust +comptime { + let x: i32 = 1; + let x_type: Type = std::meta::type_of(x); + + assert_eq(x_type, quote { i32 }.as_type()); +} +``` + +### unquote + +```rust title="unquote" showLineNumbers +pub comptime fn unquote(code: Quoted) -> Quoted { +``` +> Source code: noir_stdlib/src/meta/mod.nr#L19-L21 + + +Unquotes the passed-in token stream where this function was called. + +Example: +```rust +comptime { + let code = quote { 1 + 2 }; + + // let x = 1 + 2; + let x = unquote!(code); +} +``` + +### derive + +```rust title="derive" showLineNumbers +#[varargs] +pub comptime fn derive(s: StructDefinition, traits: [TraitDefinition]) -> Quoted { +``` +> Source code: noir_stdlib/src/meta/mod.nr#L48-L51 + + +Attribute placed on struct definitions. + +Creates a trait impl for each trait passed in as an argument. +To do this, the trait must have a derive handler registered +with `derive_via` beforehand. The traits in the stdlib that +can be derived this way are `Eq`, `Ord`, `Default`, and `Hash`. + +Example: +```rust +#[derive(Eq, Default)] +struct Foo { + x: i32, + y: T, +} + +fn main() { + let foo1 = Foo::default(); + let foo2 = Foo { x: 0, y: &[0] }; + assert_eq(foo1, foo2); +} +``` + +### derive_via + +```rust title="derive_via_signature" showLineNumbers +pub comptime fn derive_via(t: TraitDefinition, f: DeriveFunction) { +``` +> Source code: noir_stdlib/src/meta/mod.nr#L68-L70 + + +Attribute placed on trait definitions. + +Registers a function to create impls for the given trait +when the trait is used in a `derive` call. Users may use +this to register their own functions to enable their traits +to be derived by `derive`. + +Because this function requires a function as an argument which +should produce a trait impl for any given struct, users may find +it helpful to use a function like `std::meta::make_trait_impl` to +help creating these impls. + +Example: +```rust +#[derive_via(derive_do_nothing)] +trait DoNothing { + fn do_nothing(self); +} + +comptime fn derive_do_nothing(s: StructDefinition) -> Quoted { + let typ = s.as_type(); + quote { + impl DoNothing for $typ { + fn do_nothing(self) { + println("Nothing"); + } + } + } +} +``` + +As another example, `derive_eq` in the stdlib is used to derive the `Eq` +trait for any struct. It makes use of `make_trait_impl` to do this: + +```rust title="derive_eq" showLineNumbers +comptime fn derive_eq(s: StructDefinition) -> Quoted { + let signature = quote { fn eq(_self: Self, _other: Self) -> bool }; + let for_each_field = |name| quote { (_self.$name == _other.$name) }; + let body = |fields| { + if s.fields().len() == 0 { + quote { true } + } else { + fields + } + }; + crate::meta::make_trait_impl( + s, + quote { Eq }, + signature, + for_each_field, + quote { & }, + body, + ) +} +``` +> Source code: noir_stdlib/src/cmp.nr#L10-L30 + + +### make_trait_impl + +```rust title="make_trait_impl" showLineNumbers +pub comptime fn make_trait_impl( + s: StructDefinition, + trait_name: Quoted, + function_signature: Quoted, + for_each_field: fn[Env1](Quoted) -> Quoted, + join_fields_with: Quoted, + body: fn[Env2](Quoted) -> Quoted, +) -> Quoted { +``` +> Source code: noir_stdlib/src/meta/mod.nr#L87-L96 + + +A helper function to more easily create trait impls while deriving traits. + +Note that this function only works for traits which: +1. Have only one method +2. Have no generics on the trait itself. + - E.g. Using this on a trait such as `trait Foo { ... }` will result in the + generated impl incorrectly missing the `T` generic. + +If your trait fits these criteria then `make_trait_impl` is likely the easiest +way to write your derive handler. The arguments are as follows: + +- `s`: The struct to make the impl for +- `trait_name`: The name of the trait to derive. E.g. `quote { Eq }`. +- `function_signature`: The signature of the trait method to derive. E.g. `fn eq(self, other: Self) -> bool`. +- `for_each_field`: An operation to be performed on each field. E.g. `|name| quote { (self.$name == other.$name) }`. +- `join_fields_with`: A separator to join each result of `for_each_field` with. + E.g. `quote { & }`. You can also use an empty `quote {}` for no separator. +- `body`: The result of the field operations are passed into this function for any final processing. + This is the place to insert any setup/teardown code the trait requires. If the trait doesn't require + any such code, you can return the body as-is: `|body| body`. + +Example deriving `Hash`: + +```rust title="derive_hash" showLineNumbers +comptime fn derive_hash(s: StructDefinition) -> Quoted { + let name = quote { Hash }; + let signature = quote { fn hash(_self: Self, _state: &mut H) where H: std::hash::Hasher }; + let for_each_field = |name| quote { _self.$name.hash(_state); }; + crate::meta::make_trait_impl( + s, + name, + signature, + for_each_field, + quote {}, + |fields| fields, + ) +} +``` +> Source code: noir_stdlib/src/hash/mod.nr#L138-L152 + + +Example deriving `Ord`: + +```rust title="derive_ord" showLineNumbers +comptime fn derive_ord(s: StructDefinition) -> Quoted { + let signature = quote { fn cmp(_self: Self, _other: Self) -> std::cmp::Ordering }; + let for_each_field = |name| quote { + if result == std::cmp::Ordering::equal() { + result = _self.$name.cmp(_other.$name); + } + }; + let body = |fields| quote { + let mut result = std::cmp::Ordering::equal(); + $fields + result + }; + crate::meta::make_trait_impl(s, quote { Ord }, signature, for_each_field, quote {}, body) +} +``` +> Source code: noir_stdlib/src/cmp.nr#L216-L231 + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/module.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/module.md new file mode 100644 index 00000000000..f47231972b7 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/module.md @@ -0,0 +1,82 @@ +--- +title: Module +--- + +`std::meta::module` contains methods on the built-in `Module` type which represents a module in the source program. +Note that this type represents a module generally, it isn't limited to only `mod my_submodule { ... }` +declarations in the source program. + +## Methods + +### add_item + +```rust title="add_item" showLineNumbers +pub comptime fn add_item(self, item: Quoted) {} +``` +> Source code: noir_stdlib/src/meta/module.nr#L3-L5 + + +Adds a top-level item (a function, a struct, a global, etc.) to the module. +Adding multiple items in one go is also valid if the `Quoted` value has multiple items in it. +Note that the items are type-checked as if they are inside the module they are being added to. + +### functions + +```rust title="functions" showLineNumbers +pub comptime fn functions(self) -> [FunctionDefinition] {} +``` +> Source code: noir_stdlib/src/meta/module.nr#L18-L20 + + +Returns each function defined in the module. + +### has_named_attribute + +```rust title="has_named_attribute" showLineNumbers +pub comptime fn has_named_attribute(self, name: str) -> bool {} +``` +> Source code: noir_stdlib/src/meta/module.nr#L8-L10 + + +Returns true if this module has a custom attribute with the given name. + +### is_contract + +```rust title="is_contract" showLineNumbers +pub comptime fn is_contract(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/module.nr#L13-L15 + + +`true` if this module is a contract module (was declared via `contract foo { ... }`). + +### name + +```rust title="name" showLineNumbers +pub comptime fn name(self) -> Quoted {} +``` +> Source code: noir_stdlib/src/meta/module.nr#L28-L30 + + +Returns the name of the module. + +### structs + +```rust title="structs" showLineNumbers +pub comptime fn structs(self) -> [StructDefinition] {} +``` +> Source code: noir_stdlib/src/meta/module.nr#L23-L25 + + +Returns each struct defined in the module. + +## Trait Implementations + +```rust +impl Eq for Module +impl Hash for Module +``` + +Note that each module is assigned a unique ID internally and this is what is used for +equality and hashing. So even modules with identical names and contents may not +be equal in this sense if they were originally different items in the source program. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/op.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/op.md new file mode 100644 index 00000000000..03ea49ad8ec --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/op.md @@ -0,0 +1,244 @@ +--- +title: UnaryOp and BinaryOp +--- + +`std::meta::op` contains the `UnaryOp` and `BinaryOp` types as well as methods on them. +These types are used to represent a unary or binary operator respectively in Noir source code. + +## Types + +### UnaryOp + +Represents a unary operator. One of `-`, `!`, `&mut`, or `*`. + +### Methods + +#### is_minus + +```rust title="is_minus" showLineNumbers +pub fn is_minus(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L24-L26 + + +Returns `true` if this operator is `-`. + +#### is_not + +```rust title="is_not" showLineNumbers +pub fn is_not(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L30-L32 + + +`true` if this operator is `!` + +#### is_mutable_reference + +```rust title="is_mutable_reference" showLineNumbers +pub fn is_mutable_reference(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L36-L38 + + +`true` if this operator is `&mut` + +#### is_dereference + +```rust title="is_dereference" showLineNumbers +pub fn is_dereference(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L42-L44 + + +`true` if this operator is `*` + +#### quoted + +```rust title="unary_quoted" showLineNumbers +pub comptime fn quoted(self) -> Quoted { +``` +> Source code: noir_stdlib/src/meta/op.nr#L48-L50 + + +Returns this operator as a `Quoted` value. + +### Trait Implementations + +```rust +impl Eq for UnaryOp +impl Hash for UnaryOp +``` + +### BinaryOp + +Represents a binary operator. One of `+`, `-`, `*`, `/`, `%`, `==`, `!=`, `<`, `<=`, `>`, `>=`, `&`, `|`, `^`, `>>`, or `<<`. + +### Methods + +#### is_add + +```rust title="is_add" showLineNumbers +pub fn is_add(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L86-L88 + + +`true` if this operator is `+` + +#### is_subtract + +```rust title="is_subtract" showLineNumbers +pub fn is_subtract(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L92-L94 + + +`true` if this operator is `-` + +#### is_multiply + +```rust title="is_multiply" showLineNumbers +pub fn is_multiply(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L98-L100 + + +`true` if this operator is `*` + +#### is_divide + +```rust title="is_divide" showLineNumbers +pub fn is_divide(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L104-L106 + + +`true` if this operator is `/` + +#### is_modulo + +```rust title="is_modulo" showLineNumbers +pub fn is_modulo(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L176-L178 + + +`true` if this operator is `%` + +#### is_equal + +```rust title="is_equal" showLineNumbers +pub fn is_equal(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L110-L112 + + +`true` if this operator is `==` + +#### is_not_equal + +```rust title="is_not_equal" showLineNumbers +pub fn is_not_equal(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L116-L118 + + +`true` if this operator is `!=` + +#### is_less_than + +```rust title="is_less_than" showLineNumbers +pub fn is_less_than(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L122-L124 + + +`true` if this operator is `<` + +#### is_less_than_or_equal + +```rust title="is_less_than_or_equal" showLineNumbers +pub fn is_less_than_or_equal(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L128-L130 + + +`true` if this operator is `<=` + +#### is_greater_than + +```rust title="is_greater_than" showLineNumbers +pub fn is_greater_than(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L134-L136 + + +`true` if this operator is `>` + +#### is_greater_than_or_equal + +```rust title="is_greater_than_or_equal" showLineNumbers +pub fn is_greater_than_or_equal(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L140-L142 + + +`true` if this operator is `>=` + +#### is_and + +```rust title="is_and" showLineNumbers +pub fn is_and(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L146-L148 + + +`true` if this operator is `&` + +#### is_or + +```rust title="is_or" showLineNumbers +pub fn is_or(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L152-L154 + + +`true` if this operator is `|` + +#### is_shift_right + +```rust title="is_shift_right" showLineNumbers +pub fn is_shift_right(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L164-L166 + + +`true` if this operator is `>>` + +#### is_shift_left + +```rust title="is_shift_right" showLineNumbers +pub fn is_shift_right(self) -> bool { +``` +> Source code: noir_stdlib/src/meta/op.nr#L164-L166 + + +`true` if this operator is `<<` + +#### quoted + +```rust title="binary_quoted" showLineNumbers +pub comptime fn quoted(self) -> Quoted { +``` +> Source code: noir_stdlib/src/meta/op.nr#L182-L184 + + +Returns this operator as a `Quoted` value. + +### Trait Implementations + +```rust +impl Eq for BinaryOp +impl Hash for BinaryOp +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/quoted.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/quoted.md new file mode 100644 index 00000000000..d7acf23bc07 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/quoted.md @@ -0,0 +1,141 @@ +--- +title: Quoted +--- + +`std::meta::quoted` contains methods on the built-in `Quoted` type which represents +quoted token streams and is the result of the `quote { ... }` expression. + +## Methods + +### as_expr + +```rust title="as_expr" showLineNumbers +pub comptime fn as_expr(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/quoted.nr#L6-L8 + + +Parses the quoted token stream as an expression. Returns `Option::none()` if +the expression failed to parse. + +Example: + +```rust title="as_expr_example" showLineNumbers +#[test] + fn test_expr_as_function_call() { + comptime + { + let expr = quote { foo(42) }.as_expr().unwrap(); + let (_function, args) = expr.as_function_call().unwrap(); + assert_eq(args.len(), 1); + assert_eq(args[0].as_integer().unwrap(), (42, false)); + } + } +``` +> Source code: test_programs/noir_test_success/comptime_expr/src/main.nr#L360-L371 + + +### as_module + +```rust title="as_module" showLineNumbers +pub comptime fn as_module(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/quoted.nr#L11-L13 + + +Interprets this token stream as a module path leading to the name of a module. +Returns `Option::none()` if the module isn't found or this token stream cannot be parsed as a path. + +Example: + +```rust title="as_module_example" showLineNumbers +mod baz { + pub mod qux {} +} + +#[test] +fn as_module_test() { + comptime { + let my_mod = quote { baz::qux }.as_module().unwrap(); + assert_eq(my_mod.name(), quote { qux }); + } +} +``` +> Source code: test_programs/compile_success_empty/comptime_module/src/main.nr#L115-L127 + + +### as_trait_constraint + +```rust title="as_trait_constraint" showLineNumbers +pub comptime fn as_trait_constraint(self) -> TraitConstraint {} +``` +> Source code: noir_stdlib/src/meta/quoted.nr#L16-L18 + + +Interprets this token stream as a trait constraint (without an object type). +Note that this function panics instead of returning `Option::none()` if the token +stream does not parse and resolve to a valid trait constraint. + +Example: + +```rust title="implements_example" showLineNumbers +pub fn function_with_where(_x: T) +where + T: SomeTrait, +{ + comptime { + let t = quote { T }.as_type(); + let some_trait_i32 = quote { SomeTrait }.as_trait_constraint(); + assert(t.implements(some_trait_i32)); + + assert(t.get_trait_impl(some_trait_i32).is_none()); + } +} +``` +> Source code: test_programs/compile_success_empty/comptime_type/src/main.nr#L160-L173 + + +### as_type + +```rust title="as_type" showLineNumbers +pub comptime fn as_type(self) -> Type {} +``` +> Source code: noir_stdlib/src/meta/quoted.nr#L21-L23 + + +Interprets this token stream as a resolved type. Panics if the token +stream doesn't parse to a type or if the type isn't a valid type in scope. + +```rust title="implements_example" showLineNumbers +pub fn function_with_where(_x: T) +where + T: SomeTrait, +{ + comptime { + let t = quote { T }.as_type(); + let some_trait_i32 = quote { SomeTrait }.as_trait_constraint(); + assert(t.implements(some_trait_i32)); + + assert(t.get_trait_impl(some_trait_i32).is_none()); + } +} +``` +> Source code: test_programs/compile_success_empty/comptime_type/src/main.nr#L160-L173 + + +### tokens + +```rust title="tokens" showLineNumbers +pub comptime fn tokens(self) -> [Quoted] {} +``` +> Source code: noir_stdlib/src/meta/quoted.nr#L26-L28 + + +Returns a slice of the individual tokens that form this token stream. + +## Trait Implementations + +```rust +impl Eq for Quoted +impl Hash for Quoted +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/struct_def.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/struct_def.md new file mode 100644 index 00000000000..fd609942f4e --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/struct_def.md @@ -0,0 +1,177 @@ +--- +title: StructDefinition +--- + +`std::meta::struct_def` contains methods on the built-in `StructDefinition` type. +This type corresponds to `struct Name { field1: Type1, ... }` items in the source program. + +## Methods + +### add_attribute + +```rust title="add_attribute" showLineNumbers +pub comptime fn add_attribute(self, attribute: str) {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L3-L5 + + +Adds an attribute to the struct. + +### add_generic + +```rust title="add_generic" showLineNumbers +pub comptime fn add_generic(self, generic_name: str) -> Type {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L8-L10 + + +Adds an generic to the struct. Returns the new generic type. +Errors if the given generic name isn't a single identifier or if +the struct already has a generic with the same name. + +This method should be used carefully, if there is existing code referring +to the struct type it may be checked before this function is called and +see the struct with the original number of generics. This method should +thus be preferred to use on code generated from other macros and structs +that are not used in function signatures. + +Example: + +```rust title="add-generic-example" showLineNumbers +comptime fn add_generic(s: StructDefinition) { + assert_eq(s.generics().len(), 0); + let new_generic = s.add_generic("T"); + + let generics = s.generics(); + assert_eq(generics.len(), 1); + assert_eq(generics[0], new_generic); + } +``` +> Source code: test_programs/compile_success_empty/comptime_struct_definition/src/main.nr#L35-L44 + + +### as_type + +```rust title="as_type" showLineNumbers +pub comptime fn as_type(self) -> Type {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L15-L17 + + +Returns this struct as a type in the source program. If this struct has +any generics, the generics are also included as-is. + +### generics + +```rust title="generics" showLineNumbers +pub comptime fn generics(self) -> [Type] {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L26-L28 + + +Returns each generic on this struct. + +Example: + +``` +#[example] +struct Foo { + bar: [T; 2], + baz: Baz, +} + +comptime fn example(foo: StructDefinition) { + assert_eq(foo.generics().len(), 2); + + // Fails because `T` isn't in scope + // let t = quote { T }.as_type(); + // assert_eq(foo.generics()[0], t); +} +``` + +### fields + +```rust title="fields" showLineNumbers +pub comptime fn fields(self) -> [(Quoted, Type)] {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L33-L35 + + +Returns each field of this struct as a pair of (field name, field type). + +### has_named_attribute + +```rust title="has_named_attribute" showLineNumbers +pub comptime fn has_named_attribute(self, name: str) -> bool {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L20-L22 + + +Returns true if this struct has a custom attribute with the given name. + +### module + +```rust title="module" showLineNumbers +pub comptime fn module(self) -> Module {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L38-L40 + + +Returns the module where the struct is defined. + +### name + +```rust title="name" showLineNumbers +pub comptime fn name(self) -> Quoted {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L43-L45 + + +Returns the name of this struct + +Note that the returned quoted value will be just the struct name, it will +not be the full path to the struct, nor will it include any generics. + +### set_fields + +```rust title="set_fields" showLineNumbers +pub comptime fn set_fields(self, new_fields: [(Quoted, Type)]) {} +``` +> Source code: noir_stdlib/src/meta/struct_def.nr#L52-L54 + + +Sets the fields of this struct to the given fields list where each element +is a pair of the field's name and the field's type. Expects each field name +to be a single identifier. Note that this will override any previous fields +on this struct. If those should be preserved, use `.fields()` to retrieve the +current fields on the struct type and append the new fields from there. + +Example: + +```rust +// Change this struct to: +// struct Foo { +// a: u32, +// b: i8, +// } +#[mangle_fields] +struct Foo { x: Field } + +comptime fn mangle_fields(s: StructDefinition) { + s.set_fields(&[ + (quote { a }, quote { u32 }.as_type()), + (quote { b }, quote { i8 }.as_type()), + ]); +} +``` + +## Trait Implementations + +```rust +impl Eq for StructDefinition +impl Hash for StructDefinition +``` + +Note that each struct is assigned a unique ID internally and this is what is used for +equality and hashing. So even structs with identical generics and fields may not +be equal in this sense if they were originally different items in the source program. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_constraint.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_constraint.md new file mode 100644 index 00000000000..3106f732b5a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_constraint.md @@ -0,0 +1,17 @@ +--- +title: TraitConstraint +--- + +`std::meta::trait_constraint` contains methods on the built-in `TraitConstraint` type which represents +a trait constraint that can be used to search for a trait implementation. This is similar +syntactically to just the trait itself, but can also contain generic arguments. E.g. `Eq`, `Default`, +`BuildHasher`. + +This type currently has no public methods but it can be used alongside `Type` in `implements` or `get_trait_impl`. + +## Trait Implementations + +```rust +impl Eq for TraitConstraint +impl Hash for TraitConstraint +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_def.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_def.md new file mode 100644 index 00000000000..e661d3af7f1 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_def.md @@ -0,0 +1,26 @@ +--- +title: TraitDefinition +--- + +`std::meta::trait_def` contains methods on the built-in `TraitDefinition` type. This type +represents trait definitions such as `trait Foo { .. }` at the top-level of a program. + +## Methods + +### as_trait_constraint + +```rust title="as_trait_constraint" showLineNumbers +pub comptime fn as_trait_constraint(_self: Self) -> TraitConstraint {} +``` +> Source code: noir_stdlib/src/meta/trait_def.nr#L6-L8 + + +Converts this trait into a trait constraint. If there are any generics on this +trait, they will be kept as-is without instantiating or replacing them. + +## Trait Implementations + +```rust +impl Eq for TraitDefinition +impl Hash for TraitDefinition +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_impl.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_impl.md new file mode 100644 index 00000000000..a527617c1e6 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/trait_impl.md @@ -0,0 +1,60 @@ +--- +title: TraitImpl +--- + +`std::meta::trait_impl` contains methods on the built-in `TraitImpl` type which represents a trait +implementation such as `impl Foo for Bar { ... }`. + +## Methods + +### trait_generic_args + +```rust title="trait_generic_args" showLineNumbers +pub comptime fn trait_generic_args(self) -> [Type] {} +``` +> Source code: noir_stdlib/src/meta/trait_impl.nr#L3-L5 + + +Returns any generic arguments on the trait of this trait implementation, if any. + +```rs +impl Foo for Bar { ... } + +comptime { + let bar_type = quote { Bar }.as_type(); + let foo = quote { Foo }.as_trait_constraint(); + + let my_impl: TraitImpl = bar_type.get_trait_impl(foo).unwrap(); + + let generics = my_impl.trait_generic_args(); + assert_eq(generics.len(), 2); + + assert_eq(generics[0], quote { i32 }.as_type()); + assert_eq(generics[1], quote { Field }.as_type()); +} +``` + +### methods + +```rust title="methods" showLineNumbers +pub comptime fn methods(self) -> [FunctionDefinition] {} +``` +> Source code: noir_stdlib/src/meta/trait_impl.nr#L8-L10 + + +Returns each method in this trait impl. + +Example: + +```rs +comptime { + let i32_type = quote { i32 }.as_type(); + let eq = quote { Eq }.as_trait_constraint(); + + let impl_eq_for_i32: TraitImpl = i32_type.get_trait_impl(eq).unwrap(); + let methods = impl_eq_for_i32.methods(); + + assert_eq(methods.len(), 1); + assert_eq(methods[0].name(), quote { eq }); +} +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typ.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typ.md new file mode 100644 index 00000000000..90222c222f5 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typ.md @@ -0,0 +1,264 @@ +--- +title: Type +--- + +`std::meta::typ` contains methods on the built-in `Type` type used for representing +a type in the source program. + +## Functions + +```rust title="fresh_type_variable" showLineNumbers +pub comptime fn fresh_type_variable() -> Type {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L57-L59 + + +Creates and returns an unbound type variable. This is a special kind of type internal +to type checking which will type check with any other type. When it is type checked +against another type it will also be set to that type. For example, if `a` is a type +variable and we have the type equality `(a, i32) = (u8, i32)`, the compiler will set +`a` equal to `u8`. + +Unbound type variables will often be rendered as `_` while printing them. Bound type +variables will appear as the type they are bound to. + +This can be used in conjunction with functions which internally perform type checks +such as `Type::implements` or `Type::get_trait_impl` to potentially grab some of the types used. + +Note that calling `Type::implements` or `Type::get_trait_impl` on a type variable will always +fail. + +Example: + +```rust title="serialize-setup" showLineNumbers +trait Serialize {} + +impl Serialize<1> for Field {} + +impl Serialize for [T; N] +where + T: Serialize, +{} + +impl Serialize for (T, U) +where + T: Serialize, + U: Serialize, +{} +``` +> Source code: test_programs/compile_success_empty/comptime_type/src/main.nr#L14-L29 + +```rust title="fresh-type-variable-example" showLineNumbers +let typevar1 = std::meta::typ::fresh_type_variable(); + let constraint = quote { Serialize<$typevar1> }.as_trait_constraint(); + let field_type = quote { Field }.as_type(); + + // Search for a trait impl (binding typevar1 to 1 when the impl is found): + assert(field_type.implements(constraint)); + + // typevar1 should be bound to the "1" generic now: + assert_eq(typevar1.as_constant().unwrap(), 1); + + // If we want to do the same with a different type, we need to + // create a new type variable now that `typevar1` is bound + let typevar2 = std::meta::typ::fresh_type_variable(); + let constraint = quote { Serialize<$typevar2> }.as_trait_constraint(); + let array_type = quote { [(Field, Field); 5] }.as_type(); + assert(array_type.implements(constraint)); + + // Now typevar2 should be bound to the serialized pair size 2 times the array length 5 + assert_eq(typevar2.as_constant().unwrap(), 10); +``` +> Source code: test_programs/compile_success_empty/comptime_type/src/main.nr#L129-L149 + + +## Methods + +### as_array + +```rust title="as_array" showLineNumbers +pub comptime fn as_array(self) -> Option<(Type, Type)> {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L76-L78 + + +If this type is an array, return a pair of (element type, size type). + +Example: + +```rust +comptime { + let array_type = quote { [Field; 3] }.as_type(); + let (field_type, three_type) = array_type.as_array().unwrap(); + + assert(field_type.is_field()); + assert_eq(three_type.as_constant().unwrap(), 3); +} +``` + +### as_constant + +```rust title="as_constant" showLineNumbers +pub comptime fn as_constant(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L83-L85 + + +If this type is a constant integer (such as the `3` in the array type `[Field; 3]`), +return the numeric constant. + +### as_integer + +```rust title="as_integer" showLineNumbers +pub comptime fn as_integer(self) -> Option<(bool, u8)> {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L90-L92 + + +If this is an integer type, return a boolean which is `true` +if the type is signed, as well as the number of bits of this integer type. + +### as_mutable_reference + +```rust title="as_mutable_reference" showLineNumbers +comptime fn as_mutable_reference(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L96-L98 + + +If this is a mutable reference type `&mut T`, returns the mutable type `T`. + +### as_slice + +```rust title="as_slice" showLineNumbers +pub comptime fn as_slice(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L102-L104 + + +If this is a slice type, return the element type of the slice. + +### as_str + +```rust title="as_str" showLineNumbers +pub comptime fn as_str(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L108-L110 + + +If this is a `str` type, returns the length `N` as a type. + +### as_struct + +```rust title="as_struct" showLineNumbers +pub comptime fn as_struct(self) -> Option<(StructDefinition, [Type])> {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L114-L116 + + +If this is a struct type, returns the struct in addition to +any generic arguments on this type. + +### as_tuple + +```rust title="as_tuple" showLineNumbers +pub comptime fn as_tuple(self) -> Option<[Type]> {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L120-L122 + + +If this is a tuple type, returns each element type of the tuple. + +### get_trait_impl + +```rust title="get_trait_impl" showLineNumbers +pub comptime fn get_trait_impl(self, constraint: TraitConstraint) -> Option {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L143-L145 + + +Retrieves the trait implementation that implements the given +trait constraint for this type. If the trait constraint is not +found, `None` is returned. Note that since the concrete trait implementation +for a trait constraint specified from a `where` clause is unknown, +this function will return `None` in these cases. If you only want to know +whether a type implements a trait, use `implements` instead. + +Example: + +```rust +comptime { + let field_type = quote { Field }.as_type(); + let default = quote { Default }.as_trait_constraint(); + + let the_impl: TraitImpl = field_type.get_trait_impl(default).unwrap(); + assert(the_impl.methods().len(), 1); +} +``` + +### implements + +```rust title="implements" showLineNumbers +pub comptime fn implements(self, constraint: TraitConstraint) -> bool {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L166-L168 + + +`true` if this type implements the given trait. Note that unlike +`get_trait_impl` this will also return true for any `where` constraints +in scope. + +Example: + +```rust +fn foo() where T: Default { + comptime { + let field_type = quote { Field }.as_type(); + let default = quote { Default }.as_trait_constraint(); + assert(field_type.implements(default)); + + let t = quote { T }.as_type(); + assert(t.implements(default)); + } +} +``` + +### is_bool + +```rust title="is_bool" showLineNumbers +pub comptime fn is_bool(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L172-L174 + + +`true` if this type is `bool`. + +### is_field + +```rust title="is_field" showLineNumbers +pub comptime fn is_field(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L178-L180 + + +`true` if this type is `Field`. + +### is_unit + +```rust title="is_unit" showLineNumbers +comptime fn is_unit(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/typ.nr#L184-L186 + + +`true` if this type is the unit `()` type. + +## Trait Implementations + +```rust +impl Eq for Type +impl Hash for Type +``` +Note that this is syntactic equality, this is not the same as whether two types will type check +to be the same type. Unless type inference or generics are being used however, users should not +typically have to worry about this distinction unless `std::meta::typ::fresh_type_variable` is used. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typed_expr.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typed_expr.md new file mode 100644 index 00000000000..0db7dbfef61 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/typed_expr.md @@ -0,0 +1,27 @@ +--- +title: TypedExpr +--- + +`std::meta::typed_expr` contains methods on the built-in `TypedExpr` type for resolved and type-checked expressions. + +## Methods + +### get_type + +```rust title="as_function_definition" showLineNumbers +pub comptime fn as_function_definition(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/typed_expr.nr#L7-L9 + + +If this expression refers to a function definitions, returns it. Otherwise returns `Option::none()`. + +### get_type + +```rust title="get_type" showLineNumbers +pub comptime fn get_type(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/typed_expr.nr#L13-L15 + + +Returns the type of the expression, or `Option::none()` if there were errors when the expression was previously resolved. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/unresolved_type.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/unresolved_type.md new file mode 100644 index 00000000000..2826ec5ec0f --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/meta/unresolved_type.md @@ -0,0 +1,57 @@ +--- +title: UnresolvedType +--- + +`std::meta::unresolved_type` contains methods on the built-in `UnresolvedType` type for the syntax of types. + +## Methods + +### as_mutable_reference + +```rust title="as_mutable_reference" showLineNumbers +comptime fn as_mutable_reference(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/unresolved_type.nr#L8-L10 + + +If this is a mutable reference type `&mut T`, returns the mutable type `T`. + +### as_slice + +```rust title="as_slice" showLineNumbers +comptime fn as_slice(self) -> Option {} +``` +> Source code: noir_stdlib/src/meta/unresolved_type.nr#L14-L16 + + +If this is a slice `&[T]`, returns the element type `T`. + +### is_bool + +```rust title="is_bool" showLineNumbers +comptime fn is_bool(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/unresolved_type.nr#L20-L22 + + +Returns `true` if this type is `bool`. + +### is_field + +```rust title="is_field" showLineNumbers +pub comptime fn is_field(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/unresolved_type.nr#L26-L28 + + +Returns true if this type refers to the Field type. + +### is_unit + +```rust title="is_unit" showLineNumbers +comptime fn is_unit(self) -> bool {} +``` +> Source code: noir_stdlib/src/meta/unresolved_type.nr#L32-L34 + + +Returns true if this type is the unit `()` type. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/options.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/options.md new file mode 100644 index 00000000000..a1bd4e1de5f --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/options.md @@ -0,0 +1,101 @@ +--- +title: Option Type +--- + +The `Option` type is a way to express that a value might be present (`Some(T))` or absent (`None`). It's a safer way to handle potential absence of values, compared to using nulls in many other languages. + +```rust +struct Option { + None, + Some(T), +} +``` + +The `Option` type, already imported into your Noir program, can be used directly: + +```rust +fn main() { + let none = Option::none(); + let some = Option::some(3); +} +``` + +See [this test](https://github.com/noir-lang/noir/blob/5cbfb9c4a06c8865c98ff2b594464b037d821a5c/crates/nargo_cli/tests/test_data/option/src/main.nr) for a more comprehensive set of examples of each of the methods described below. + +## Methods + +### none + +Constructs a none value. + +### some + +Constructs a some wrapper around a given value. + +### is_none + +Returns true if the Option is None. + +### is_some + +Returns true of the Option is Some. + +### unwrap + +Asserts `self.is_some()` and returns the wrapped value. + +### unwrap_unchecked + +Returns the inner value without asserting `self.is_some()`. This method can be useful within an if condition when we already know that `option.is_some()`. If the option is None, there is no guarantee what value will be returned, only that it will be of type T for an `Option`. + +### unwrap_or + +Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value. + +### unwrap_or_else + +Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return a default value. + +### expect + +Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value. The custom message is expected to be a format string. + +### map + +If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`. + +### map_or + +If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value. + +### map_or_else + +If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`. + +### and + +Returns None if self is None. Otherwise, this returns `other`. + +### and_then + +If self is None, this returns None. Otherwise, this calls the given function 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`. + +### or + +If self is Some, return self. Otherwise, return `other`. + +### or_else + +If self is Some, return self. Otherwise, return `default()`. + +### xor + +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. + +### filter + +Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true. Otherwise, this returns `None`. + +### flatten + +Flattens an `Option>` into a `Option`. This returns `None` if the outer Option is None. Otherwise, this returns the inner Option. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/recursion.mdx b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/recursion.mdx new file mode 100644 index 00000000000..60414a2fa51 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/recursion.mdx @@ -0,0 +1,85 @@ +--- +title: Recursive Proofs +description: Learn about how to write recursive proofs in Noir. +keywords: [recursion, recursive proofs, verification_key, verify_proof] +--- + +import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; + +Noir supports recursively verifying proofs, meaning you verify the proof of a Noir program in another Noir program. This enables creating proofs of arbitrary size by doing step-wise verification of smaller components of a large proof. + +Read [the explainer on recursion](../../explainers/explainer-recursion.md) to know more about this function and the [guide on how to use it.](../../how_to/how-to-recursion.md) + +## The `#[recursive]` Attribute + +In Noir, the `#[recursive]` attribute is used to indicate that a circuit is designed for recursive proof generation. When applied, it informs the compiler and the tooling that the circuit should be compiled in a way that makes its proofs suitable for recursive verification. This attribute eliminates the need for manual flagging of recursion at the tooling level, streamlining the proof generation process for recursive circuits. + +### Example usage with `#[recursive]` + +```rust +#[recursive] +fn main(x: Field, y: pub Field) { + assert(x == y, "x and y are not equal"); +} + +// This marks the circuit as recursion-friendly and indicates that proofs generated from this circuit +// are intended for recursive verification. +``` + +By incorporating this attribute directly in the circuit's definition, tooling like Nargo and NoirJS can automatically execute recursive-specific duties for Noir programs (e.g. recursive-friendly proof artifact generation) without additional flags or configurations. + +## Verifying Recursive Proofs + +```rust +#[foreign(recursive_aggregation)] +pub fn verify_proof(verification_key: [Field], proof: [Field], public_inputs: [Field], key_hash: Field) {} +``` + + + +## Example usage + +```rust + +fn main( + verification_key : [Field; 114], + proof : [Field; 93], + public_inputs : [Field; 1], + key_hash : Field, + proof_b : [Field; 93], +) { + std::verify_proof( + verification_key, + proof, + public_inputs, + key_hash + ); + + std::verify_proof( + verification_key, + proof_b, + public_inputs, + key_hash + ); +} +``` + +You can see a full example of recursive proofs in [this example recursion demo repo](https://github.com/noir-lang/noir-examples/tree/master/recursion). + +## Parameters + +### `verification_key` + +The verification key for the zk program that is being verified. + +### `proof` + +The proof for the zk program that is being verified. + +### `public_inputs` + +These represent the public inputs of the proof we are verifying. + +### `key_hash` + +A key hash is used to check the validity of the verification key. The circuit implementing this opcode can use this hash to ensure that the key provided to the circuit matches the key produced by the circuit creator. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/traits.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/traits.md new file mode 100644 index 00000000000..ee20f9cd949 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/noir/standard_library/traits.md @@ -0,0 +1,628 @@ +--- +title: Traits +description: Noir's stdlib provides a few commonly used traits. +keywords: [traits, trait, interface, protocol, default, add, eq] +--- + +## `std::default` + +### `std::default::Default` + +```rust title="default-trait" showLineNumbers +pub trait Default { + fn default() -> Self; +} +``` +> Source code: noir_stdlib/src/default.nr#L4-L8 + + +Constructs a default value of a type. + +Implementations: +```rust +impl Default for Field { .. } + +impl Default for i8 { .. } +impl Default for i16 { .. } +impl Default for i32 { .. } +impl Default for i64 { .. } + +impl Default for u8 { .. } +impl Default for u16 { .. } +impl Default for u32 { .. } +impl Default for u64 { .. } + +impl Default for () { .. } +impl Default for bool { .. } + +impl Default for [T; N] + where T: Default { .. } + +impl Default for [T] { .. } + +impl Default for (A, B) + where A: Default, B: Default { .. } + +impl Default for (A, B, C) + where A: Default, B: Default, C: Default { .. } + +impl Default for (A, B, C, D) + where A: Default, B: Default, C: Default, D: Default { .. } + +impl Default for (A, B, C, D, E) + where A: Default, B: Default, C: Default, D: Default, E: Default { .. } +``` + +For primitive integer types, the return value of `default` is `0`. Container +types such as arrays are filled with default values of their element type, +except slices whose length is unknown and thus defaulted to zero. + +--- + +## `std::convert` + +### `std::convert::From` + +```rust title="from-trait" showLineNumbers +pub trait From { + fn from(input: T) -> Self; +} +``` +> Source code: noir_stdlib/src/convert.nr#L1-L5 + + +The `From` trait defines how to convert from a given type `T` to the type on which the trait is implemented. + +The Noir standard library provides a number of implementations of `From` between primitive types. +```rust title="from-impls" showLineNumbers +// Unsigned integers + +impl From for u32 { + fn from(value: u8) -> u32 { + value as u32 + } +} + +impl From for u64 { + fn from(value: u8) -> u64 { + value as u64 + } +} +impl From for u64 { + fn from(value: u32) -> u64 { + value as u64 + } +} + +impl From for Field { + fn from(value: u8) -> Field { + value as Field + } +} +impl From for Field { + fn from(value: u32) -> Field { + value as Field + } +} +impl From for Field { + fn from(value: u64) -> Field { + value as Field + } +} + +// Signed integers + +impl From for i32 { + fn from(value: i8) -> i32 { + value as i32 + } +} + +impl From for i64 { + fn from(value: i8) -> i64 { + value as i64 + } +} +impl From for i64 { + fn from(value: i32) -> i64 { + value as i64 + } +} + +// Booleans +impl From for u8 { + fn from(value: bool) -> u8 { + value as u8 + } +} +impl From for u32 { + fn from(value: bool) -> u32 { + value as u32 + } +} +impl From for u64 { + fn from(value: bool) -> u64 { + value as u64 + } +} +impl From for i8 { + fn from(value: bool) -> i8 { + value as i8 + } +} +impl From for i32 { + fn from(value: bool) -> i32 { + value as i32 + } +} +impl From for i64 { + fn from(value: bool) -> i64 { + value as i64 + } +} +impl From for Field { + fn from(value: bool) -> Field { + value as Field + } +} +``` +> Source code: noir_stdlib/src/convert.nr#L28-L119 + + +#### When to implement `From` + +As a general rule of thumb, `From` may be implemented in the [situations where it would be suitable in Rust](https://doc.rust-lang.org/std/convert/trait.From.html#when-to-implement-from): + +- The conversion is *infallible*: Noir does not provide an equivalent to Rust's `TryFrom`, if the conversion can fail then provide a named method instead. +- The conversion is *lossless*: semantically, it should not lose or discard information. For example, `u32: From` can losslessly convert any `u16` into a valid `u32` such that the original `u16` can be recovered. On the other hand, `u16: From` should not be implemented as `2**16` is a `u32` which cannot be losslessly converted into a `u16`. +- The conversion is *value-preserving*: the conceptual kind and meaning of the resulting value is the same, even though the Noir type and technical representation might be different. While it's possible to infallibly and losslessly convert a `u8` into a `str<2>` hex representation, `4u8` and `"04"` are too different for `str<2>: From` to be implemented. +- The conversion is *obvious*: it's the only reasonable conversion between the two types. If there's ambiguity on how to convert between them such that the same input could potentially map to two different values then a named method should be used. For instance rather than implementing `U128: From<[u8; 16]>`, the methods `U128::from_le_bytes` and `U128::from_be_bytes` are used as otherwise the endianness of the array would be ambiguous, resulting in two potential values of `U128` from the same byte array. + +One additional recommendation specific to Noir is: +- The conversion is *efficient*: it's relatively cheap to convert between the two types. Due to being a ZK DSL, it's more important to avoid unnecessary computation compared to Rust. If the implementation of `From` would encourage users to perform unnecessary conversion, resulting in additional proving time, then it may be preferable to expose functionality such that this conversion may be avoided. + +### `std::convert::Into` + +The `Into` trait is defined as the reciprocal of `From`. It should be easy to convince yourself that if we can convert to type `A` from type `B`, then it's possible to convert type `B` into type `A`. + +For this reason, implementing `From` on a type will automatically generate a matching `Into` implementation. One should always prefer implementing `From` over `Into` as implementing `Into` will not generate a matching `From` implementation. + +```rust title="into-trait" showLineNumbers +pub trait Into { + fn into(self) -> T; +} + +impl Into for U +where + T: From, +{ + fn into(self) -> T { + T::from(self) + } +} +``` +> Source code: noir_stdlib/src/convert.nr#L13-L26 + + +`Into` is most useful when passing function arguments where the types don't quite match up with what the function expects. In this case, the compiler has enough type information to perform the necessary conversion by just appending `.into()` onto the arguments in question. + +--- + +## `std::cmp` + +### `std::cmp::Eq` + +```rust title="eq-trait" showLineNumbers +pub trait Eq { + fn eq(self, other: Self) -> bool; +} +``` +> Source code: noir_stdlib/src/cmp.nr#L4-L8 + + +Returns `true` if `self` is equal to `other`. Implementing this trait on a type +allows the type to be used with `==` and `!=`. + +Implementations: +```rust +impl Eq for Field { .. } + +impl Eq for i8 { .. } +impl Eq for i16 { .. } +impl Eq for i32 { .. } +impl Eq for i64 { .. } + +impl Eq for u8 { .. } +impl Eq for u16 { .. } +impl Eq for u32 { .. } +impl Eq for u64 { .. } + +impl Eq for () { .. } +impl Eq for bool { .. } + +impl Eq for [T; N] + where T: Eq { .. } + +impl Eq for [T] + where T: Eq { .. } + +impl Eq for (A, B) + where A: Eq, B: Eq { .. } + +impl Eq for (A, B, C) + where A: Eq, B: Eq, C: Eq { .. } + +impl Eq for (A, B, C, D) + where A: Eq, B: Eq, C: Eq, D: Eq { .. } + +impl Eq for (A, B, C, D, E) + where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq { .. } +``` + +### `std::cmp::Ord` + +```rust title="ord-trait" showLineNumbers +pub trait Ord { + fn cmp(self, other: Self) -> Ordering; +} +``` +> Source code: noir_stdlib/src/cmp.nr#L210-L214 + + +`a.cmp(b)` compares two values returning `Ordering::less()` if `a < b`, +`Ordering::equal()` if `a == b`, or `Ordering::greater()` if `a > b`. +Implementing this trait on a type allows `<`, `<=`, `>`, and `>=` to be +used on values of the type. + +`std::cmp` also provides `max` and `min` functions for any type which implements the `Ord` trait. + +Implementations: + +```rust +impl Ord for u8 { .. } +impl Ord for u16 { .. } +impl Ord for u32 { .. } +impl Ord for u64 { .. } + +impl Ord for i8 { .. } +impl Ord for i16 { .. } +impl Ord for i32 { .. } + +impl Ord for i64 { .. } + +impl Ord for () { .. } +impl Ord for bool { .. } + +impl Ord for [T; N] + where T: Ord { .. } + +impl Ord for [T] + where T: Ord { .. } + +impl Ord for (A, B) + where A: Ord, B: Ord { .. } + +impl Ord for (A, B, C) + where A: Ord, B: Ord, C: Ord { .. } + +impl Ord for (A, B, C, D) + where A: Ord, B: Ord, C: Ord, D: Ord { .. } + +impl Ord for (A, B, C, D, E) + where A: Ord, B: Ord, C: Ord, D: Ord, E: Ord { .. } +``` + +--- + +## `std::ops` + +### `std::ops::Add`, `std::ops::Sub`, `std::ops::Mul`, and `std::ops::Div` + +These traits abstract over addition, subtraction, multiplication, and division respectively. +Implementing these traits for a given type will also allow that type to be used with the corresponding operator +for that trait (`+` for Add, etc) in addition to the normal method names. + +```rust title="add-trait" showLineNumbers +pub trait Add { + fn add(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L1-L5 + +```rust title="sub-trait" showLineNumbers +pub trait Sub { + fn sub(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L60-L64 + +```rust title="mul-trait" showLineNumbers +pub trait Mul { + fn mul(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L119-L123 + +```rust title="div-trait" showLineNumbers +pub trait Div { + fn div(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L178-L182 + + +The implementations block below is given for the `Add` trait, but the same types that implement +`Add` also implement `Sub`, `Mul`, and `Div`. + +Implementations: +```rust +impl Add for Field { .. } + +impl Add for i8 { .. } +impl Add for i16 { .. } +impl Add for i32 { .. } +impl Add for i64 { .. } + +impl Add for u8 { .. } +impl Add for u16 { .. } +impl Add for u32 { .. } +impl Add for u64 { .. } +``` + +### `std::ops::Rem` + +```rust title="rem-trait" showLineNumbers +pub trait Rem { + fn rem(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L237-L241 + + +`Rem::rem(a, b)` is the remainder function returning the result of what is +left after dividing `a` and `b`. Implementing `Rem` allows the `%` operator +to be used with the implementation type. + +Unlike other numeric traits, `Rem` is not implemented for `Field`. + +Implementations: +```rust +impl Rem for u8 { fn rem(self, other: u8) -> u8 { self % other } } +impl Rem for u16 { fn rem(self, other: u16) -> u16 { self % other } } +impl Rem for u32 { fn rem(self, other: u32) -> u32 { self % other } } +impl Rem for u64 { fn rem(self, other: u64) -> u64 { self % other } } + +impl Rem for i8 { fn rem(self, other: i8) -> i8 { self % other } } +impl Rem for i16 { fn rem(self, other: i16) -> i16 { self % other } } +impl Rem for i32 { fn rem(self, other: i32) -> i32 { self % other } } +impl Rem for i64 { fn rem(self, other: i64) -> i64 { self % other } } +``` + +### `std::ops::Neg` + +```rust title="neg-trait" showLineNumbers +pub trait Neg { + fn neg(self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L290-L294 + + +`Neg::neg` is equivalent to the unary negation operator `-`. + +Implementations: +```rust title="neg-trait-impls" showLineNumbers +impl Neg for Field { + fn neg(self) -> Field { + -self + } +} + +impl Neg for i8 { + fn neg(self) -> i8 { + -self + } +} +impl Neg for i16 { + fn neg(self) -> i16 { + -self + } +} +impl Neg for i32 { + fn neg(self) -> i32 { + -self + } +} +impl Neg for i64 { + fn neg(self) -> i64 { + -self + } +} +``` +> Source code: noir_stdlib/src/ops/arith.nr#L296-L323 + + +### `std::ops::Not` + +```rust title="not-trait" showLineNumbers +pub trait Not { + fn not(self: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L1-L5 + + +`Not::not` is equivalent to the unary bitwise NOT operator `!`. + +Implementations: +```rust title="not-trait-impls" showLineNumbers +impl Not for bool { + fn not(self) -> bool { + !self + } +} + +impl Not for u64 { + fn not(self) -> u64 { + !self + } +} +impl Not for u32 { + fn not(self) -> u32 { + !self + } +} +impl Not for u16 { + fn not(self) -> u16 { + !self + } +} +impl Not for u8 { + fn not(self) -> u8 { + !self + } +} +impl Not for u1 { + fn not(self) -> u1 { + !self + } +} + +impl Not for i8 { + fn not(self) -> i8 { + !self + } +} +impl Not for i16 { + fn not(self) -> i16 { + !self + } +} +impl Not for i32 { + fn not(self) -> i32 { + !self + } +} +impl Not for i64 { + fn not(self) -> i64 { + !self + } +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L7-L60 + + +### `std::ops::{ BitOr, BitAnd, BitXor }` + +```rust title="bitor-trait" showLineNumbers +pub trait BitOr { + fn bitor(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L62-L66 + +```rust title="bitand-trait" showLineNumbers +pub trait BitAnd { + fn bitand(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L121-L125 + +```rust title="bitxor-trait" showLineNumbers +pub trait BitXor { + fn bitxor(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L180-L184 + + +Traits for the bitwise operations `|`, `&`, and `^`. + +Implementing `BitOr`, `BitAnd` or `BitXor` for a type allows the `|`, `&`, or `^` operator respectively +to be used with the type. + +The implementations block below is given for the `BitOr` trait, but the same types that implement +`BitOr` also implement `BitAnd` and `BitXor`. + +Implementations: +```rust +impl BitOr for bool { fn bitor(self, other: bool) -> bool { self | other } } + +impl BitOr for u8 { fn bitor(self, other: u8) -> u8 { self | other } } +impl BitOr for u16 { fn bitor(self, other: u16) -> u16 { self | other } } +impl BitOr for u32 { fn bitor(self, other: u32) -> u32 { self | other } } +impl BitOr for u64 { fn bitor(self, other: u64) -> u64 { self | other } } + +impl BitOr for i8 { fn bitor(self, other: i8) -> i8 { self | other } } +impl BitOr for i16 { fn bitor(self, other: i16) -> i16 { self | other } } +impl BitOr for i32 { fn bitor(self, other: i32) -> i32 { self | other } } +impl BitOr for i64 { fn bitor(self, other: i64) -> i64 { self | other } } +``` + +### `std::ops::{ Shl, Shr }` + +```rust title="shl-trait" showLineNumbers +pub trait Shl { + fn shl(self, other: u8) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L239-L243 + +```rust title="shr-trait" showLineNumbers +pub trait Shr { + fn shr(self, other: u8) -> Self; +} +``` +> Source code: noir_stdlib/src/ops/bit.nr#L292-L296 + + +Traits for a bit shift left and bit shift right. + +Implementing `Shl` for a type allows the left shift operator (`<<`) to be used with the implementation type. +Similarly, implementing `Shr` allows the right shift operator (`>>`) to be used with the type. + +Note that bit shifting is not currently implemented for signed types. + +The implementations block below is given for the `Shl` trait, but the same types that implement +`Shl` also implement `Shr`. + +Implementations: +```rust +impl Shl for u8 { fn shl(self, other: u8) -> u8 { self << other } } +impl Shl for u16 { fn shl(self, other: u16) -> u16 { self << other } } +impl Shl for u32 { fn shl(self, other: u32) -> u32 { self << other } } +impl Shl for u64 { fn shl(self, other: u64) -> u64 { self << other } } +``` + +--- + +## `std::append` + +### `std::append::Append` + +`Append` can abstract over types that can be appended to - usually container types: + +```rust title="append-trait" showLineNumbers +pub trait Append { + fn empty() -> Self; + fn append(self, other: Self) -> Self; +} +``` +> Source code: noir_stdlib/src/append.nr#L9-L14 + + +`Append` requires two methods: + +- `empty`: Constructs an empty value of `Self`. +- `append`: Append two values together, returning the result. + +Additionally, it is expected that for any implementation: + +- `T::empty().append(x) == x` +- `x.append(T::empty()) == x` + +Implementations: +```rust +impl Append for [T] +impl Append for Quoted +``` diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/.nojekyll b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md new file mode 100644 index 00000000000..252d72a0b71 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend.md @@ -0,0 +1,138 @@ +# BarretenbergBackend + +## Implements + +- [`Backend`](../index.md#backend) +- [`Backend`](../index.md#backend) + +## Constructors + +### new BarretenbergBackend(acirCircuit, options) + +```ts +new BarretenbergBackend(acirCircuit, options): BarretenbergBackend +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `acirCircuit` | `CompiledCircuit` | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`BarretenbergBackend`](BarretenbergBackend.md) + +## Properties + +| Property | Type | Description | +| :------ | :------ | :------ | +| `backend` | `UltraPlonkBackend` | - | + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +*** + +### generateProof() + +```ts +generateProof(compressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `compressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<`ProofData`\> + +#### Description + +Generates a proof + +*** + +### generateRecursiveProofArtifacts() + +```ts +generateRecursiveProofArtifacts(proofData, numOfPublicInputs): Promise +``` + +Generates artifacts that will be passed to a circuit that will verify this proof. + +Instead of passing the proof and verification key as a byte array, we pass them +as fields which makes it cheaper to verify in a circuit. + +The proof that is passed here will have been created using a circuit +that has the #[recursive] attribute on its `main` method. + +The number of public inputs denotes how many public inputs are in the inner proof. + +#### Parameters + +| Parameter | Type | Default value | +| :------ | :------ | :------ | +| `proofData` | `ProofData` | `undefined` | +| `numOfPublicInputs` | `number` | `0` | + +#### Returns + +`Promise`\<`object`\> + +#### Example + +```typescript +const artifacts = await backend.generateRecursiveProofArtifacts(proof, numOfPublicInputs); +``` + +*** + +### getVerificationKey() + +```ts +getVerificationKey(): Promise +``` + +#### Returns + +`Promise`\<`Uint8Array`\> + +*** + +### verifyProof() + +```ts +verifyProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies a proof + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md new file mode 100644 index 00000000000..500276ea748 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier.md @@ -0,0 +1,58 @@ +# BarretenbergVerifier + +## Constructors + +### new BarretenbergVerifier(options) + +```ts +new BarretenbergVerifier(options): BarretenbergVerifier +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`BarretenbergVerifier`](BarretenbergVerifier.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +*** + +### verifyProof() + +```ts +verifyProof(proofData, verificationKey): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | +| `verificationKey` | `Uint8Array` | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies a proof + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkBackend.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkBackend.md new file mode 100644 index 00000000000..204aaa18db6 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkBackend.md @@ -0,0 +1,114 @@ +# UltraHonkBackend + +## Implements + +- [`Backend`](../index.md#backend) +- [`Backend`](../index.md#backend) + +## Constructors + +### new UltraHonkBackend(acirCircuit, options) + +```ts +new UltraHonkBackend(acirCircuit, options): UltraHonkBackend +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `acirCircuit` | `CompiledCircuit` | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`UltraHonkBackend`](UltraHonkBackend.md) + +## Properties + +| Property | Type | Description | +| :------ | :------ | :------ | +| `backend` | `UltraHonkBackend` | - | + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +*** + +### generateProof() + +```ts +generateProof(compressedWitness): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `compressedWitness` | `Uint8Array` | + +#### Returns + +`Promise`\<`ProofData`\> + +*** + +### generateRecursiveProofArtifacts() + +```ts +generateRecursiveProofArtifacts(proofData, numOfPublicInputs): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | +| `numOfPublicInputs` | `number` | + +#### Returns + +`Promise`\<`object`\> + +*** + +### getVerificationKey() + +```ts +getVerificationKey(): Promise +``` + +#### Returns + +`Promise`\<`Uint8Array`\> + +*** + +### verifyProof() + +```ts +verifyProof(proofData): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | + +#### Returns + +`Promise`\<`boolean`\> + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkVerifier.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkVerifier.md new file mode 100644 index 00000000000..aee9460153f --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/classes/UltraHonkVerifier.md @@ -0,0 +1,58 @@ +# UltraHonkVerifier + +## Constructors + +### new UltraHonkVerifier(options) + +```ts +new UltraHonkVerifier(options): UltraHonkVerifier +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `options` | [`BackendOptions`](../type-aliases/BackendOptions.md) | + +#### Returns + +[`UltraHonkVerifier`](UltraHonkVerifier.md) + +## Methods + +### destroy() + +```ts +destroy(): Promise +``` + +#### Returns + +`Promise`\<`void`\> + +*** + +### verifyProof() + +```ts +verifyProof(proofData, verificationKey): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `proofData` | `ProofData` | +| `verificationKey` | `Uint8Array` | + +#### Returns + +`Promise`\<`boolean`\> + +#### Description + +Verifies a proof + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/index.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/index.md new file mode 100644 index 00000000000..4699e16dee6 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/index.md @@ -0,0 +1,42 @@ +# backend_barretenberg + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [BarretenbergBackend](classes/BarretenbergBackend.md) | - | +| [BarretenbergVerifier](classes/BarretenbergVerifier.md) | - | +| [UltraHonkBackend](classes/UltraHonkBackend.md) | - | +| [UltraHonkVerifier](classes/UltraHonkVerifier.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [BackendOptions](type-aliases/BackendOptions.md) | - | + +## References + +### CompiledCircuit + +Renames and re-exports [Backend](index.md#backend) + +*** + +### ProofData + +Renames and re-exports [Backend](index.md#backend) + +## Variables + +### Backend + +```ts +Backend: any; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md new file mode 100644 index 00000000000..1837bd4e205 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions.md @@ -0,0 +1,19 @@ +# BackendOptions + +```ts +type BackendOptions: object; +``` + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `crsPath` | `string` | **Description**

Path to download CRS files | +| `memory` | `object` | **Description**

Initial and Maximum memory to be alloted to the backend worker | +| `memory.initial` | `number` | - | +| `memory.maximum` | `number` | - | +| `threads` | `number` | **Description**

Number of threads to run the backend worker on | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs new file mode 100644 index 00000000000..8ecf05c0163 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/backend_barretenberg/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/BarretenbergBackend","label":"BarretenbergBackend"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/BarretenbergVerifier","label":"BarretenbergVerifier"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/UltraHonkBackend","label":"UltraHonkBackend"},{"type":"doc","id":"reference/NoirJS/backend_barretenberg/classes/UltraHonkVerifier","label":"UltraHonkVerifier"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/backend_barretenberg/type-aliases/BackendOptions","label":"BackendOptions"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/.nojekyll b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/classes/Noir.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/classes/Noir.md new file mode 100644 index 00000000000..ead255bc504 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/classes/Noir.md @@ -0,0 +1,52 @@ +# Noir + +## Constructors + +### new Noir(circuit) + +```ts +new Noir(circuit): Noir +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `circuit` | `CompiledCircuit` | + +#### Returns + +[`Noir`](Noir.md) + +## Methods + +### execute() + +```ts +execute(inputs, foreignCallHandler?): Promise +``` + +#### Parameters + +| Parameter | Type | +| :------ | :------ | +| `inputs` | `InputMap` | +| `foreignCallHandler`? | [`ForeignCallHandler`](../type-aliases/ForeignCallHandler.md) | + +#### Returns + +`Promise`\<`object`\> + +#### Description + +Allows to execute a circuit to get its witness and return value. + +#### Example + +```typescript +async execute(inputs) +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/and.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/and.md new file mode 100644 index 00000000000..c783283e396 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/and.md @@ -0,0 +1,22 @@ +# and() + +```ts +and(lhs, rhs): string +``` + +Performs a bitwise AND operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/blake2s256.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/blake2s256.md new file mode 100644 index 00000000000..7882d0da8d5 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/blake2s256.md @@ -0,0 +1,21 @@ +# blake2s256() + +```ts +blake2s256(inputs): Uint8Array +``` + +Calculates the Blake2s256 hash of the input bytes + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `inputs` | `Uint8Array` | | + +## Returns + +`Uint8Array` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md new file mode 100644 index 00000000000..5e3cd53e9d3 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify.md @@ -0,0 +1,28 @@ +# ecdsa\_secp256k1\_verify() + +```ts +ecdsa_secp256k1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Verifies a ECDSA signature over the secp256k1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md new file mode 100644 index 00000000000..0b20ff68957 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify.md @@ -0,0 +1,28 @@ +# ecdsa\_secp256r1\_verify() + +```ts +ecdsa_secp256r1_verify( + hashed_msg, + public_key_x_bytes, + public_key_y_bytes, + signature): boolean +``` + +Verifies a ECDSA signature over the secp256r1 curve. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `hashed_msg` | `Uint8Array` | | +| `public_key_x_bytes` | `Uint8Array` | | +| `public_key_y_bytes` | `Uint8Array` | | +| `signature` | `Uint8Array` | | + +## Returns + +`boolean` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/xor.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/xor.md new file mode 100644 index 00000000000..8d762b895d3 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/functions/xor.md @@ -0,0 +1,22 @@ +# xor() + +```ts +xor(lhs, rhs): string +``` + +Performs a bitwise XOR operation between `lhs` and `rhs` + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `lhs` | `string` | | +| `rhs` | `string` | | + +## Returns + +`string` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/index.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/index.md new file mode 100644 index 00000000000..4de7a696991 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/index.md @@ -0,0 +1,47 @@ +# noir_js + +## Exports + +### Classes + +| Class | Description | +| :------ | :------ | +| [Noir](classes/Noir.md) | - | + +### Type Aliases + +| Type alias | Description | +| :------ | :------ | +| [ErrorWithPayload](type-aliases/ErrorWithPayload.md) | - | +| [ForeignCallHandler](type-aliases/ForeignCallHandler.md) | A callback which performs an foreign call and returns the response. | +| [ForeignCallInput](type-aliases/ForeignCallInput.md) | - | +| [ForeignCallOutput](type-aliases/ForeignCallOutput.md) | - | +| [WitnessMap](type-aliases/WitnessMap.md) | - | + +### Functions + +| Function | Description | +| :------ | :------ | +| [and](functions/and.md) | Performs a bitwise AND operation between `lhs` and `rhs` | +| [blake2s256](functions/blake2s256.md) | Calculates the Blake2s256 hash of the input bytes | +| [ecdsa\_secp256k1\_verify](functions/ecdsa_secp256k1_verify.md) | Verifies a ECDSA signature over the secp256k1 curve. | +| [ecdsa\_secp256r1\_verify](functions/ecdsa_secp256r1_verify.md) | Verifies a ECDSA signature over the secp256r1 curve. | +| [xor](functions/xor.md) | Performs a bitwise XOR operation between `lhs` and `rhs` | + +## References + +### CompiledCircuit + +Renames and re-exports [InputMap](index.md#inputmap) + +## Variables + +### InputMap + +```ts +InputMap: any; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md new file mode 100644 index 00000000000..e8c2f4aef3d --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ErrorWithPayload.md @@ -0,0 +1,15 @@ +# ErrorWithPayload + +```ts +type ErrorWithPayload: ExecutionError & object; +``` + +## Type declaration + +| Member | Type | Description | +| :------ | :------ | :------ | +| `decodedAssertionPayload` | `any` | - | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md new file mode 100644 index 00000000000..812b8b16481 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallHandler.md @@ -0,0 +1,24 @@ +# ForeignCallHandler + +```ts +type ForeignCallHandler: (name, inputs) => Promise; +``` + +A callback which performs an foreign call and returns the response. + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | The identifier for the type of foreign call being performed. | +| `inputs` | [`ForeignCallInput`](ForeignCallInput.md)[] | An array of hex encoded inputs to the foreign call. | + +## Returns + +`Promise`\<[`ForeignCallOutput`](ForeignCallOutput.md)[]\> + +outputs - An array of hex encoded outputs containing the results of the foreign call. + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md new file mode 100644 index 00000000000..dd95809186a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallInput.md @@ -0,0 +1,9 @@ +# ForeignCallInput + +```ts +type ForeignCallInput: string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md new file mode 100644 index 00000000000..b71fb78a946 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/ForeignCallOutput.md @@ -0,0 +1,9 @@ +# ForeignCallOutput + +```ts +type ForeignCallOutput: string | string[]; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md new file mode 100644 index 00000000000..258c46f9d0c --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/type-aliases/WitnessMap.md @@ -0,0 +1,9 @@ +# WitnessMap + +```ts +type WitnessMap: Map; +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs new file mode 100644 index 00000000000..4796b5abaa8 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_js/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"category","label":"Classes","items":[{"type":"doc","id":"reference/NoirJS/noir_js/classes/Noir","label":"Noir"}]},{"type":"category","label":"Type Aliases","items":[{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ErrorWithPayload","label":"ErrorWithPayload"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallHandler","label":"ForeignCallHandler"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallInput","label":"ForeignCallInput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/ForeignCallOutput","label":"ForeignCallOutput"},{"type":"doc","id":"reference/NoirJS/noir_js/type-aliases/WitnessMap","label":"WitnessMap"}]},{"type":"category","label":"Functions","items":[{"type":"doc","id":"reference/NoirJS/noir_js/functions/and","label":"and"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/blake2s256","label":"blake2s256"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256k1_verify","label":"ecdsa_secp256k1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/ecdsa_secp256r1_verify","label":"ecdsa_secp256r1_verify"},{"type":"doc","id":"reference/NoirJS/noir_js/functions/xor","label":"xor"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/.nojekyll b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/.nojekyll new file mode 100644 index 00000000000..e2ac6616add --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile.md new file mode 100644 index 00000000000..6faf763b37f --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile.md @@ -0,0 +1,51 @@ +# compile() + +```ts +compile( + fileManager, + projectPath?, + logFn?, +debugLogFn?): Promise +``` + +Compiles a Noir project + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `fileManager` | `FileManager` | The file manager to use | +| `projectPath`? | `string` | The path to the project inside the file manager. Defaults to the root of the file manager | +| `logFn`? | `LogFn` | A logging function. If not provided, console.log will be used | +| `debugLogFn`? | `LogFn` | A debug logging function. If not provided, logFn will be used | + +## Returns + +`Promise`\<[`ProgramCompilationArtifacts`](../index.md#programcompilationartifacts)\> + +## Example + +```typescript +// Node.js + +import { compile_program, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager(myProjectPath); +const myCompiledCode = await compile_program(fm); +``` + +```typescript +// Browser + +import { compile_program, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager('/'); +for (const path of files) { + await fm.writeFile(path, await getFileAsStream(path)); +} +const myCompiledCode = await compile_program(fm); +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile_contract.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile_contract.md new file mode 100644 index 00000000000..7d0b39a43ef --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/compile_contract.md @@ -0,0 +1,51 @@ +# compile\_contract() + +```ts +compile_contract( + fileManager, + projectPath?, + logFn?, +debugLogFn?): Promise +``` + +Compiles a Noir project + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `fileManager` | `FileManager` | The file manager to use | +| `projectPath`? | `string` | The path to the project inside the file manager. Defaults to the root of the file manager | +| `logFn`? | `LogFn` | A logging function. If not provided, console.log will be used | +| `debugLogFn`? | `LogFn` | A debug logging function. If not provided, logFn will be used | + +## Returns + +`Promise`\<[`ContractCompilationArtifacts`](../index.md#contractcompilationartifacts)\> + +## Example + +```typescript +// Node.js + +import { compile_contract, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager(myProjectPath); +const myCompiledCode = await compile_contract(fm); +``` + +```typescript +// Browser + +import { compile_contract, createFileManager } from '@noir-lang/noir_wasm'; + +const fm = createFileManager('/'); +for (const path of files) { + await fm.writeFile(path, await getFileAsStream(path)); +} +const myCompiledCode = await compile_contract(fm); +``` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/createFileManager.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/createFileManager.md new file mode 100644 index 00000000000..7e65c1d69c7 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/createFileManager.md @@ -0,0 +1,21 @@ +# createFileManager() + +```ts +createFileManager(dataDir): FileManager +``` + +Creates a new FileManager instance based on fs in node and memfs in the browser (via webpack alias) + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `dataDir` | `string` | root of the file system | + +## Returns + +`FileManager` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md new file mode 100644 index 00000000000..fcea9275341 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/functions/inflateDebugSymbols.md @@ -0,0 +1,21 @@ +# inflateDebugSymbols() + +```ts +inflateDebugSymbols(debugSymbols): any +``` + +Decompresses and decodes the debug symbols + +## Parameters + +| Parameter | Type | Description | +| :------ | :------ | :------ | +| `debugSymbols` | `string` | The base64 encoded debug symbols | + +## Returns + +`any` + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/index.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/index.md new file mode 100644 index 00000000000..b6e0f9d1bc0 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/index.md @@ -0,0 +1,49 @@ +# noir_wasm + +## Exports + +### Functions + +| Function | Description | +| :------ | :------ | +| [compile](functions/compile.md) | Compiles a Noir project | +| [compile\_contract](functions/compile_contract.md) | Compiles a Noir project | +| [createFileManager](functions/createFileManager.md) | Creates a new FileManager instance based on fs in node and memfs in the browser (via webpack alias) | +| [inflateDebugSymbols](functions/inflateDebugSymbols.md) | Decompresses and decodes the debug symbols | + +## References + +### compile\_program + +Renames and re-exports [compile](functions/compile.md) + +## Interfaces + +### ContractCompilationArtifacts + +The compilation artifacts of a given contract. + +#### Properties + +| Property | Type | Description | +| :------ | :------ | :------ | +| `contract` | `ContractArtifact` | The compiled contract. | +| `warnings` | `unknown`[] | Compilation warnings. | + +*** + +### ProgramCompilationArtifacts + +The compilation artifacts of a given program. + +#### Properties + +| Property | Type | Description | +| :------ | :------ | :------ | +| `name` | `string` | not part of the compilation output, injected later | +| `program` | `ProgramArtifact` | The compiled contract. | +| `warnings` | `unknown`[] | Compilation warnings. | + +*** + +Generated using [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) and [TypeDoc](https://typedoc.org/) diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs new file mode 100644 index 00000000000..e0870710349 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/NoirJS/noir_wasm/typedoc-sidebar.cjs @@ -0,0 +1,4 @@ +// @ts-check +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const typedocSidebar = { items: [{"type":"doc","id":"reference/NoirJS/noir_wasm/index","label":"API"},{"type":"category","label":"Functions","items":[{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/compile","label":"compile"},{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/compile_contract","label":"compile_contract"},{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/createFileManager","label":"createFileManager"},{"type":"doc","id":"reference/NoirJS/noir_wasm/functions/inflateDebugSymbols","label":"inflateDebugSymbols"}]}]}; +module.exports = typedocSidebar.items; \ No newline at end of file diff --git a/noir/noir-repo/docs/docs/getting_started/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/_category_.json similarity index 72% rename from noir/noir-repo/docs/docs/getting_started/_category_.json rename to noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/_category_.json index 5d694210bbf..5b6a20a609a 100644 --- a/noir/noir-repo/docs/docs/getting_started/_category_.json +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/_category_.json @@ -1,5 +1,5 @@ { - "position": 0, + "position": 4, "collapsible": true, "collapsed": true } diff --git a/noir/noir-repo/docs/docs/getting_started/backend/_category_.json b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/_category_.json similarity index 63% rename from noir/noir-repo/docs/docs/getting_started/backend/_category_.json rename to noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/_category_.json index b82e92beb0c..27869205ad3 100644 --- a/noir/noir-repo/docs/docs/getting_started/backend/_category_.json +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/_category_.json @@ -1,6 +1,6 @@ { + "label": "Debugger", "position": 1, - "label": "Install Proving Backend", "collapsible": true, "collapsed": true } diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_known_limitations.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_known_limitations.md new file mode 100644 index 00000000000..936d416ac4b --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_known_limitations.md @@ -0,0 +1,59 @@ +--- +title: Known limitations +description: + An overview of known limitations of the current version of the Noir debugger +keywords: + [ + Nargo, + Noir Debugger, + VS Code, + ] +sidebar_position: 2 +--- + +# Debugger Known Limitations + +There are currently some limits to what the debugger can observe. + +## Mutable references + +The debugger is currently blind to any state mutated via a mutable reference. For example, in: + +``` +let mut x = 1; +let y = &mut x; +*y = 2; +``` + +The update on `x` will not be observed by the debugger. That means, when running `vars` from the debugger REPL, or inspecting the _local variables_ pane in the VS Code debugger, `x` will appear with value 1 despite having executed `*y = 2;`. + +## Variables of type function or mutable references are opaque + +When inspecting variables, any variable of type `Function` or `MutableReference` will render its value as `<>` or `<>`. + +## Debugger instrumentation affects resulting ACIR + +In order to make the state of local variables observable, the debugger compiles Noir circuits interleaving foreign calls that track any mutations to them. While this works (except in the cases described above) and doesn't introduce any behavior changes, it does as a side effect produce bigger bytecode. In particular, when running the command `opcodes` on the REPL debugger, you will notice Unconstrained VM blocks that look like this: + +``` +... +5 BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [], q_c: 2 }), Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(2))], q_c: 0 })] + | outputs=[] + 5.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 5.1 | Mov { destination: RegisterIndex(3), source: RegisterIndex(1) } + 5.2 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 5.3 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 5.4 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 5.5 | Mov { destination: RegisterIndex(3), source: RegisterIndex(3) } + 5.6 | Call { location: 8 } + 5.7 | Stop + 5.8 | ForeignCall { function: "__debug_var_assign", destinations: [], inputs: [RegisterIndex(RegisterIndex(2)), RegisterIndex(RegisterIndex(3))] } +... +``` + +If you are interested in debugging/inspecting compiled ACIR without these synthetic changes, you can invoke the REPL debugger with the `--skip-instrumentation` flag or launch the VS Code debugger with the `skipConfiguration` property set to true in its launch configuration. You can find more details about those in the [Debugger REPL reference](debugger_repl.md) and the [VS Code Debugger reference](debugger_vscode.md). + +:::note +Skipping debugger instrumentation means you won't be able to inspect values of local variables. +::: + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_repl.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_repl.md new file mode 100644 index 00000000000..46e2011304e --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_repl.md @@ -0,0 +1,360 @@ +--- +title: REPL Debugger +description: + Noir Debugger REPL options and commands. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + REPL, + ] +sidebar_position: 1 +--- + +## Running the REPL debugger + +`nargo debug [OPTIONS] [WITNESS_NAME]` + +Runs the Noir REPL debugger. If a `WITNESS_NAME` is provided the debugger writes the resulting execution witness to a `WITNESS_NAME` file. + +### Options + +| Option | Description | +| --------------------- | ------------------------------------------------------------ | +| `-p, --prover-name ` | The name of the toml file which contains the inputs for the prover [default: Prover]| +| `--package ` | The name of the package to debug | +| `--print-acir` | Display the ACIR for compiled circuit | +| `--deny-warnings` | Treat all warnings as errors | +| `--silence-warnings` | Suppress warnings | +| `-h, --help` | Print help | + +None of these options are required. + +:::note +Since the debugger starts by compiling the target package, all Noir compiler options are also available. Check out the [compiler reference](../nargo_commands.md#nargo-compile) to learn more about the compiler options. +::: + +## REPL commands + +Once the debugger is running, it accepts the following commands. + +#### `help` (h) + +Displays the menu of available commands. + +``` +> help +Available commands: + + opcodes display ACIR opcodes + into step into to the next opcode + next step until a new source location is reached + out step until a new source location is reached + and the current stack frame is finished + break LOCATION:OpcodeLocation add a breakpoint at an opcode location + over step until a new source location is reached + without diving into function calls + restart restart the debugging session + delete LOCATION:OpcodeLocation delete breakpoint at an opcode location + witness show witness map + witness index:u32 display a single witness from the witness map + witness index:u32 value:String update a witness with the given value + memset index:usize value:String update a memory cell with the given + value + continue continue execution until the end of the + program + vars show variable values available at this point + in execution + stacktrace display the current stack trace + memory show memory (valid when executing unconstrained code) value + step step to the next ACIR opcode + +Other commands: + + help Show this help message + quit Quit repl + +``` + +### Stepping through programs + +#### `next` (n) + +Step until the next Noir source code location. While other commands, such as [`into`](#into-i) and [`step`](#step-s), allow for finer grained control of the program's execution at the opcode level, `next` is source code centric. For example: + +``` +3 ... +4 fn main(x: u32) { +5 assert(entry_point(x) == 2); +6 swap_entry_point(x, x + 1); +7 -> assert(deep_entry_point(x) == 4); +8 multiple_values_entry_point(x); +9 } +``` + + +Using `next` here would cause the debugger to jump to the definition of `deep_entry_point` (if available). + +If you want to step over `deep_entry_point` and go straight to line 8, use [the `over` command](#over) instead. + +#### `over` + +Step until the next source code location, without diving into function calls. For example: + +``` +3 ... +4 fn main(x: u32) { +5 assert(entry_point(x) == 2); +6 swap_entry_point(x, x + 1); +7 -> assert(deep_entry_point(x) == 4); +8 multiple_values_entry_point(x); +9 } +``` + + +Using `over` here would cause the debugger to execute until line 8 (`multiple_values_entry_point(x);`). + +If you want to step into `deep_entry_point` instead, use [the `next` command](#next-n). + +#### `out` + +Step until the end of the current function call. For example: + +``` + 3 ... + 4 fn main(x: u32) { + 5 assert(entry_point(x) == 2); + 6 swap_entry_point(x, x + 1); + 7 -> assert(deep_entry_point(x) == 4); + 8 multiple_values_entry_point(x); + 9 } + 10 + 11 unconstrained fn returns_multiple_values(x: u32) -> (u32, u32, u32, u32) { + 12 ... + ... + 55 + 56 unconstrained fn deep_entry_point(x: u32) -> u32 { + 57 -> level_1(x + 1) + 58 } + +``` + +Running `out` here will resume execution until line 8. + +#### `step` (s) + +Skips to the next ACIR code. A compiled Noir program is a sequence of ACIR opcodes. However, an unconstrained VM opcode denotes the start of an unconstrained code block, to be executed by the unconstrained VM. For example (redacted for brevity): + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +The `->` here shows the debugger paused at an ACIR opcode: `BRILLIG`, at index 1, which denotes an unconstrained code block is about to start. + +Using the `step` command at this point would result in the debugger stopping at ACIR opcode 2, `EXPR`, skipping unconstrained computation steps. + +Use [the `into` command](#into-i) instead if you want to follow unconstrained computation step by step. + +#### `into` (i) + +Steps into the next opcode. A compiled Noir program is a sequence of ACIR opcodes. However, a BRILLIG opcode denotes the start of an unconstrained code block, to be executed by the unconstrained VM. For example (redacted for brevity): + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +The `->` here shows the debugger paused at an ACIR opcode: `BRILLIG`, at index 1, which denotes an unconstrained code block is about to start. + +Using the `into` command at this point would result in the debugger stopping at opcode 1.0, `Mov ...`, allowing the debugger user to follow unconstrained computation step by step. + +Use [the `step` command](#step-s) instead if you want to skip to the next ACIR code directly. + +#### `continue` (c) + +Continues execution until the next breakpoint, or the end of the program. + +#### `restart` (res) + +Interrupts execution, and restarts a new debugging session from scratch. + +#### `opcodes` (o) + +Display the program's ACIR opcode sequence. For example: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +### Breakpoints + +#### `break [Opcode]` (or shorthand `b [Opcode]`) + +Sets a breakpoint on the specified opcode index. To get a list of the program opcode numbers, see [the `opcode` command](#opcodes-o). For example: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +In this example, issuing a `break 1.2` command adds break on opcode 1.2, as denoted by the `*` character: + +``` +0 BLACKBOX::RANGE [(_0, num_bits: 32)] [ ] +1 -> BRILLIG inputs=[Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })] outputs=[Simple(Witness(1))] + 1.0 | Mov { destination: RegisterIndex(2), source: RegisterIndex(0) } + 1.1 | Const { destination: RegisterIndex(0), value: Value { inner: 0 } } + 1.2 | * Const { destination: RegisterIndex(1), value: Value { inner: 0 } } + 1.3 | Mov { destination: RegisterIndex(2), source: RegisterIndex(2) } + 1.4 | Call { location: 7 } + ... + 1.43 | Return +2 EXPR [ (1, _1) -2 ] +``` + +Running [the `continue` command](#continue-c) at this point would cause the debugger to execute the program until opcode 1.2. + +#### `delete [Opcode]` (or shorthand `d [Opcode]`) + +Deletes a breakpoint at an opcode location. Usage is analogous to [the `break` command](#). + +### Variable inspection + +#### vars + +Show variable values available at this point in execution. + +:::note +The ability to inspect variable values from the debugger depends on compilation to be run in a special debug instrumentation mode. This instrumentation weaves variable tracing code with the original source code. + +So variable value inspection comes at the expense of making the resulting ACIR bytecode bigger and harder to understand and optimize. + +If you find this compromise unacceptable, you can run the debugger with the flag `--skip-debug-instrumentation`. This will compile your circuit without any additional debug information, so the resulting ACIR bytecode will be identical to the one produced by standard Noir compilation. However, if you opt for this, the `vars` command will not be available while debugging. +::: + + +### Stacktrace + +#### `stacktrace` + +Displays the current stack trace. + + +### Witness map + +#### `witness` (w) + +Show witness map. For example: + +``` +_0 = 0 +_1 = 2 +_2 = 1 +``` + +#### `witness [Witness Index]` + +Display a single witness from the witness map. For example: + +``` +> witness 1 +_1 = 2 +``` + +#### `witness [Witness Index] [New value]` + +Overwrite the given index with a new value. For example: + +``` +> witness 1 3 +_1 = 3 +``` + + +### Unconstrained VM memory + +#### `memory` + +Show unconstrained VM memory state. For example: + +``` +> memory +At opcode 1.13: Store { destination_pointer: RegisterIndex(0), source: RegisterIndex(3) } +... +> registers +0 = 0 +1 = 10 +2 = 0 +3 = 1 +4 = 1 +5 = 2³² +6 = 1 +> into +At opcode 1.14: Const { destination: RegisterIndex(5), value: Value { inner: 1 } } +... +> memory +0 = 1 +> +``` + +In the example above: we start with clean memory, then step through a `Store` opcode which stores the value of register 3 (1) into the memory address stored in register 0 (0). Thus now `memory` shows memory address 0 contains value 1. + +:::note +This command is only functional while the debugger is executing unconstrained code. +::: + +#### `memset [Memory address] [New value]` + +Update a memory cell with the given value. For example: + +``` +> memory +0 = 1 +> memset 0 2 +> memory +0 = 2 +> memset 1 4 +> memory +0 = 2 +1 = 4 +> +``` + +:::note +This command is only functional while the debugger is executing unconstrained code. +::: \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_vscode.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_vscode.md new file mode 100644 index 00000000000..c027332b3b0 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/debugger/debugger_vscode.md @@ -0,0 +1,82 @@ +--- +title: VS Code Debugger +description: + VS Code Debugger configuration and features. +keywords: + [ + Nargo, + Noir CLI, + Noir Debugger, + VS Code, + IDE, + ] +sidebar_position: 0 +--- + +# VS Code Noir Debugger Reference + +The Noir debugger enabled by the vscode-noir extension ships with default settings such that the most common scenario should run without any additional configuration steps. + +These defaults can nevertheless be overridden by defining a launch configuration file. This page provides a reference for the properties you can override via a launch configuration file, as well as documenting the Nargo `dap` command, which is a dependency of the VS Code Noir debugger. + + +## Creating and editing launch configuration files + +To create a launch configuration file from VS Code, open the _debug pane_, and click on _create a launch.json file_. + +![Creating a launch configuration file](@site/static/img/debugger/ref1-create-launch.png) + +A `launch.json` file will be created, populated with basic defaults. + +### Noir Debugger launch.json properties + +#### projectFolder + +_String, optional._ + +Absolute path to the Nargo project to debug. By default, it is dynamically determined by looking for the nearest `Nargo.toml` file to the active file at the moment of launching the debugger. + +#### proverName + +_String, optional._ + +Name of the prover input to use. Defaults to `Prover`, which looks for a file named `Prover.toml` at the `projectFolder`. + +#### generateAcir + +_Boolean, optional._ + +If true, generate ACIR opcodes instead of unconstrained opcodes which will be closer to release binaries but less convenient for debugging. Defaults to `false`. + +#### skipInstrumentation + +_Boolean, optional._ + +Skips variables debugging instrumentation of code, making debugging less convenient but the resulting binary smaller and closer to production. Defaults to `false`. + +:::note +Skipping instrumentation causes the debugger to be unable to inspect local variables. +::: + +## `nargo dap [OPTIONS]` + +When run without any option flags, it starts the Nargo Debug Adapter Protocol server, which acts as the debugging backend for the VS Code Noir Debugger. + +All option flags are related to preflight checks. The Debug Adapter Protocol specifies how errors are to be informed from a running DAP server, but it doesn't specify mechanisms to communicate server initialization errors between the DAP server and its client IDE. + +Thus `nargo dap` ships with a _preflight check_ mode. If flag `--preflight-check` and the rest of the `--preflight-*` flags are provided, Nargo will run the same initialization routine except it will not start the DAP server. + +`vscode-noir` will then run `nargo dap` in preflight check mode first before a debugging session starts. If the preflight check ends in error, vscode-noir will present stderr and stdout output from this process through its own Output pane in VS Code. This makes it possible for users to diagnose what pieces of configuration might be wrong or missing in case of initialization errors. + +If the preflight check succeeds, `vscode-noir` proceeds to start the DAP server normally but running `nargo dap` without any additional flags. + +### Options + +| Option | Description | +| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `--preflight-check` | If present, dap runs in preflight check mode. | +| `--preflight-project-folder ` | Absolute path to the project to debug for preflight check. | +| `--preflight-prover-name ` | Name of prover file to use for preflight check | +| `--preflight-generate-acir` | Optional. If present, compile in ACIR mode while running preflight check. | +| `--preflight-skip-instrumentation` | Optional. If present, compile without introducing debug instrumentation while running preflight check. | +| `-h, --help` | Print help. | diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/nargo_commands.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/nargo_commands.md new file mode 100644 index 00000000000..db1884afee2 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/nargo_commands.md @@ -0,0 +1,297 @@ +--- +title: Nargo +description: + Noir CLI Commands for Noir Prover and Verifier to create, execute, prove and verify programs, + generate Solidity verifier smart contract and compile into JSON file containing ACIR + representation and ABI of circuit. +keywords: + [ + Nargo, + Noir CLI, + Noir Prover, + Noir Verifier, + generate Solidity verifier, + compile JSON file, + ACIR representation, + ABI of circuit, + TypeScript, + ] +sidebar_position: 0 +--- + +# Command-Line Help for `nargo` + +This document contains the help content for the `nargo` command-line program. + +**Command Overview:** + +* [`nargo`↴](#nargo) +* [`nargo check`↴](#nargo-check) +* [`nargo fmt`↴](#nargo-fmt) +* [`nargo compile`↴](#nargo-compile) +* [`nargo new`↴](#nargo-new) +* [`nargo init`↴](#nargo-init) +* [`nargo execute`↴](#nargo-execute) +* [`nargo debug`↴](#nargo-debug) +* [`nargo test`↴](#nargo-test) +* [`nargo info`↴](#nargo-info) +* [`nargo lsp`↴](#nargo-lsp) + +## `nargo` + +Noir's package manager + +**Usage:** `nargo ` + +###### **Subcommands:** + +* `check` — Checks the constraint system for errors +* `fmt` — Format the Noir files in a workspace +* `compile` — Compile the program and its secret execution trace into ACIR format +* `new` — Create a Noir project in a new directory +* `init` — Create a Noir project in the current directory +* `execute` — Executes a circuit to calculate its return value +* `debug` — Executes a circuit in debug mode +* `test` — Run the tests for this program +* `info` — Provides detailed information on each of a program's function (represented by a single circuit) +* `lsp` — Starts the Noir LSP server + +###### **Options:** + + + + +## `nargo check` + +Checks the constraint system for errors + +**Usage:** `nargo check [OPTIONS]` + +###### **Options:** + +* `--package ` — The name of the package to check +* `--workspace` — Check all packages in the workspace +* `--overwrite` — Force overwrite of existing files +* `--expression-width ` — Specify the backend expression width that should be targeted +* `--bounded-codegen` — Generate ACIR with the target backend expression width. The default is to generate ACIR without a bound and split expressions after code generation. Activating this flag can sometimes provide optimizations for certain programs + + Default value: `false` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--debug-comptime-in-file ` — Enable printing results of comptime evaluation: provide a path suffix for the module to debug, e.g. "package_name/src/main.nr" +* `--skip-underconstrained-check` — Flag to turn off the compiler check for under constrained values. Warning: This can improve compilation speed but can also lead to correctness errors. This check should always be run on production code + + + +## `nargo fmt` + +Format the Noir files in a workspace + +**Usage:** `nargo fmt [OPTIONS]` + +###### **Options:** + +* `--check` — Run noirfmt in check mode + + + +## `nargo compile` + +Compile the program and its secret execution trace into ACIR format + +**Usage:** `nargo compile [OPTIONS]` + +###### **Options:** + +* `--package ` — The name of the package to compile +* `--workspace` — Compile all packages in the workspace +* `--expression-width ` — Specify the backend expression width that should be targeted +* `--bounded-codegen` — Generate ACIR with the target backend expression width. The default is to generate ACIR without a bound and split expressions after code generation. Activating this flag can sometimes provide optimizations for certain programs + + Default value: `false` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--debug-comptime-in-file ` — Enable printing results of comptime evaluation: provide a path suffix for the module to debug, e.g. "package_name/src/main.nr" +* `--skip-underconstrained-check` — Flag to turn off the compiler check for under constrained values. Warning: This can improve compilation speed but can also lead to correctness errors. This check should always be run on production code + + + +## `nargo new` + +Create a Noir project in a new directory + +**Usage:** `nargo new [OPTIONS] ` + +###### **Arguments:** + +* `` — The path to save the new project + +###### **Options:** + +* `--name ` — Name of the package [default: package directory name] +* `--lib` — Use a library template +* `--bin` — Use a binary template [default] +* `--contract` — Use a contract template + + + +## `nargo init` + +Create a Noir project in the current directory + +**Usage:** `nargo init [OPTIONS]` + +###### **Options:** + +* `--name ` — Name of the package [default: current directory name] +* `--lib` — Use a library template +* `--bin` — Use a binary template [default] +* `--contract` — Use a contract template + + + +## `nargo execute` + +Executes a circuit to calculate its return value + +**Usage:** `nargo execute [OPTIONS] [WITNESS_NAME]` + +###### **Arguments:** + +* `` — Write the execution witness to named file + +Defaults to the name of the package being executed. + +###### **Options:** + +* `-p`, `--prover-name ` — The name of the toml file which contains the inputs for the prover + + Default value: `Prover` +* `--package ` — The name of the package to execute +* `--workspace` — Execute all packages in the workspace +* `--expression-width ` — Specify the backend expression width that should be targeted +* `--bounded-codegen` — Generate ACIR with the target backend expression width. The default is to generate ACIR without a bound and split expressions after code generation. Activating this flag can sometimes provide optimizations for certain programs + + Default value: `false` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--debug-comptime-in-file ` — Enable printing results of comptime evaluation: provide a path suffix for the module to debug, e.g. "package_name/src/main.nr" +* `--skip-underconstrained-check` — Flag to turn off the compiler check for under constrained values. Warning: This can improve compilation speed but can also lead to correctness errors. This check should always be run on production code +* `--oracle-resolver ` — JSON RPC url to solve oracle calls + + + +## `nargo debug` + +Executes a circuit in debug mode + +**Usage:** `nargo debug [OPTIONS] [WITNESS_NAME]` + +###### **Arguments:** + +* `` — Write the execution witness to named file + +###### **Options:** + +* `-p`, `--prover-name ` — The name of the toml file which contains the inputs for the prover + + Default value: `Prover` +* `--package ` — The name of the package to execute +* `--expression-width ` — Specify the backend expression width that should be targeted +* `--bounded-codegen` — Generate ACIR with the target backend expression width. The default is to generate ACIR without a bound and split expressions after code generation. Activating this flag can sometimes provide optimizations for certain programs + + Default value: `false` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--debug-comptime-in-file ` — Enable printing results of comptime evaluation: provide a path suffix for the module to debug, e.g. "package_name/src/main.nr" +* `--skip-underconstrained-check` — Flag to turn off the compiler check for under constrained values. Warning: This can improve compilation speed but can also lead to correctness errors. This check should always be run on production code +* `--acir-mode` — Force ACIR output (disabling instrumentation) +* `--skip-instrumentation ` — Disable vars debug instrumentation (enabled by default) + + Possible values: `true`, `false` + + + + +## `nargo test` + +Run the tests for this program + +**Usage:** `nargo test [OPTIONS] [TEST_NAME]` + +###### **Arguments:** + +* `` — If given, only tests with names containing this string will be run + +###### **Options:** + +* `--show-output` — Display output of `println` statements +* `--exact` — Only run tests that match exactly +* `--package ` — The name of the package to test +* `--workspace` — Test all packages in the workspace +* `--expression-width ` — Specify the backend expression width that should be targeted +* `--bounded-codegen` — Generate ACIR with the target backend expression width. The default is to generate ACIR without a bound and split expressions after code generation. Activating this flag can sometimes provide optimizations for certain programs + + Default value: `false` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--debug-comptime-in-file ` — Enable printing results of comptime evaluation: provide a path suffix for the module to debug, e.g. "package_name/src/main.nr" +* `--skip-underconstrained-check` — Flag to turn off the compiler check for under constrained values. Warning: This can improve compilation speed but can also lead to correctness errors. This check should always be run on production code +* `--oracle-resolver ` — JSON RPC url to solve oracle calls + + + +## `nargo info` + +Provides detailed information on each of a program's function (represented by a single circuit) + +Current information provided per circuit: 1. The number of ACIR opcodes 2. Counts the final number gates in the circuit used by a backend + +**Usage:** `nargo info [OPTIONS]` + +###### **Options:** + +* `--package ` — The name of the package to detail +* `--workspace` — Detail all packages in the workspace +* `--expression-width ` — Specify the backend expression width that should be targeted +* `--bounded-codegen` — Generate ACIR with the target backend expression width. The default is to generate ACIR without a bound and split expressions after code generation. Activating this flag can sometimes provide optimizations for certain programs + + Default value: `false` +* `--force` — Force a full recompilation +* `--print-acir` — Display the ACIR for compiled circuit +* `--deny-warnings` — Treat all warnings as errors +* `--silence-warnings` — Suppress warnings +* `--debug-comptime-in-file ` — Enable printing results of comptime evaluation: provide a path suffix for the module to debug, e.g. "package_name/src/main.nr" +* `--skip-underconstrained-check` — Flag to turn off the compiler check for under constrained values. Warning: This can improve compilation speed but can also lead to correctness errors. This check should always be run on production code + + + +## `nargo lsp` + +Starts the Noir LSP server + +Starts an LSP server which allows IDEs such as VS Code to display diagnostics in Noir source. + +VS Code Noir Language Support: https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir + +**Usage:** `nargo lsp` + + + +
+ + + This document was generated automatically by + clap-markdown. + + diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/noir_codegen.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/noir_codegen.md new file mode 100644 index 00000000000..e4c362f9610 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/reference/noir_codegen.md @@ -0,0 +1,116 @@ +--- +title: Noir Codegen for TypeScript +description: Learn how to use Noir codegen to generate TypeScript bindings +keywords: [Nargo, Noir, compile, TypeScript] +sidebar_position: 3 +--- + +When using TypeScript, it is extra work to interpret Noir program outputs in a type-safe way. Third party libraries may exist for popular Noir programs, but they are either hard to find or unmaintained. + +Now you can generate TypeScript bindings for your Noir programs in two steps: + +1. Exporting Noir functions using `nargo export` +2. Using the TypeScript module `noir_codegen` to generate TypeScript binding + +**Note:** you can only export functions from a Noir *library* (not binary or contract program types). + +## Installation + +### Your TypeScript project + +If you don't already have a TypeScript project you can add the module with `yarn` (or `npm`), then initialize it: + +```bash +yarn add typescript -D +npx tsc --init +``` + +### Add TypeScript module - `noir_codegen` + +The following command will add the module to your project's devDependencies: + +```bash +yarn add @noir-lang/noir_codegen -D +``` + +### Nargo library + +Make sure you have Nargo, v0.25.0 or greater, installed. If you don't, follow the [installation guide](../getting_started/noir_installation.md). + +If you're in a new project, make a `circuits` folder and create a new Noir library: + +```bash +mkdir circuits && cd circuits +nargo new --lib myNoirLib +``` + +## Usage + +### Export ABI of specified functions + +First go to the `.nr` files in your Noir library, and add the `#[export]` macro to each function that you want to use in TypeScript. + +```rust +#[export] +fn your_function(... +``` + +From your Noir library (where `Nargo.toml` is), run the following command: + +```bash +nargo export +``` + +You will now have an `export` directory with a .json file per exported function. + +You can also specify the directory of Noir programs using `--program-dir`, for example: + +```bash +nargo export --program-dir=./circuits/myNoirLib +``` + +### Generate TypeScript bindings from exported functions + +To use the `noir-codegen` package we added to the TypeScript project: + +```bash +yarn noir-codegen ./export/your_function.json +``` + +This creates an `exports` directory with an `index.ts` file containing all exported functions. + +**Note:** adding `--out-dir` allows you to specify an output dir for your TypeScript bindings to go. Eg: + +```bash +yarn noir-codegen ./export/*.json --out-dir ./path/to/output/dir +``` + +## Example .nr function to .ts output + +Consider a Noir library with this function: + +```rust +#[export] +fn not_equal(x: Field, y: Field) -> bool { + x != y +} +``` + +After the export and codegen steps, you should have an `index.ts` like: + +```typescript +export type Field = string; + + +export const is_equal_circuit: CompiledCircuit = +{"abi":{"parameters":[{"name":"x","type":{"kind":"field"},"visibility":"private"},{"name":"y","type":{"kind":"field"},"visibility":"private"}],"return_type":{"abi_type":{"kind":"boolean"},"visibility":"private"}},"bytecode":"H4sIAAAAAAAA/7WUMQ7DIAxFQ0Krrr2JjSGYLVcpKrn/CaqqDQN12WK+hPBgmWd/wEyHbF1SS923uhOs3pfoChI+wKXMAXzIKyNj4PB0TFTYc0w5RUjoqeAeEu1wqK0F54RGkWvW44LPzExnlkbMEs4JNZmN8PxS42uHv82T8a3Jeyn2Ks+VLPcO558HmyLMCDOXAXXtpPt4R/Rt9T36ss6dS9HGPx/eG17nGegKBQAA"}; + +export async function is_equal(x: Field, y: Field, foreignCallHandler?: ForeignCallHandler): Promise { + const program = new Noir(is_equal_circuit); + const args: InputMap = { x, y }; + const { returnValue } = await program.execute(args, foreignCallHandler); + return returnValue as boolean; +} +``` + +Now the `is_equal()` function and relevant types are readily available for use in TypeScript. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/debugger.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/debugger.md new file mode 100644 index 00000000000..200b5fc423a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/debugger.md @@ -0,0 +1,26 @@ +--- +title: Debugger +description: Learn about the Noir Debugger, in its REPL or VS Code versions. +keywords: [Nargo, VSCode, Visual Studio Code, REPL, Debugger] +sidebar_position: 2 +--- + +# Noir Debugger + +There are currently two ways of debugging Noir programs: + +1. From VS Code, via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). +2. Via the REPL debugger, which ships with Nargo. + +In order to use either version of the debugger, you will need to install recent enough versions of Noir, [Nargo](../getting_started/noir_installation.md) and vscode-noir: + +- Noir & Nargo ≥0.28.0 +- Noir's VS Code extension ≥0.0.11 + +:::info +At the moment, the debugger supports debugging binary projects, but not contracts. +::: + +We cover the VS Code Noir debugger more in depth in [its VS Code debugger how-to guide](../how_to/debugger/debugging_with_vs_code.md) and [the reference](../reference/debugger/debugger_vscode.md). + +The REPL debugger is discussed at length in [the REPL debugger how-to guide](../how_to/debugger/debugging_with_the_repl.md) and [the reference](../reference/debugger/debugger_repl.md). diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/language_server.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/language_server.md new file mode 100644 index 00000000000..81e0356ef8a --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/language_server.md @@ -0,0 +1,43 @@ +--- +title: Language Server +description: Learn about the Noir Language Server, how to install the components, and configuration that may be required. +keywords: [Nargo, Language Server, LSP, VSCode, Visual Studio Code] +sidebar_position: 0 +--- + +This section helps you install and configure the Noir Language Server. + +The Language Server Protocol (LSP) has two components, the [Server](#language-server) and the [Client](#language-client). Below we describe each in the context of Noir. + +## Language Server + +The Server component is provided by the Nargo command line tool that you installed at the beginning of this guide. +As long as Nargo is installed and you've used it to run other commands in this guide, it should be good to go! + +If you'd like to verify that the `nargo lsp` command is available, you can run `nargo --help` and look for `lsp` in the list of commands. If you see it, you're using a version of Noir with LSP support. + +## Language Client + +The Client component is usually an editor plugin that launches the Server. It communicates LSP messages between the editor and the Server. For example, when you save a file, the Client will alert the Server, so it can try to compile the project and report any errors. + +Currently, Noir provides a Language Client for Visual Studio Code via the [vscode-noir](https://github.com/noir-lang/vscode-noir) extension. You can install it via the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir). + +> **Note:** Noir's Language Server Protocol support currently assumes users' VSCode workspace root to be the same as users' Noir project root (i.e. where Nargo.toml lies). +> +> If LSP features seem to be missing / malfunctioning, make sure you are opening your Noir project directly (instead of as a sub-folder) in your VSCode instance. + +When your language server is running correctly and the VSCode plugin is installed, you should see handy codelens buttons for compilation, measuring circuit size, execution, and tests: + +![Compile and Execute](@site/static/img/codelens_compile_execute.png) +![Run test](@site/static/img/codelens_run_test.png) + +You should also see your tests in the `testing` panel: + +![Testing panel](@site/static/img/codelens_testing_panel.png) + +### Configuration + +- **Noir: Enable LSP** - If checked, the extension will launch the Language Server via `nargo lsp` and communicate with it. +- **Noir: Nargo Flags** - Additional flags may be specified if you require them to be added when the extension calls `nargo lsp`. +- **Noir: Nargo Path** - An absolute path to a Nargo binary with the `lsp` command. This may be useful if Nargo is not within the `PATH` of your editor. +- **Noir > Trace: Server** - Setting this to `"messages"` or `"verbose"` will log LSP messages between the Client and Server. Useful for debugging. diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/testing.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/testing.md new file mode 100644 index 00000000000..866677da567 --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tooling/testing.md @@ -0,0 +1,79 @@ +--- +title: Testing in Noir +description: Learn how to use Nargo to test your Noir program in a quick and easy way +keywords: [Nargo, testing, Noir, compile, test] +sidebar_position: 1 +--- + +You can test your Noir programs using Noir circuits. + +Nargo will automatically compile and run any functions which have the decorator `#[test]` on them if +you run `nargo test`. + +For example if you have a program like: + +```rust +fn add(x: u64, y: u64) -> u64 { + x + y +} +#[test] +fn test_add() { + assert(add(2,2) == 4); + assert(add(0,1) == 1); + assert(add(1,0) == 1); +} +``` + +Running `nargo test` will test that the `test_add` function can be executed while satisfying all +the constraints which allows you to test that add returns the expected values. Test functions can't +have any arguments currently. + +### Test fail + +You can write tests that are expected to fail by using the decorator `#[test(should_fail)]`. For example: + +```rust +fn add(x: u64, y: u64) -> u64 { + x + y +} +#[test(should_fail)] +fn test_add() { + assert(add(2,2) == 5); +} +``` + +You can be more specific and make it fail with a specific reason by using `should_fail_with = ""`: + +```rust +fn main(african_swallow_avg_speed : Field) { + assert(african_swallow_avg_speed == 65, "What is the airspeed velocity of an unladen swallow"); +} + +#[test] +fn test_king_arthur() { + main(65); +} + +#[test(should_fail_with = "What is the airspeed velocity of an unladen swallow")] +fn test_bridgekeeper() { + main(32); +} +``` + +The string given to `should_fail_with` doesn't need to exactly match the failure reason, it just needs to be a substring of it: + +```rust +fn main(african_swallow_avg_speed : Field) { + assert(african_swallow_avg_speed == 65, "What is the airspeed velocity of an unladen swallow"); +} + +#[test] +fn test_king_arthur() { + main(65); +} + +#[test(should_fail_with = "airspeed velocity")] +fn test_bridgekeeper() { + main(32); +} +``` \ No newline at end of file diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tutorials/noirjs_app.md b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tutorials/noirjs_app.md new file mode 100644 index 00000000000..6e69ea0bbed --- /dev/null +++ b/noir/noir-repo/docs/versioned_docs/version-v0.36.0/tutorials/noirjs_app.md @@ -0,0 +1,366 @@ +--- +title: Building a web app with NoirJS +description: Learn how to setup a new app that uses Noir to generate and verify zero-knowledge SNARK proofs in a typescript or javascript environment. +keywords: [how to, guide, javascript, typescript, noir, barretenberg, zero-knowledge, proofs, app] +sidebar_position: 0 +pagination_next: noir/concepts/data_types/index +--- + +NoirJS is a set of packages meant to work both in a browser and a server environment. In this tutorial, we will build a simple web app using them. From here, you should get an idea on how to proceed with your own Noir projects! + +You can find the complete app code for this guide [here](https://github.com/noir-lang/tiny-noirjs-app). + +## Setup + +:::note + +Feel free to use whatever versions, just keep in mind that Nargo and the NoirJS packages are meant to be in sync. For example, Nargo 0.31.x matches `noir_js@0.31.x`, etc. + +In this guide, we will be pinned to 0.31.0. + +::: + +Before we start, we want to make sure we have Node, Nargo and the Barretenberg proving system (`bb`) installed. + +We start by opening a terminal and executing `node --version`. If we don't get an output like `v20.10.0`, that means node is not installed. Let's do that by following the handy [nvm guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script). + +As for `Nargo`, we can follow the [Nargo guide](../getting_started/quick_start.md) to install it. If you're lazy, just paste this on a terminal and run `noirup`: + +```sh +curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash +``` + +Follow the instructions on [this page](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg/cpp/src/barretenberg/bb#installation) to install `bb`. +Version 0.41.0 is compatible with `nargo` version 0.31.0, which you can install with `bbup -v 0.41.0` once `bbup` is installed. + +Easy enough. Onwards! + +## Our project + +ZK is a powerful technology. An app that doesn't reveal one of the inputs to _anyone_ is almost unbelievable, yet Noir makes it as easy as a single line of code. + +In fact, it's so simple that it comes nicely packaged in `nargo`. Let's do that! + +### Nargo + +Run: + +```bash +nargo new circuit +``` + +And... That's about it. Your program is ready to be compiled and run. + +To compile, let's `cd` into the `circuit` folder to enter our project, and call: + +```bash +nargo compile +``` + +This compiles our circuit into `json` format and add it to a new `target` folder. + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit <---- our working directory + ├── Nargo.toml + ├── src + │ └── main.nr + └── target + └── circuit.json +``` + +::: + +### Node and Vite + +If you want to explore Nargo, feel free to go on a side-quest now and follow the steps in the +[getting started](../getting_started/quick_start.md) guide. However, we want our app to run on the browser, so we need Vite. + +Vite is a powerful tool to generate static websites. While it provides all kinds of features, let's just go barebones with some good old vanilla JS. + +To do this this, go back to the previous folder (`cd ..`) and create a new vite project by running `npm create vite` and choosing "Vanilla" and "Javascript". + +A wild `vite-project` directory should now appear in your root folder! Let's not waste any time and dive right in: + +```bash +cd vite-project +``` + +### Setting Up Vite and Configuring the Project + +Before we proceed with any coding, let's get our environment tailored for Noir. We'll start by laying down the foundations with a `vite.config.js` file. This little piece of configuration is our secret sauce for making sure everything meshes well with the NoirJS libraries and other special setups we might need, like handling WebAssembly modules. Here’s how you get that going: + +#### Creating the vite.config.js + +In your freshly minted `vite-project` folder, create a new file named `vite.config.js` and open it in your code editor. Paste the following to set the stage: + +```javascript +import { defineConfig } from 'vite'; +import copy from 'rollup-plugin-copy'; +import fs from 'fs'; +import path from 'path'; + +const wasmContentTypePlugin = { + name: 'wasm-content-type-plugin', + configureServer(server) { + server.middlewares.use(async (req, res, next) => { + if (req.url.endsWith('.wasm')) { + res.setHeader('Content-Type', 'application/wasm'); + const newPath = req.url.replace('deps', 'dist'); + const targetPath = path.join(__dirname, newPath); + const wasmContent = fs.readFileSync(targetPath); + return res.end(wasmContent); + } + next(); + }); + }, +}; + +export default defineConfig(({ command }) => { + if (command === 'serve') { + return { + build: { + target: 'esnext', + rollupOptions: { + external: ['@aztec/bb.js'] + } + }, + optimizeDeps: { + esbuildOptions: { + target: 'esnext' + } + }, + plugins: [ + copy({ + targets: [{ src: 'node_modules/**/*.wasm', dest: 'node_modules/.vite/dist' }], + copySync: true, + hook: 'buildStart', + }), + command === 'serve' ? wasmContentTypePlugin : [], + ], + }; + } + + return {}; +}); +``` + +#### Install Dependencies + +Now that our stage is set, install the necessary NoirJS packages along with our other dependencies: + +```bash +npm install && npm install @noir-lang/backend_barretenberg@0.31.0 @noir-lang/noir_js@0.31.0 +npm install rollup-plugin-copy --save-dev +``` + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit + └── ...etc... +└── vite-project <---- our working directory + └── ...etc... +``` + +::: + +#### Some cleanup + +`npx create vite` is amazing but it creates a bunch of files we don't really need for our simple example. Actually, let's just delete everything except for `vite.config.js`, `index.html`, `main.js` and `package.json`. I feel lighter already. + +![my heart is ready for you, noir.js](@site/static/img/memes/titanic.jpeg) + +## HTML + +Our app won't run like this, of course. We need some working HTML, at least. Let's open our broken-hearted `index.html` and replace everything with this code snippet: + +```html + + + + + + +

Noir app

+
+ + +
+
+

Logs

+

Proof

+
+ + +``` + +It _could_ be a beautiful UI... Depending on which universe you live in. + +## Some good old vanilla Javascript + +Our love for Noir needs undivided attention, so let's just open `main.js` and delete everything (this is where the romantic scenery becomes a bit creepy). + +Start by pasting in this boilerplate code: + +```js +function display(container, msg) { + const c = document.getElementById(container); + const p = document.createElement('p'); + p.textContent = msg; + c.appendChild(p); +} + +document.getElementById('submitGuess').addEventListener('click', async () => { + try { + // here's where love happens + } catch (err) { + display('logs', 'Oh 💔 Wrong guess'); + } +}); +``` + +The display function doesn't do much. We're simply manipulating our website to see stuff happening. For example, if the proof fails, it will simply log a broken heart 😢 + +:::info + +At this point in the tutorial, your folder structure should look like this: + +```tree +. +└── circuit + └── ...same as above +└── vite-project + ├── vite.config.js + ├── main.js + ├── package.json + └── index.html +``` + +You'll see other files and folders showing up (like `package-lock.json`, `node_modules`) but you shouldn't have to care about those. + +::: + +## Some NoirJS + +We're starting with the good stuff now. If you've compiled the circuit as described above, you should have a `json` file we want to import at the very top of our `main.js` file: + +```ts +import circuit from '../circuit/target/circuit.json'; +``` + +[Noir is backend-agnostic](../index.mdx#whats-new-about-noir). We write Noir, but we also need a proving backend. That's why we need to import and instantiate the two dependencies we installed above: `BarretenbergBackend` and `Noir`. Let's import them right below: + +```js +import { BarretenbergBackend, BarretenbergVerifier as Verifier } from '@noir-lang/backend_barretenberg'; +import { Noir } from '@noir-lang/noir_js'; +``` + +And instantiate them inside our try-catch block: + +```ts +// try { +const backend = new BarretenbergBackend(circuit); +const noir = new Noir(circuit); +// } +``` + +:::note + +For the remainder of the tutorial, everything will be happening inside the `try` block + +::: + +## Our app + +Now for the app itself. We're capturing whatever is in the input when people press the submit button. Just add this: + +```js +const x = parseInt(document.getElementById('guessInput').value); +const input = { x, y: 2 }; +``` + +Now we're ready to prove stuff! Let's feed some inputs to our circuit and calculate the proof: + +```js +await setup(); // let's squeeze our wasm inits here + +display('logs', 'Generating proof... ⌛'); +const { witness } = await noir.execute(input); +const proof = await backend.generateProof(witness); +display('logs', 'Generating proof... ✅'); +display('results', proof.proof); +``` + +You're probably eager to see stuff happening, so go and run your app now! + +From your terminal, run `npm run dev`. If it doesn't open a browser for you, just visit `localhost:5173`. You should now see the worst UI ever, with an ugly input. + +![Getting Started 0](@site/static/img/noir_getting_started_1.png) + +Now, our circuit says `fn main(x: Field, y: pub Field)`. This means only the `y` value is public, and it's hardcoded above: `input = { x, y: 2 }`. In other words, you won't need to send your secret`x` to the verifier! + +By inputting any number other than 2 in the input box and clicking "submit", you should get a valid proof. Otherwise the proof won't even generate correctly. By the way, if you're human, you shouldn't be able to understand anything on the "proof" box. That's OK. We like you, human ❤️. + +## Verifying + +Time to celebrate, yes! But we shouldn't trust machines so blindly. Let's add these lines to see our proof being verified: + +```js +display('logs', 'Verifying proof... ⌛'); +const isValid = await backend.verifyProof(proof); + +// or to cache and use the verification key: +// const verificationKey = await backend.getVerificationKey(); +// const verifier = new Verifier(); +// const isValid = await verifier.verifyProof(proof, verificationKey); + +if (isValid) display('logs', 'Verifying proof... ✅'); +``` + +You have successfully generated a client-side Noir web app! + +![coded app without math knowledge](@site/static/img/memes/flextape.jpeg) + +## Further Reading + +You can see how noirjs is used in a full stack Next.js hardhat application in the [noir-starter repo here](https://github.com/noir-lang/noir-starter/tree/main/vite-hardhat). The example shows how to calculate a proof in the browser and verify it with a deployed Solidity verifier contract from noirjs. + +You should also check out the more advanced examples in the [noir-examples repo](https://github.com/noir-lang/noir-examples), where you'll find reference usage for some cool apps. + +## UltraHonk Backend + +Barretenberg has recently exposed a new UltraHonk backend. We can use UltraHonk in NoirJS after version 0.33.0. Everything will be the same as the tutorial above, except that the class we need to import will change: + +```js +import { UltraHonkBackend, UltraHonkVerifier as Verifier } from '@noir-lang/backend_barretenberg'; +``` + +The backend will then be instantiated as such: + +```js +const backend = new UltraHonkBackend(circuit); +``` + +Then all the commands to prove and verify your circuit will be same. + +The only feature currently unsupported with UltraHonk are [recursive proofs](../explainers/explainer-recursion.md). diff --git a/noir/noir-repo/docs/versioned_sidebars/version-v0.36.0-sidebars.json b/noir/noir-repo/docs/versioned_sidebars/version-v0.36.0-sidebars.json new file mode 100644 index 00000000000..b9ad026f69f --- /dev/null +++ b/noir/noir-repo/docs/versioned_sidebars/version-v0.36.0-sidebars.json @@ -0,0 +1,93 @@ +{ + "sidebar": [ + { + "type": "doc", + "id": "index" + }, + { + "type": "category", + "label": "Getting Started", + "items": [ + { + "type": "autogenerated", + "dirName": "getting_started" + } + ] + }, + { + "type": "category", + "label": "The Noir Language", + "items": [ + { + "type": "autogenerated", + "dirName": "noir" + } + ] + }, + { + "type": "html", + "value": "
", + "defaultStyle": true + }, + { + "type": "category", + "label": "How To Guides", + "items": [ + { + "type": "autogenerated", + "dirName": "how_to" + } + ] + }, + { + "type": "category", + "label": "Explainers", + "items": [ + { + "type": "autogenerated", + "dirName": "explainers" + } + ] + }, + { + "type": "category", + "label": "Tutorials", + "items": [ + { + "type": "autogenerated", + "dirName": "tutorials" + } + ] + }, + { + "type": "category", + "label": "Reference", + "items": [ + { + "type": "autogenerated", + "dirName": "reference" + } + ] + }, + { + "type": "category", + "label": "Tooling", + "items": [ + { + "type": "autogenerated", + "dirName": "tooling" + } + ] + }, + { + "type": "html", + "value": "
", + "defaultStyle": true + }, + { + "type": "doc", + "id": "migration_notes", + "label": "Migration notes" + } + ] +} diff --git a/noir/noir-repo/noir_stdlib/src/array/check_shuffle.nr b/noir/noir-repo/noir_stdlib/src/array/check_shuffle.nr index 26f5ced3467..82028d487c7 100644 --- a/noir/noir-repo/noir_stdlib/src/array/check_shuffle.nr +++ b/noir/noir-repo/noir_stdlib/src/array/check_shuffle.nr @@ -1,7 +1,10 @@ use crate::cmp::Eq; -unconstrained fn __get_shuffle_indices(lhs: [T; N], rhs: [T; N]) -> [Field; N] where T: Eq { - let mut shuffle_indices: [Field;N ] = [0; N]; +unconstrained fn __get_shuffle_indices(lhs: [T; N], rhs: [T; N]) -> [Field; N] +where + T: Eq, +{ + let mut shuffle_indices: [Field; N] = [0; N]; let mut shuffle_mask: [bool; N] = [false; N]; for i in 0..N { @@ -35,7 +38,10 @@ unconstrained fn __get_index(indices: [Field; N], idx: Field) -> Fie result } -pub(crate) fn check_shuffle(lhs: [T; N], rhs: [T; N]) where T: Eq { +pub(crate) fn check_shuffle(lhs: [T; N], rhs: [T; N]) +where + T: Eq, +{ unsafe { let shuffle_indices = __get_shuffle_indices(lhs, rhs); @@ -59,7 +65,7 @@ mod test { struct CompoundStruct { a: bool, b: Field, - c: u64 + c: u64, } impl Eq for CompoundStruct { fn eq(self, other: Self) -> bool { @@ -102,14 +108,14 @@ mod test { CompoundStruct { a: false, b: -100, c: 54321 }, CompoundStruct { a: true, b: 5, c: 0xffffffffffffffff }, CompoundStruct { a: true, b: 9814, c: 0xeeffee0011001133 }, - CompoundStruct { a: false, b: 0x155, c: 0 } + CompoundStruct { a: false, b: 0x155, c: 0 }, ]; let rhs: [CompoundStruct; 5] = [ CompoundStruct { a: false, b: 0x155, c: 0 }, CompoundStruct { a: false, b: 0, c: 12345 }, CompoundStruct { a: false, b: -100, c: 54321 }, CompoundStruct { a: true, b: 9814, c: 0xeeffee0011001133 }, - CompoundStruct { a: true, b: 5, c: 0xffffffffffffffff } + CompoundStruct { a: true, b: 5, c: 0xffffffffffffffff }, ]; check_shuffle(lhs, rhs); } diff --git a/noir/noir-repo/noir_stdlib/src/array/mod.nr b/noir/noir-repo/noir_stdlib/src/array/mod.nr index 46acf619dd2..8bb425854f2 100644 --- a/noir/noir-repo/noir_stdlib/src/array/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/array/mod.nr @@ -7,13 +7,13 @@ mod quicksort; impl [T; N] { /// Returns the length of this array. - /// + /// /// ```noir /// fn len(self) -> Field /// ``` - /// + /// /// example - /// + /// /// ```noir /// fn main() { /// let array = [42, 42]; @@ -24,7 +24,7 @@ impl [T; N] { pub fn len(self) -> u32 {} /// Returns this array as a slice. - /// + /// /// ```noir /// let array = [1, 2]; /// let slice = array.as_slice(); @@ -34,19 +34,19 @@ impl [T; N] { pub fn as_slice(self) -> [T] {} /// Applies a function to each element of this array, returning a new array containing the mapped elements. - /// + /// /// Example: - /// + /// /// ```rust /// let a = [1, 2, 3]; /// let b = a.map(|a| a * 2); /// assert_eq(b, [2, 4, 6]); /// ``` pub fn map(self, f: fn[Env](T) -> U) -> [U; N] { - let first_elem = f(self[0]); - let mut ret = [first_elem; N]; + let uninitialized = crate::mem::zeroed(); + let mut ret = [uninitialized; N]; - for i in 1..self.len() { + for i in 0..self.len() { ret[i] = f(self[i]); } @@ -55,20 +55,20 @@ impl [T; N] { /// Applies a function to each element of the array, returning the final accumulated value. The first /// parameter is the initial value. - /// + /// /// This is a left fold, so the given function will be applied to the accumulator and first element of /// the array, then the second, and so on. For a given call the expected result would be equivalent to: - /// + /// /// ```rust /// let a1 = [1]; /// let a2 = [1, 2]; /// let a3 = [1, 2, 3]; - /// + /// /// let f = |a, b| a - b; /// a1.fold(10, f); //=> f(10, 1) /// a2.fold(10, f); //=> f(f(10, 1), 2) /// a3.fold(10, f); //=> f(f(f(10, 1), 2), 3) - /// + /// /// assert_eq(a3.fold(10, f), 10 - 1 - 2 - 3); /// ``` pub fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U { @@ -79,9 +79,11 @@ impl [T; N] { } /// Same as fold, but uses the first element as the starting element. - /// + /// + /// Requires the input array to be non-empty. + /// /// Example: - /// + /// /// ```noir /// fn main() { /// let arr = [1, 2, 3, 4]; @@ -98,9 +100,9 @@ impl [T; N] { } /// Returns true if all the elements in this array satisfy the given predicate. - /// + /// /// Example: - /// + /// /// ```noir /// fn main() { /// let arr = [2, 2, 2, 2, 2]; @@ -117,9 +119,9 @@ impl [T; N] { } /// Returns true if any of the elements in this array satisfy the given predicate. - /// + /// /// Example: - /// + /// /// ```noir /// fn main() { /// let arr = [2, 2, 2, 2, 5]; @@ -136,14 +138,17 @@ impl [T; N] { } } -impl [T; N] where T: Ord + Eq { +impl [T; N] +where + T: Ord + Eq, +{ /// Returns a new sorted array. The original array remains untouched. Notice that this function will /// only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting /// logic it uses internally is optimized specifically for these values. If you need a sort function to /// sort any type, you should use the `sort_via` function. - /// + /// /// Example: - /// + /// /// ```rust /// fn main() { /// let arr = [42, 32]; @@ -156,21 +161,24 @@ impl [T; N] where T: Ord + Eq { } } -impl [T; N] where T: Eq { - /// Returns a new sorted array by sorting it with a custom comparison function. - /// The original array remains untouched. +impl [T; N] +where + T: Eq, +{ + /// Returns a new sorted array by sorting it with a custom comparison function. + /// The original array remains untouched. /// The ordering function must return true if the first argument should be sorted to be before the second argument or is equal to the second argument. - /// + /// /// Using this method with an operator like `<` that does not return `true` for equal values will result in an assertion failure for arrays with equal elements. - /// + /// /// Example: - /// + /// /// ```rust /// fn main() { /// let arr = [42, 32] /// let sorted_ascending = arr.sort_via(|a, b| a <= b); /// assert(sorted_ascending == [32, 42]); // verifies - /// + /// /// let sorted_descending = arr.sort_via(|a, b| a >= b); /// assert(sorted_descending == [32, 42]); // does not verify /// } @@ -185,7 +193,8 @@ impl [T; N] where T: Eq { if !is_unconstrained() { for i in 0..N - 1 { assert( - ordering(sorted[i], sorted[i + 1]), "Array has not been sorted correctly according to `ordering`." + ordering(sorted[i], sorted[i + 1]), + "Array has not been sorted correctly according to `ordering`.", ); } check_shuffle::check_shuffle(self, sorted); @@ -198,9 +207,9 @@ impl [T; N] where T: Eq { impl [u8; N] { /// Converts a byte array of type `[u8; N]` to a string. Note that this performs no UTF-8 validation - /// the given array is interpreted as-is as a string. - /// + /// /// Example: - /// + /// /// ```rust /// fn main() { /// let hi = [104, 105].as_str_unchecked(); @@ -217,3 +226,10 @@ impl From> for [u8; N] { s.as_bytes() } } + +mod test { + #[test] + fn map_empty() { + assert_eq([].map(|x| x + 1), []); + } +} diff --git a/noir/noir-repo/noir_stdlib/src/array/quicksort.nr b/noir/noir-repo/noir_stdlib/src/array/quicksort.nr index 8563a5d75bd..5e9c575c5ce 100644 --- a/noir/noir-repo/noir_stdlib/src/array/quicksort.nr +++ b/noir/noir-repo/noir_stdlib/src/array/quicksort.nr @@ -2,7 +2,7 @@ unconstrained fn partition( arr: &mut [T; N], low: u32, high: u32, - sortfn: fn[Env](T, T) -> bool + sortfn: fn[Env](T, T) -> bool, ) -> u32 { let pivot = high; let mut i = low; @@ -20,7 +20,12 @@ unconstrained fn partition( i } -unconstrained fn quicksort_recursive(arr: &mut [T; N], low: u32, high: u32, sortfn: fn[Env](T, T) -> bool) { +unconstrained fn quicksort_recursive( + arr: &mut [T; N], + low: u32, + high: u32, + sortfn: fn[Env](T, T) -> bool, +) { if low < high { let pivot_index = partition(arr, low, high, sortfn); if pivot_index > 0 { @@ -30,7 +35,10 @@ unconstrained fn quicksort_recursive(arr: &mut [T; N], low: } } -pub(crate) unconstrained fn quicksort(_arr: [T; N], sortfn: fn[Env](T, T) -> bool) -> [T; N] { +pub(crate) unconstrained fn quicksort( + _arr: [T; N], + sortfn: fn[Env](T, T) -> bool, +) -> [T; N] { let mut arr: [T; N] = _arr; if arr.len() <= 1 {} else { quicksort_recursive(&mut arr, 0, arr.len() - 1, sortfn); diff --git a/noir/noir-repo/noir_stdlib/src/bigint.nr b/noir/noir-repo/noir_stdlib/src/bigint.nr index 0015f480794..203ff90d444 100644 --- a/noir/noir-repo/noir_stdlib/src/bigint.nr +++ b/noir/noir-repo/noir_stdlib/src/bigint.nr @@ -1,16 +1,30 @@ use crate::ops::{Add, Sub, Mul, Div}; use crate::cmp::Eq; -global bn254_fq = &[0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97, - 0x5d, 0x58, 0x81, 0x81, 0xb6, 0x45, 0x50, 0xb8, 0x29, 0xa0, 0x31, 0xe1, 0x72, 0x4e, 0x64, 0x30]; -global bn254_fr = &[1, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48]; -global secpk1_fr = &[0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF, 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA, - 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; -global secpk1_fq = &[0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; -global secpr1_fq = &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF]; -global secpr1_fr = &[81, 37, 99, 252, 194, 202, 185, 243, 132, 158, 23, 167, 173, 250, 230, 188, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255]; +global bn254_fq = &[ + 0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97, + 0x5d, 0x58, 0x81, 0x81, 0xb6, 0x45, 0x50, 0xb8, 0x29, 0xa0, 0x31, 0xe1, 0x72, 0x4e, 0x64, 0x30, +]; +global bn254_fr = &[ + 1, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, + 80, 184, 41, 160, 49, 225, 114, 78, 100, 48, +]; +global secpk1_fr = &[ + 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF, 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +]; +global secpk1_fq = &[ + 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +]; +global secpr1_fq = &[ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +]; +global secpr1_fr = &[ + 81, 37, 99, 252, 194, 202, 185, 243, 132, 158, 23, 167, 173, 250, 230, 188, 255, 255, 255, 255, + 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, +]; // docs:start:big_int_definition pub struct BigInt { pointer: u32, @@ -50,7 +64,7 @@ pub trait BigField { } pub struct Secpk1Fq { - array: [u8;32], + array: [u8; 32], } impl BigField for Secpk1Fq { @@ -107,7 +121,7 @@ impl Eq for Secpk1Fq { } pub struct Secpk1Fr { - array: [u8;32], + array: [u8; 32], } impl BigField for Secpk1Fr { @@ -164,7 +178,7 @@ impl Eq for Secpk1Fr { } pub struct Bn254Fr { - array: [u8;32], + array: [u8; 32], } impl BigField for Bn254Fr { @@ -221,7 +235,7 @@ impl Eq for Bn254Fr { } pub struct Bn254Fq { - array: [u8;32], + array: [u8; 32], } impl BigField for Bn254Fq { @@ -278,7 +292,7 @@ impl Eq for Bn254Fq { } pub struct Secpr1Fq { - array: [u8;32], + array: [u8; 32], } impl BigField for Secpr1Fq { @@ -335,7 +349,7 @@ impl Eq for Secpr1Fq { } pub struct Secpr1Fr { - array: [u8;32], + array: [u8; 32], } impl BigField for Secpr1Fr { diff --git a/noir/noir-repo/noir_stdlib/src/cmp.nr b/noir/noir-repo/noir_stdlib/src/cmp.nr index ac7e3df66ad..10be6e7b867 100644 --- a/noir/noir-repo/noir_stdlib/src/cmp.nr +++ b/noir/noir-repo/noir_stdlib/src/cmp.nr @@ -18,7 +18,14 @@ comptime fn derive_eq(s: StructDefinition) -> Quoted { fields } }; - crate::meta::make_trait_impl(s, quote { Eq }, signature, for_each_field, quote { & }, body) + crate::meta::make_trait_impl( + s, + quote { Eq }, + signature, + for_each_field, + quote { & }, + body, + ) } // docs:end:derive_eq @@ -86,7 +93,10 @@ impl Eq for bool { } } -impl Eq for [T; N] where T: Eq { +impl Eq for [T; N] +where + T: Eq, +{ fn eq(self, other: [T; N]) -> bool { let mut result = true; for i in 0..self.len() { @@ -96,7 +106,10 @@ impl Eq for [T; N] where T: Eq { } } -impl Eq for [T] where T: Eq { +impl Eq for [T] +where + T: Eq, +{ fn eq(self, other: [T]) -> bool { let mut result = self.len() == other.len(); for i in 0..self.len() { @@ -114,25 +127,47 @@ impl Eq for str { } } -impl Eq for (A, B) where A: Eq, B: Eq { +impl Eq for (A, B) +where + A: Eq, + B: Eq, +{ fn eq(self, other: (A, B)) -> bool { self.0.eq(other.0) & self.1.eq(other.1) } } -impl Eq for (A, B, C) where A: Eq, B: Eq, C: Eq { +impl Eq for (A, B, C) +where + A: Eq, + B: Eq, + C: Eq, +{ fn eq(self, other: (A, B, C)) -> bool { self.0.eq(other.0) & self.1.eq(other.1) & self.2.eq(other.2) } } -impl Eq for (A, B, C, D) where A: Eq, B: Eq, C: Eq, D: Eq { +impl Eq for (A, B, C, D) +where + A: Eq, + B: Eq, + C: Eq, + D: Eq, +{ fn eq(self, other: (A, B, C, D)) -> bool { self.0.eq(other.0) & self.1.eq(other.1) & self.2.eq(other.2) & self.3.eq(other.3) } } -impl Eq for (A, B, C, D, E) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq { +impl Eq for (A, B, C, D, E) +where + A: Eq, + B: Eq, + C: Eq, + D: Eq, + E: Eq, +{ fn eq(self, other: (A, B, C, D, E)) -> bool { self.0.eq(other.0) & self.1.eq(other.1) @@ -315,7 +350,10 @@ impl Ord for bool { } } -impl Ord for [T; N] where T: Ord { +impl Ord for [T; N] +where + T: Ord, +{ // The first non-equal element of both arrays determines // the ordering for the whole array. fn cmp(self, other: [T; N]) -> Ordering { @@ -335,7 +373,10 @@ impl Ord for [T; N] where T: Ord { } } -impl Ord for [T] where T: Ord { +impl Ord for [T] +where + T: Ord, +{ // The first non-equal element of both arrays determines // the ordering for the whole array. fn cmp(self, other: [T]) -> Ordering { @@ -355,7 +396,11 @@ impl Ord for [T] where T: Ord { } } -impl Ord for (A, B) where A: Ord, B: Ord { +impl Ord for (A, B) +where + A: Ord, + B: Ord, +{ fn cmp(self, other: (A, B)) -> Ordering { let result = self.0.cmp(other.0); @@ -367,7 +412,12 @@ impl Ord for (A, B) where A: Ord, B: Ord { } } -impl Ord for (A, B, C) where A: Ord, B: Ord, C: Ord { +impl Ord for (A, B, C) +where + A: Ord, + B: Ord, + C: Ord, +{ fn cmp(self, other: (A, B, C)) -> Ordering { let mut result = self.0.cmp(other.0); @@ -383,7 +433,13 @@ impl Ord for (A, B, C) where A: Ord, B: Ord, C: Ord { } } -impl Ord for (A, B, C, D) where A: Ord, B: Ord, C: Ord, D: Ord { +impl Ord for (A, B, C, D) +where + A: Ord, + B: Ord, + C: Ord, + D: Ord, +{ fn cmp(self, other: (A, B, C, D)) -> Ordering { let mut result = self.0.cmp(other.0); @@ -403,7 +459,14 @@ impl Ord for (A, B, C, D) where A: Ord, B: Ord, C: Ord, D: Ord { } } -impl Ord for (A, B, C, D, E) where A: Ord, B: Ord, C: Ord, D: Ord, E: Ord { +impl Ord for (A, B, C, D, E) +where + A: Ord, + B: Ord, + C: Ord, + D: Ord, + E: Ord, +{ fn cmp(self, other: (A, B, C, D, E)) -> Ordering { let mut result = self.0.cmp(other.0); @@ -439,8 +502,15 @@ impl Ord for (A, B, C, D, E) where A: Ord, B: Ord, C: Ord, D: Ord // assert_eq(cmp::max(1, 2), 2); // assert_eq(cmp::max(2, 2), 2); // ``` -pub fn max(v1: T, v2: T) -> T where T: Ord { - if v1 > v2 { v1 } else { v2 } +pub fn max(v1: T, v2: T) -> T +where + T: Ord, +{ + if v1 > v2 { + v1 + } else { + v2 + } } // Compares and returns the minimum of two values. @@ -455,8 +525,15 @@ pub fn max(v1: T, v2: T) -> T where T: Ord { // assert_eq(cmp::min(1, 2), 1); // assert_eq(cmp::min(2, 2), 2); // ``` -pub fn min(v1: T, v2: T) -> T where T: Ord { - if v1 > v2 { v2 } else { v1 } +pub fn min(v1: T, v2: T) -> T +where + T: Ord, +{ + if v1 > v2 { + v2 + } else { + v1 + } } mod cmp_tests { diff --git a/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr b/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr index c2a3ff9b7ca..9e70c403f77 100644 --- a/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr +++ b/noir/noir-repo/noir_stdlib/src/collections/bounded_vec.nr @@ -4,16 +4,16 @@ use crate::{cmp::Eq, convert::From}; /// is bounded with a maximum possible length. Unlike `Vec`, `BoundedVec` is not implemented /// via slices and thus is not subject to the same restrictions slices are (notably, nested /// slices - and thus nested vectors as well - are disallowed). -/// +/// /// Since a BoundedVec is backed by a normal array under the hood, growing the BoundedVec by /// pushing an additional element is also more efficient - the length only needs to be increased /// by one. -/// +/// /// For these reasons `BoundedVec` should generally be preferred over `Vec` when there /// is a reasonable maximum bound that can be placed on the vector. -/// +/// /// Example: -/// +/// /// ```noir /// let mut vector: BoundedVec = BoundedVec::new(); /// for i in 0..5 { @@ -63,7 +63,7 @@ impl BoundedVec { /// ``` /// /// This defaulting of `MaxLen` (and numeric generics in general) to zero may change in future noir versions - /// but for now make sure to use type annotations when using bounded vectors. Otherwise, you will receive a + /// but for now make sure to use type annotations when using bounded vectors. Otherwise, you will receive a /// constraint failure at runtime when the vec is pushed to. pub fn new() -> Self { let zeroed = crate::mem::zeroed(); @@ -71,12 +71,12 @@ impl BoundedVec { } /// Retrieves an element from the vector at the given index, starting from zero. - /// + /// /// If the given index is equal to or greater than the length of the vector, this /// will issue a constraint failure. - /// + /// /// Example: - /// + /// /// ```noir /// fn foo(v: BoundedVec) { /// let first = v.get(0); @@ -91,12 +91,12 @@ impl BoundedVec { /// Retrieves an element from the vector at the given index, starting from zero, without /// performing a bounds check. - /// + /// /// Since this function does not perform a bounds check on length before accessing the element, /// it is unsafe! Use at your own risk! - /// + /// /// Example: - /// + /// /// ```noir /// fn sum_of_first_three(v: BoundedVec) -> u32 { /// // Always ensure the length is larger than the largest @@ -113,11 +113,11 @@ impl BoundedVec { } /// Writes an element to the vector at the given index, starting from zero. - /// + /// /// If the given index is equal to or greater than the length of the vector, this will issue a constraint failure. - /// + /// /// Example: - /// + /// /// ```noir /// fn foo(v: BoundedVec) { /// let first = v.get(0); @@ -133,30 +133,30 @@ impl BoundedVec { } /// Writes an element to the vector at the given index, starting from zero, without performing a bounds check. - /// + /// /// Since this function does not perform a bounds check on length before accessing the element, it is unsafe! Use at your own risk! - /// + /// /// Example: - /// + /// /// ```noir /// fn set_unchecked_example() { /// let mut vec: BoundedVec = BoundedVec::new(); /// vec.extend_from_array([1, 2]); - /// + /// /// // Here we're safely writing within the valid range of `vec` /// // `vec` now has the value [42, 2] /// vec.set_unchecked(0, 42); - /// + /// /// // We can then safely read this value back out of `vec`. /// // Notice that we use the checked version of `get` which would prevent reading unsafe values. /// assert_eq(vec.get(0), 42); - /// + /// /// // We've now written past the end of `vec`. /// // As this index is still within the maximum potential length of `v`, - /// // it won't cause a constraint failure. + /// // it won't cause a constraint failure. /// vec.set_unchecked(2, 42); /// println(vec); - /// + /// /// // This will write past the end of the maximum potential length of `vec`, /// // it will then trigger a constraint failure. /// vec.set_unchecked(5, 42); @@ -169,17 +169,17 @@ impl BoundedVec { /// Pushes an element to the end of the vector. This increases the length /// of the vector by one. - /// + /// /// Panics if the new length of the vector will be greater than the max length. - /// + /// /// Example: - /// + /// /// ```noir /// let mut v: BoundedVec = BoundedVec::new(); - /// + /// /// v.push(1); /// v.push(2); - /// + /// /// // Panics with failed assertion "push out of bounds" /// v.push(3); /// ``` @@ -191,21 +191,21 @@ impl BoundedVec { } /// Returns the current length of this vector - /// + /// /// Example: - /// + /// /// ```noir /// let mut v: BoundedVec = BoundedVec::new(); /// assert(v.len() == 0); - /// + /// /// v.push(100); /// assert(v.len() == 1); - /// + /// /// v.push(200); /// v.push(300); /// v.push(400); /// assert(v.len() == 4); - /// + /// /// let _ = v.pop(); /// let _ = v.pop(); /// assert(v.len() == 2); @@ -216,12 +216,12 @@ impl BoundedVec { /// Returns the maximum length of this vector. This is always /// equal to the `MaxLen` parameter this vector was initialized with. - /// + /// /// Example: - /// + /// /// ```noir /// let mut v: BoundedVec = BoundedVec::new(); - /// + /// /// assert(v.max_len() == 5); /// v.push(10); /// assert(v.max_len() == 5); @@ -231,19 +231,19 @@ impl BoundedVec { } /// Returns the internal array within this vector. - /// + /// /// Since arrays in Noir are immutable, mutating the returned storage array will not mutate /// the storage held internally by this vector. - /// + /// /// Note that uninitialized elements may be zeroed out! - /// + /// /// Example: - /// + /// /// ```noir /// let mut v: BoundedVec = BoundedVec::new(); - /// + /// /// assert(v.storage() == [0, 0, 0, 0, 0]); - /// + /// /// v.push(57); /// assert(v.storage() == [57, 0, 0, 0, 0]); /// ``` @@ -252,16 +252,16 @@ impl BoundedVec { } /// Pushes each element from the given array to this vector. - /// + /// /// Panics if pushing each element would cause the length of this vector /// to exceed the maximum length. - /// + /// /// Example: - /// + /// /// ```noir /// let mut vec: BoundedVec = BoundedVec::new(); /// vec.extend_from_array([2, 4]); - /// + /// /// assert(vec.len == 2); /// assert(vec.get(0) == 2); /// assert(vec.get(1) == 4); @@ -276,16 +276,16 @@ impl BoundedVec { } /// Pushes each element from the given slice to this vector. - /// + /// /// Panics if pushing each element would cause the length of this vector /// to exceed the maximum length. - /// + /// /// Example: - /// + /// /// ```noir /// let mut vec: BoundedVec = BoundedVec::new(); /// vec.extend_from_slice(&[2, 4]); - /// + /// /// assert(vec.len == 2); /// assert(vec.get(0) == 2); /// assert(vec.get(1) == 4); @@ -301,17 +301,17 @@ impl BoundedVec { /// Pushes each element from the other vector to this vector. The length of /// the other vector is left unchanged. - /// + /// /// Panics if pushing each element would cause the length of this vector /// to exceed the maximum length. - /// + /// /// ```noir /// let mut v1: BoundedVec = BoundedVec::new(); /// let mut v2: BoundedVec = BoundedVec::new(); - /// + /// /// v2.extend_from_array([1, 2, 3]); /// v1.extend_from_bounded_vec(v2); - /// + /// /// assert(v1.storage() == [1, 2, 3, 0, 0]); /// assert(v2.storage() == [1, 2, 3, 0, 0, 0, 0]); /// ``` @@ -330,11 +330,11 @@ impl BoundedVec { self.len = new_len; } - /// Creates a new vector, populating it with values derived from an array input. + /// Creates a new vector, populating it with values derived from an array input. /// The maximum length of the vector is determined based on the type signature. - /// + /// /// Example: - /// + /// /// ```noir /// let bounded_vec: BoundedVec = BoundedVec::from_array([1, 2, 3]) /// ``` @@ -347,19 +347,19 @@ impl BoundedVec { /// Pops the element at the end of the vector. This will decrease the length /// of the vector by one. - /// + /// /// Panics if the vector is empty. - /// + /// /// Example: - /// + /// /// ```noir /// let mut v: BoundedVec = BoundedVec::new(); /// v.push(1); /// v.push(2); - /// + /// /// let two = v.pop(); /// let one = v.pop(); - /// + /// /// assert(two == 2); /// assert(one == 1); /// @@ -377,13 +377,13 @@ impl BoundedVec { /// Returns true if the given predicate returns true for any element /// in this vector. - /// + /// /// Example: - /// + /// /// ```noir /// let mut v: BoundedVec = BoundedVec::new(); /// v.extend_from_array([2, 4, 6]); - /// + /// /// let all_even = !v.any(|elem: u32| elem % 2 != 0); /// assert(all_even); /// ``` @@ -399,14 +399,14 @@ impl BoundedVec { ret } - /// Creates a new vector of equal size by calling a closure on each element in this vector. - /// + /// Creates a new vector of equal size by calling a closure on each element in this vector. + /// /// Example: - /// + /// /// ```noir /// let vec: BoundedVec = BoundedVec::from_array([1, 2, 3, 4]); /// let result = vec.map(|value| value * 2); - /// + /// /// let expected = BoundedVec::from_array([2, 4, 6, 8]); /// assert_eq(result, expected); /// ``` @@ -422,13 +422,15 @@ impl BoundedVec { } } -impl Eq for BoundedVec where T: Eq { +impl Eq for BoundedVec +where + T: Eq, +{ fn eq(self, other: BoundedVec) -> bool { // TODO: https://github.com/noir-lang/noir/issues/4837 // // We make the assumption that the user has used the proper interface for working with `BoundedVec`s // rather than directly manipulating the internal fields as this can result in an inconsistent internal state. - (self.len == other.len) & (self.storage == other.storage) } } @@ -502,7 +504,7 @@ mod bounded_vec_tests { #[test] fn applies_function_that_changes_return_type() { let vec: BoundedVec = BoundedVec::from_array([1, 2, 3, 4]); - let result = vec.map(|value| (value * 2) as Field); + let result = vec.map(|value| (value * 2) as Field); let expected: BoundedVec = BoundedVec::from_array([2, 4, 6, 8]); assert_eq(result, expected); diff --git a/noir/noir-repo/noir_stdlib/src/collections/map.nr b/noir/noir-repo/noir_stdlib/src/collections/map.nr index a336a01d101..cd203c43ad3 100644 --- a/noir/noir-repo/noir_stdlib/src/collections/map.nr +++ b/noir/noir-repo/noir_stdlib/src/collections/map.nr @@ -4,30 +4,30 @@ use crate::default::Default; use crate::hash::{Hash, Hasher, BuildHasher}; use crate::collections::bounded_vec::BoundedVec; -// We use load factor alpha_max = 0.75. -// Upon exceeding it, assert will fail in order to inform the user +// We use load factor alpha_max = 0.75. +// Upon exceeding it, assert will fail in order to inform the user // about performance degradation, so that he can adjust the capacity. global MAX_LOAD_FACTOR_NUMERATOR = 3; global MAX_LOAD_FACTOR_DEN0MINATOR = 4; /// `HashMap` is used to efficiently store and look up key-value pairs. -/// +/// /// `HashMap` is a bounded type which can store anywhere from zero to `MaxLen` total elements. /// Note that due to hash collisions, the actual maximum number of elements stored by any particular /// hashmap is likely lower than `MaxLen`. This is true even with cryptographic hash functions since /// every hash value will be performed modulo `MaxLen`. -/// +/// /// Example: -/// +/// /// ```noir /// // Create a mapping from Fields to u32s with a maximum length of 12 /// // using a poseidon2 hasher /// use std::hash::poseidon2::Poseidon2Hasher; /// let mut map: HashMap> = HashMap::default(); -/// +/// /// map.insert(1, 2); /// map.insert(3, 4); -/// +/// /// let two = map.get(1).unwrap(); /// ``` pub struct HashMap { @@ -36,11 +36,11 @@ pub struct HashMap { /// Amount of valid elements in the map. _len: u32, - _build_hasher: B + _build_hasher: B, } // Data unit in the HashMap table. -// In case Noir adds support for enums in the future, this +// In case Noir adds support for enums in the future, this // should be refactored to have three states: // 1. (key, value) // 2. (empty) @@ -79,7 +79,7 @@ impl Slot { } // Shall not override `_key_value` with Option::none(), - // because we must be able to differentiate empty + // because we must be able to differentiate empty // and deleted slots for lookup. fn mark_deleted(&mut self) { self._is_deleted = true; @@ -87,12 +87,12 @@ impl Slot { } // While conducting lookup, we iterate attempt from 0 to N - 1 due to heuristic, -// that if we have went that far without finding desired, +// that if we have went that far without finding desired, // it is very unlikely to be after - performance will be heavily degraded. impl HashMap { /// Creates a hashmap with an existing `BuildHasher`. This can be used to ensure multiple /// hashmaps are created with the same hasher instance. - /// + /// /// Example: /// /// ```noir @@ -103,7 +103,8 @@ impl HashMap { // docs:start:with_hasher pub fn with_hasher(_build_hasher: B) -> Self where - B: BuildHasher { + B: BuildHasher, + { // docs:end:with_hasher let _table = [Slot::default(); N]; let _len = 0; @@ -111,9 +112,9 @@ impl HashMap { } /// Clears the hashmap, removing all key-value pairs from it. - /// + /// /// Example: - /// + /// /// ```noir /// assert(!map.is_empty()); /// map.clear(); @@ -128,9 +129,9 @@ impl HashMap { /// Returns `true` if the hashmap contains the given key. Unlike `get`, this will not also return /// the value associated with the key. - /// + /// /// Example: - /// + /// /// ```noir /// if map.contains_key(7) { /// let value = map.get(7); @@ -140,28 +141,26 @@ impl HashMap { /// } /// ``` // docs:start:contains_key - pub fn contains_key( - self, - key: K - ) -> bool + pub fn contains_key(self, key: K) -> bool where K: Hash + Eq, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:contains_key self.get(key).is_some() } /// Returns `true` if the length of the hash map is empty. - /// + /// /// Example: - /// + /// /// ```noir /// assert(map.is_empty()); - /// + /// /// map.insert(1, 2); /// assert(!map.is_empty()); - /// + /// /// map.remove(1); /// assert(map.is_empty()); /// ``` @@ -172,14 +171,14 @@ impl HashMap { } /// Returns a vector of each key-value pair present in the hashmap. - /// + /// /// The length of the returned vector is always equal to the length of the hashmap. - /// + /// /// Example: - /// + /// /// ```noir /// let entries = map.entries(); - /// + /// /// // The length of a hashmap may not be compile-time known, so we /// // need to loop over its capacity instead /// for i in 0..map.capacity() { @@ -209,14 +208,14 @@ impl HashMap { } /// Returns a vector of each key present in the hashmap. - /// + /// /// The length of the returned vector is always equal to the length of the hashmap. - /// + /// /// Example: - /// + /// /// ```noir /// let keys = map.keys(); - /// + /// /// for i in 0..keys.max_len() { /// if i < keys.len() { /// let key = keys.get_unchecked(i); @@ -237,21 +236,22 @@ impl HashMap { } } - let msg = f"Amount of valid elements should have been {self._len} times, but got {keys.len()}."; + let msg = + f"Amount of valid elements should have been {self._len} times, but got {keys.len()}."; assert(keys.len() == self._len, msg); keys } /// Returns a vector of each value present in the hashmap. - /// + /// /// The length of the returned vector is always equal to the length of the hashmap. - /// + /// /// Example: - /// + /// /// ```noir /// let values = map.values(); - /// + /// /// for i in 0..values.max_len() { /// if i < values.len() { /// let value = values.get_unchecked(i); @@ -266,14 +266,13 @@ impl HashMap { for slot in self._table { if slot.is_valid() { - let (_, value) = unsafe { - slot.key_value_unchecked() - }; + let (_, value) = unsafe { slot.key_value_unchecked() }; values.push(value); } } - let msg = f"Amount of valid elements should have been {self._len} times, but got {values.len()}."; + let msg = + f"Amount of valid elements should have been {self._len} times, but got {values.len()}."; assert(values.len() == self._len, msg); values @@ -281,29 +280,27 @@ impl HashMap { /// Iterates through each key-value pair of the HashMap, setting each key-value pair to the /// result returned from the given function. - /// + /// /// Note that since keys can be mutated, the HashMap needs to be rebuilt as it is iterated /// through. If this is not desired, use `iter_values_mut` if only values need to be mutated, /// or `entries` if neither keys nor values need to be mutated. - /// + /// /// The iteration order is left unspecified. As a result, if two keys are mutated to become /// equal, which of the two values that will be present for the key in the resulting map is also unspecified. - /// + /// /// Example: - /// + /// /// ```noir /// // Add 1 to each key in the map, and double the value associated with that key. /// map.iter_mut(|k, v| (k + 1, v * 2)); /// ``` // docs:start:iter_mut - pub fn iter_mut( - &mut self, - f: fn(K, V) -> (K, V) - ) + pub fn iter_mut(&mut self, f: fn(K, V) -> (K, V)) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:iter_mut let mut entries = self.entries(); let mut new_map = HashMap::with_hasher(self._build_hasher); @@ -321,29 +318,27 @@ impl HashMap { /// Iterates through the HashMap, mutating each key to the result returned from /// the given function. - /// + /// /// Note that since keys can be mutated, the HashMap needs to be rebuilt as it is iterated /// through. If only iteration is desired and the keys are not intended to be mutated, /// prefer using `entries` instead. - /// + /// /// The iteration order is left unspecified. As a result, if two keys are mutated to become /// equal, which of the two values that will be present for the key in the resulting map is also unspecified. - /// + /// /// Example: - /// + /// /// ```noir /// // Double each key, leaving the value associated with that key untouched /// map.iter_keys_mut(|k| k * 2); /// ``` // docs:start:iter_keys_mut - pub fn iter_keys_mut( - &mut self, - f: fn(K) -> K - ) + pub fn iter_keys_mut(&mut self, f: fn(K) -> K) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:iter_keys_mut let mut entries = self.entries(); let mut new_map = HashMap::with_hasher(self._build_hasher); @@ -362,9 +357,9 @@ impl HashMap { /// Iterates through the HashMap, applying the given function to each value and mutating the /// value to equal the result. This function is more efficient than `iter_mut` and `iter_keys_mut` /// because the keys are untouched and the underlying hashmap thus does not need to be reordered. - /// + /// /// Example: - /// + /// /// ```noir /// // Halve each value /// map.iter_values_mut(|v| v / 2); @@ -384,9 +379,9 @@ impl HashMap { /// Retains only the key-value pairs for which the given function returns true. /// Any key-value pairs for which the function returns false will be removed from the map. - /// + /// /// Example: - /// + /// /// ```noir /// map.retain(|k, v| (k != 0) & (v != 0)); /// ``` @@ -407,22 +402,22 @@ impl HashMap { } /// Returns the current length of this hash map. - /// + /// /// Example: - /// + /// /// ```noir /// // This is equivalent to checking map.is_empty() /// assert(map.len() == 0); - /// + /// /// map.insert(1, 2); /// map.insert(3, 4); /// map.insert(5, 6); /// assert(map.len() == 3); - /// + /// /// // 3 was already present as a key in the hash map, so the length is unchanged /// map.insert(3, 7); /// assert(map.len() == 3); - /// + /// /// map.remove(1); /// assert(map.len() == 2); /// ``` @@ -434,15 +429,15 @@ impl HashMap { /// Returns the maximum capacity of this hashmap. This is always equal to the capacity /// specified in the hashmap's type. - /// + /// /// Unlike hashmaps in general purpose programming languages, hashmaps in Noir have a /// static capacity that does not increase as the map grows larger. Thus, this capacity /// is also the maximum possible element count that can be inserted into the hashmap. /// Due to hash collisions (modulo the hashmap length), it is likely the actual maximum /// element count will be lower than the full capacity. - /// + /// /// Example: - /// + /// /// ```noir /// let empty_map: HashMap> = HashMap::default(); /// assert(empty_map.len() == 0); @@ -455,27 +450,25 @@ impl HashMap { } /// Retrieves a value from the hashmap, returning `Option::none()` if it was not found. - /// + /// /// Example: - /// + /// /// ```noir /// fn get_example(map: HashMap>) { /// let x = map.get(12); - /// + /// /// if x.is_some() { /// assert(x.unwrap() == 42); /// } /// } /// ``` // docs:start:get - pub fn get( - self, - key: K - ) -> Option + pub fn get(self, key: K) -> Option where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:get let mut result = Option::none(); @@ -503,24 +496,21 @@ impl HashMap { /// Inserts a new key-value pair into the map. If the key was already in the map, its /// previous value will be overridden with the newly provided one. - /// + /// /// Example: - /// + /// /// ```noir /// let mut map: HashMap> = HashMap::default(); /// map.insert(12, 42); /// assert(map.len() == 1); /// ``` // docs:start:insert - pub fn insert( - &mut self, - key: K, - value: V - ) + pub fn insert(&mut self, key: K, value: V) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:insert self.assert_load_factor(); @@ -555,30 +545,28 @@ impl HashMap { /// Removes the given key-value pair from the map. If the key was not already present /// in the map, this does nothing. - /// + /// /// Example: - /// + /// /// ```noir /// let mut map: HashMap> = HashMap::default(); /// map.insert(12, 42); /// assert(!map.is_empty()); - /// + /// /// map.remove(12); /// assert(map.is_empty()); - /// + /// /// // If a key was not present in the map, remove does nothing /// map.remove(12); /// assert(map.is_empty()); /// ``` // docs:start:remove - pub fn remove( - &mut self, - key: K - ) + pub fn remove(&mut self, key: K) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:remove let hash = self.hash(key); let mut should_break = false; @@ -603,14 +591,12 @@ impl HashMap { } // Apply HashMap's hasher onto key to obtain pre-hash for probing. - fn hash( - self, - key: K - ) -> u32 + fn hash(self, key: K) -> u32 where K: Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { let mut hasher = self._build_hasher.build_hasher(); key.hash(&mut hasher); hasher.finish() as u32 @@ -619,15 +605,15 @@ impl HashMap { // Probing scheme: quadratic function. // We use 0.5 constant near variadic attempt and attempt^2 monomials. // This ensures good uniformity of distribution for table sizes - // equal to prime numbers or powers of two. + // equal to prime numbers or powers of two. fn quadratic_probe(_self: Self, hash: u32, attempt: u32) -> u32 { (hash + (attempt + attempt * attempt) / 2) % N } - // Amount of elements in the table in relation to available slots exceeds alpha_max. - // To avoid a comparatively more expensive division operation + // Amount of elements in the table in relation to available slots exceeds alpha_max. + // To avoid a comparatively more expensive division operation // we conduct cross-multiplication instead. - // n / m >= MAX_LOAD_FACTOR_NUMERATOR / MAX_LOAD_FACTOR_DEN0MINATOR + // n / m >= MAX_LOAD_FACTOR_NUMERATOR / MAX_LOAD_FACTOR_DEN0MINATOR // n * MAX_LOAD_FACTOR_DEN0MINATOR >= m * MAX_LOAD_FACTOR_NUMERATOR fn assert_load_factor(self) { let lhs = self._len * MAX_LOAD_FACTOR_DEN0MINATOR; @@ -637,8 +623,8 @@ impl HashMap { } } -// Equality class on HashMap has to test that they have -// equal sets of key-value entries, +// Equality class on HashMap has to test that they have +// equal sets of key-value entries, // thus one is a subset of the other and vice versa. // docs:start:eq impl Eq for HashMap @@ -646,21 +632,22 @@ where K: Eq + Hash, V: Eq, B: BuildHasher, - H: Hasher { + H: Hasher, +{ /// Checks if two HashMaps are equal. - /// + /// /// Example: - /// + /// /// ```noir /// let mut map1: HashMap> = HashMap::default(); /// let mut map2: HashMap> = HashMap::default(); - /// + /// /// map1.insert(1, 2); /// map1.insert(3, 4); - /// + /// /// map2.insert(3, 4); /// map2.insert(1, 2); - /// + /// /// assert(map1 == map2); /// ``` fn eq(self, other: HashMap) -> bool { @@ -695,15 +682,16 @@ where impl Default for HashMap where B: BuildHasher + Default, - H: Hasher + Default { + H: Hasher + Default, +{ /// Constructs an empty HashMap. - /// + /// /// Example: - /// + /// /// ```noir /// let hashmap: HashMap> = HashMap::default(); /// assert(hashmap.is_empty()); - /// ``` + /// ``` fn default() -> Self { // docs:end:default let _build_hasher = B::default(); diff --git a/noir/noir-repo/noir_stdlib/src/collections/umap.nr b/noir/noir-repo/noir_stdlib/src/collections/umap.nr index 33010e75560..9b72b6173ca 100644 --- a/noir/noir-repo/noir_stdlib/src/collections/umap.nr +++ b/noir/noir-repo/noir_stdlib/src/collections/umap.nr @@ -17,7 +17,7 @@ pub struct UHashMap { // Amount of valid elements in the map. _len: u32, - _build_hasher: B + _build_hasher: B, } // Data unit in the UHashMap table. @@ -75,7 +75,8 @@ impl UHashMap { // docs:start:with_hasher pub fn with_hasher(_build_hasher: B) -> Self where - B: BuildHasher { + B: BuildHasher, + { // docs:end:with_hasher let _table = &[Slot::default()]; let _len = 0; @@ -84,7 +85,8 @@ impl UHashMap { pub fn with_hasher_and_capacity(_build_hasher: B, capacity: u32) -> Self where - B: BuildHasher { + B: BuildHasher, + { // docs:end:with_hasher let mut _table = &[]; for _ in 0..capacity { @@ -104,18 +106,14 @@ impl UHashMap { // Returns true if the map contains a value for the specified key. // docs:start:contains_key - pub fn contains_key( - self, - key: K - ) -> bool + pub fn contains_key(self, key: K) -> bool where K: Hash + Eq, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:contains_key - unsafe { - self.get(key) - }.is_some() + unsafe { self.get(key) }.is_some() } // Returns true if the map contains no elements. @@ -160,7 +158,8 @@ impl UHashMap { } } - let msg = f"Amount of valid elements should have been {self._len} times, but got {keys.len()}."; + let msg = + f"Amount of valid elements should have been {self._len} times, but got {keys.len()}."; assert(keys.len() == self._len, msg); keys @@ -180,7 +179,8 @@ impl UHashMap { } } - let msg = f"Amount of valid elements should have been {self._len} times, but got {values.len()}."; + let msg = + f"Amount of valid elements should have been {self._len} times, but got {values.len()}."; assert(values.len() == self._len, msg); values @@ -188,14 +188,12 @@ impl UHashMap { // For each key-value entry applies mutator function. // docs:start:iter_mut - pub unconstrained fn iter_mut( - &mut self, - f: fn(K, V) -> (K, V) - ) + pub unconstrained fn iter_mut(&mut self, f: fn(K, V) -> (K, V)) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:iter_mut let mut entries = self.entries(); let mut new_map = UHashMap::with_hasher(self._build_hasher); @@ -210,14 +208,12 @@ impl UHashMap { // For each key applies mutator function. // docs:start:iter_keys_mut - pub unconstrained fn iter_keys_mut( - &mut self, - f: fn(K) -> K - ) + pub unconstrained fn iter_keys_mut(&mut self, f: fn(K) -> K) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:iter_keys_mut let mut entries = self.entries(); let mut new_map = UHashMap::with_hasher(self._build_hasher); @@ -277,14 +273,12 @@ impl UHashMap { // Get the value by key. If it does not exist, returns none(). // docs:start:get - pub unconstrained fn get( - self, - key: K - ) -> Option + pub unconstrained fn get(self, key: K) -> Option where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:get let mut result = Option::none(); @@ -309,15 +303,12 @@ impl UHashMap { // Insert key-value entry. In case key was already present, value is overridden. // docs:start:insert - pub unconstrained fn insert( - &mut self, - key: K, - value: V - ) + pub unconstrained fn insert(&mut self, key: K, value: V) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:insert self.try_resize(); @@ -348,7 +339,11 @@ impl UHashMap { } unconstrained fn try_resize(&mut self) - where B: BuildHasher, K: Eq + Hash, H: Hasher { + where + B: BuildHasher, + K: Eq + Hash, + H: Hasher, + { if self.len() + 1 >= self.capacity() / 2 { let capacity = self.capacity() * 2; let mut new_map = UHashMap::with_hasher_and_capacity(self._build_hasher, capacity); @@ -362,14 +357,12 @@ impl UHashMap { // Removes a key-value entry. If key is not present, UHashMap remains unchanged. // docs:start:remove - pub unconstrained fn remove( - &mut self, - key: K - ) + pub unconstrained fn remove(&mut self, key: K) where K: Eq + Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { // docs:end:remove let hash = self.hash(key); @@ -391,14 +384,12 @@ impl UHashMap { } // Apply UHashMap's hasher onto key to obtain pre-hash for probing. - fn hash( - self, - key: K - ) -> u32 + fn hash(self, key: K) -> u32 where K: Hash, B: BuildHasher, - H: Hasher { + H: Hasher, + { let mut hasher = self._build_hasher.build_hasher(); key.hash(&mut hasher); hasher.finish() as u32 @@ -422,7 +413,8 @@ where K: Eq + Hash, V: Eq, B: BuildHasher, - H: Hasher { + H: Hasher, +{ fn eq(self, other: UHashMap) -> bool { // docs:end:eq let mut equal = false; @@ -433,9 +425,7 @@ where // Not marked as deleted and has key-value. if equal & slot.is_valid() { let (key, value) = slot.key_value_unchecked(); - let other_value = unsafe { - other.get(key) - }; + let other_value = unsafe { other.get(key) }; if other_value.is_none() { equal = false; @@ -457,7 +447,8 @@ where impl Default for UHashMap where B: BuildHasher + Default, - H: Hasher + Default { + H: Hasher + Default, +{ fn default() -> Self { // docs:end:default UHashMap::with_hasher(B::default()) diff --git a/noir/noir-repo/noir_stdlib/src/collections/vec.nr b/noir/noir-repo/noir_stdlib/src/collections/vec.nr index 1e641c384f0..aa019095683 100644 --- a/noir/noir-repo/noir_stdlib/src/collections/vec.nr +++ b/noir/noir-repo/noir_stdlib/src/collections/vec.nr @@ -1,5 +1,5 @@ -pub struct Vec { - pub(crate) slice: [T] +pub struct Vec { + pub(crate) slice: [T], } // 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. @@ -44,7 +44,7 @@ impl Vec { last_elem } - /// Insert an element at a specified index, shifting all elements + /// Insert an element at a specified index, shifting all elements /// after it to the right pub fn insert(&mut self, index: u32, elem: T) { self.slice = self.slice.insert(index, elem); diff --git a/noir/noir-repo/noir_stdlib/src/compat.nr b/noir/noir-repo/noir_stdlib/src/compat.nr index 92e15bae30e..c65246816bf 100644 --- a/noir/noir-repo/noir_stdlib/src/compat.nr +++ b/noir/noir-repo/noir_stdlib/src/compat.nr @@ -1,10 +1,10 @@ comptime global BN254_MODULUS_BE_BYTES: [u8] = &[ - 48, 100, 78, 114, 225, 49, 160, 41, 184, 80, 69, 182, 129, 129, 88, 93, 40, 51, 232, 72, 121, 185, 112, 145, 67, 225, 245, 147, 240, 0, 0, 1 + 48, 100, 78, 114, 225, 49, 160, 41, 184, 80, 69, 182, 129, 129, 88, 93, 40, 51, 232, 72, 121, + 185, 112, 145, 67, 225, 245, 147, 240, 0, 0, 1, ]; pub fn is_bn254() -> bool { - comptime - { + comptime { // We can't use the `Eq` trait here due to limitations on calling non-comptime functions // defined within the same crate. let mut eq = true; diff --git a/noir/noir-repo/noir_stdlib/src/convert.nr b/noir/noir-repo/noir_stdlib/src/convert.nr index a38a54ce365..d4bea8b6390 100644 --- a/noir/noir-repo/noir_stdlib/src/convert.nr +++ b/noir/noir-repo/noir_stdlib/src/convert.nr @@ -15,7 +15,10 @@ pub trait Into { fn into(self) -> T; } -impl Into for U where T: From { +impl Into for U +where + T: From, +{ fn into(self) -> T { T::from(self) } diff --git a/noir/noir-repo/noir_stdlib/src/default.nr b/noir/noir-repo/noir_stdlib/src/default.nr index 00bb278fd48..01f10a368b1 100644 --- a/noir/noir-repo/noir_stdlib/src/default.nr +++ b/noir/noir-repo/noir_stdlib/src/default.nr @@ -79,7 +79,10 @@ impl Default for bool { } } -impl Default for [T; N] where T: Default { +impl Default for [T; N] +where + T: Default, +{ fn default() -> [T; N] { [T::default(); N] } @@ -91,25 +94,47 @@ impl Default for [T] { } } -impl Default for (A, B) where A: Default, B: Default { +impl Default for (A, B) +where + A: Default, + B: Default, +{ fn default() -> (A, B) { (A::default(), B::default()) } } -impl Default for (A, B, C) where A: Default, B: Default, C: Default { +impl Default for (A, B, C) +where + A: Default, + B: Default, + C: Default, +{ fn default() -> (A, B, C) { (A::default(), B::default(), C::default()) } } -impl Default for (A, B, C, D) where A: Default, B: Default, C: Default, D: Default { +impl Default for (A, B, C, D) +where + A: Default, + B: Default, + C: Default, + D: Default, +{ fn default() -> (A, B, C, D) { (A::default(), B::default(), C::default(), D::default()) } } -impl Default for (A, B, C, D, E) where A: Default, B: Default, C: Default, D: Default, E: Default { +impl Default for (A, B, C, D, E) +where + A: Default, + B: Default, + C: Default, + D: Default, + E: Default, +{ fn default() -> (A, B, C, D, E) { (A::default(), B::default(), C::default(), D::default(), E::default()) } diff --git a/noir/noir-repo/noir_stdlib/src/ec/consts/te.nr b/noir/noir-repo/noir_stdlib/src/ec/consts/te.nr index f2425f6a786..561c16e846a 100644 --- a/noir/noir-repo/noir_stdlib/src/ec/consts/te.nr +++ b/noir/noir-repo/noir_stdlib/src/ec/consts/te.nr @@ -19,15 +19,15 @@ pub fn baby_jubjub() -> BabyJubjub { // G TEPoint::new( 995203441582195749578291179787384436505546430278305826713579947235728471134, - 5472060717959818805561601436314318772137091100104008585924551046643952123905 - ) + 5472060717959818805561601436314318772137091100104008585924551046643952123905, + ), ), // [8]G precalculated base8: TEPoint::new( 5299619240641551281634865583518297030282874472190772894086521144482721001553, - 16950150798460657717958625567821834550301663161624707787222815936182638968203 + 16950150798460657717958625567821834550301663161624707787222815936182638968203, ), // The size of the group formed from multiplying the base field by 8. - suborder: 2736030358979909402780800718157159386076813972158567259200215660948447373041 + suborder: 2736030358979909402780800718157159386076813972158567259200215660948447373041, } } diff --git a/noir/noir-repo/noir_stdlib/src/ec/mod.nr b/noir/noir-repo/noir_stdlib/src/ec/mod.nr index 112f39f74eb..b62bc99d9c8 100644 --- a/noir/noir-repo/noir_stdlib/src/ec/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/ec/mod.nr @@ -115,7 +115,7 @@ pub mod consts; // Commonly used curve presets // the curve. // // For details on all of the above in the context of hashing to elliptic curves, see . -// +// // // *TODO: Replace Field with Bigint. // **TODO: Support arrays of structs to make this work. @@ -133,18 +133,22 @@ global C5 = 19103219067921713944291392827692070036145651957329286315305642004821 //fn bit_mul(add: fn(T,T) -> T, e: T, bits: [u1; N], p: T) -> T { // let mut out = e; // let n = bits.len(); -// +// // for i in 0..n { // out = add( // add(out, out), // if(bits[n - i - 1] == 0) {e} else {p}); // } -// +// // out //} // TODO: Make this built-in. pub fn safe_inverse(x: Field) -> Field { - if x == 0 { 0 } else { 1 / x } + if x == 0 { + 0 + } else { + 1 / x + } } // Boolean indicating whether Field element is a square, i.e. whether there exists a y in Field s.t. x = y*y. pub fn is_square(x: Field) -> bool { @@ -160,7 +164,7 @@ pub fn pow(x: Field, y: Field) -> Field { for i in 0..254 { r *= r; - r *= (b[254 - 1 - i] as Field)*x + (1-b[254 - 1 - i] as Field); + r *= (b[254 - 1 - i] as Field) * x + (1 - b[254 - 1 - i] as Field); } r diff --git a/noir/noir-repo/noir_stdlib/src/ec/montcurve.nr b/noir/noir-repo/noir_stdlib/src/ec/montcurve.nr index 11b6a964c2d..6c83feb1607 100644 --- a/noir/noir-repo/noir_stdlib/src/ec/montcurve.nr +++ b/noir/noir-repo/noir_stdlib/src/ec/montcurve.nr @@ -19,13 +19,13 @@ pub mod affine { pub j: Field, pub k: Field, // Generator as point in Cartesian coordinates - pub gen: Point + pub gen: Point, } // Point in Cartesian coordinates pub struct Point { pub x: Field, pub y: Field, - pub infty: bool // Indicator for point at infinity + pub infty: bool, // Indicator for point at infinity } impl Point { @@ -44,7 +44,7 @@ pub mod affine { if self.is_zero() { curvegroup::Point::zero() } else { - let (x,y) = (self.x, self.y); + let (x, y) = (self.x, self.y); curvegroup::Point::new(x, y, 1) } } @@ -56,14 +56,14 @@ pub mod affine { // Negation pub fn negate(self) -> Self { - let Self {x, y, infty} = self; + let Self { x, y, infty } = self; Self { x, y: 0 - y, infty } } // Map into equivalent Twisted Edwards curve pub fn into_tecurve(self) -> TEPoint { - let Self {x, y, infty} = self; + let Self { x, y, infty } = self; if infty | (y * (x + 1) == 0) { TEPoint::zero() @@ -101,8 +101,8 @@ pub mod affine { // Membership check pub fn contains(self, p: Point) -> bool { - let Self {j, k, gen: _gen} = self; - let Point {x, y, infty: infty} = p; + let Self { j, k, gen: _gen } = self; + let Point { x, y, infty } = p; infty | (k * y * y == x * (x * x + j * x + 1)) } @@ -141,7 +141,7 @@ pub mod affine { // Conversion to equivalent Twisted Edwards curve pub fn into_tecurve(self) -> TECurve { - let Self {j, k, gen} = self; + let Self { j, k, gen } = self; TECurve::new((j + 2) / k, (j - 2) / k, gen.into_tecurve()) } @@ -166,7 +166,7 @@ pub mod affine { // Point mapping from equivalent Short Weierstrass curve pub fn map_from_swcurve(self, p: SWPoint) -> Point { - let SWPoint {x, y, infty} = p; + let SWPoint { x, y, infty } = p; let j = self.j; let k = self.k; @@ -178,7 +178,6 @@ pub mod affine { let j = self.j; let k = self.k; let z = ZETA; // Non-square Field element required for map - // Check whether curve is admissible assert(j != 0); let l = (j * j - 4) / (k * k); @@ -195,10 +194,18 @@ pub mod affine { let y = if is_square(gx1) { let y0 = sqrt(gx1); - if y0.sgn0() == 1 { y0 } else { 0 - y0 } + if y0.sgn0() == 1 { + y0 + } else { + 0 - y0 + } } else { let y0 = sqrt(gx2); - if y0.sgn0() == 0 { y0 } else { 0 - y0 } + if y0.sgn0() == 0 { + y0 + } else { + 0 - y0 + } }; Point::new(x * k, y * k) @@ -226,13 +233,13 @@ pub mod curvegroup { pub j: Field, pub k: Field, // Generator as point in projective coordinates - pub gen: Point + pub gen: Point, } // Point in projective coordinates pub struct Point { pub x: Field, pub y: Field, - pub z: Field + pub z: Field, } impl Point { @@ -251,7 +258,7 @@ pub mod curvegroup { if self.is_zero() { affine::Point::zero() } else { - let (x,y,z) = (self.x, self.y, self.z); + let (x, y, z) = (self.x, self.y, self.z); affine::Point::new(x / z, y / z) } } @@ -263,7 +270,7 @@ pub mod curvegroup { // Negation pub fn negate(self) -> Self { - let Self {x, y, z} = self; + let Self { x, y, z } = self; Point::new(x, 0 - y, z) } @@ -303,8 +310,8 @@ pub mod curvegroup { // Membership check pub fn contains(self, p: Point) -> bool { - let Self {j, k, gen: _gen} = self; - let Point {x, y, z} = p; + let Self { j, k, gen: _gen } = self; + let Point { x, y, z } = p; k * y * y * z == x * (x * x + j * x * z + z * z) } @@ -343,7 +350,7 @@ pub mod curvegroup { // Conversion to equivalent Twisted Edwards curve pub fn into_tecurve(self) -> TECurve { - let Self {j, k, gen} = self; + let Self { j, k, gen } = self; TECurve::new((j + 2) / k, (j - 2) / k, gen.into_tecurve()) } diff --git a/noir/noir-repo/noir_stdlib/src/ec/swcurve.nr b/noir/noir-repo/noir_stdlib/src/ec/swcurve.nr index 6e1054ad84e..145b2506f73 100644 --- a/noir/noir-repo/noir_stdlib/src/ec/swcurve.nr +++ b/noir/noir-repo/noir_stdlib/src/ec/swcurve.nr @@ -15,13 +15,13 @@ pub mod affine { pub a: Field, pub b: Field, // Generator as point in Cartesian coordinates - pub gen: Point + pub gen: Point, } // Point in Cartesian coordinates pub struct Point { pub x: Field, pub y: Field, - pub infty: bool // Indicator for point at infinity + pub infty: bool, // Indicator for point at infinity } impl Point { @@ -37,7 +37,7 @@ pub mod affine { // Conversion to CurveGroup coordinates pub fn into_group(self) -> curvegroup::Point { - let Self {x, y, infty} = self; + let Self { x, y, infty } = self; if infty { curvegroup::Point::zero() @@ -53,15 +53,15 @@ pub mod affine { // Negation pub fn negate(self) -> Self { - let Self {x, y, infty} = self; + let Self { x, y, infty } = self; Self { x, y: 0 - y, infty } } } impl Eq for Point { fn eq(self, p: Self) -> bool { - let Self {x: x1, y: y1, infty: inf1} = self; - let Self {x: x2, y: y2, infty: inf2} = p; + let Self { x: x1, y: y1, infty: inf1 } = self; + let Self { x: x2, y: y2, infty: inf2 } = p; (inf1 & inf2) | (!inf1 & !inf2 & (x1 == x2) & (y1 == y2)) } @@ -83,14 +83,14 @@ pub mod affine { // Conversion to CurveGroup coordinates pub fn into_group(self) -> curvegroup::Curve { - let Curve{a, b, gen} = self; + let Curve { a, b, gen } = self; curvegroup::Curve { a, b, gen: gen.into_group() } } // Membership check pub fn contains(self, p: Point) -> bool { - let Point {x, y, infty} = p; + let Point { x, y, infty } = p; infty | (y * y == x * x * x + self.a * x + self.b) } @@ -106,8 +106,8 @@ pub mod affine { } else if p2.is_zero() { p1.into_group() } else { - let Point {x: x1, y: y1, infty: _inf} = p1; - let curvegroup::Point {x: x2, y: y2, z: z2} = p2; + let Point { x: x1, y: y1, infty: _inf } = p1; + let curvegroup::Point { x: x2, y: y2, z: z2 } = p2; let you1 = x1 * z2 * z2; let you2 = x2; let s1 = y1 * z2 * z2 * z2; @@ -165,7 +165,7 @@ pub mod affine { // Check whether curve is admissible assert(self.a * self.b != 0); - let Curve {a, b, gen: _gen} = self; + let Curve { a, b, gen: _gen } = self; let tv1 = safe_inverse(z * z * u * u * u * u + u * u * z); let x1 = if tv1 == 0 { @@ -176,7 +176,7 @@ pub mod affine { let gx1 = x1 * x1 * x1 + a * x1 + b; let x2 = z * u * u * x1; let gx2 = x2 * x2 * x2 + a * x2 + b; - let (x,y) = if is_square(gx1) { + let (x, y) = if is_square(gx1) { (x1, sqrt(gx1)) } else { (x2, sqrt(gx2)) @@ -199,13 +199,13 @@ pub mod curvegroup { pub a: Field, pub b: Field, // Generator as point in Cartesian coordinates - pub gen: Point + pub gen: Point, } // Point in three-dimensional Jacobian coordinates pub struct Point { pub x: Field, pub y: Field, - pub z: Field // z = 0 corresponds to point at infinity. + pub z: Field, // z = 0 corresponds to point at infinity. } impl Point { @@ -221,7 +221,7 @@ pub mod curvegroup { // Conversion to affine coordinates pub fn into_affine(self) -> affine::Point { - let Self {x, y, z} = self; + let Self { x, y, z } = self; if z == 0 { affine::Point::zero() @@ -237,20 +237,23 @@ pub mod curvegroup { // Negation pub fn negate(self) -> Self { - let Self {x, y, z} = self; + let Self { x, y, z } = self; Self { x, y: 0 - y, z } } } impl Eq for Point { fn eq(self, p: Self) -> bool { - let Self {x: x1, y: y1, z: z1} = self; - let Self {x: x2, y: y2, z: z2} = p; + let Self { x: x1, y: y1, z: z1 } = self; + let Self { x: x2, y: y2, z: z2 } = p; - ((z1 == 0) & (z2 == 0)) | ((z1 != 0) - & (z2 != 0) - & (x1 * z2 * z2 == x2 * z1 * z1) - & (y1 * z2 * z2 * z2 == y2 * z1 * z1 * z1)) + ((z1 == 0) & (z2 == 0)) + | ( + (z1 != 0) + & (z2 != 0) + & (x1 * z2 * z2 == x2 * z1 * z1) + & (y1 * z2 * z2 * z2 == y2 * z1 * z1 * z1) + ) } } @@ -270,14 +273,14 @@ pub mod curvegroup { // Conversion to affine coordinates pub fn into_affine(self) -> affine::Curve { - let Curve{a, b, gen} = self; + let Curve { a, b, gen } = self; affine::Curve { a, b, gen: gen.into_affine() } } // Membership check pub fn contains(self, p: Point) -> bool { - let Point {x, y, z} = p; + let Point { x, y, z } = p; if z == 0 { true } else { @@ -292,8 +295,8 @@ pub mod curvegroup { } else if p2.is_zero() { p1 } else { - let Point {x: x1, y: y1, z: z1} = p1; - let Point {x: x2, y: y2, z: z2} = p2; + let Point { x: x1, y: y1, z: z1 } = p1; + let Point { x: x2, y: y2, z: z2 } = p2; let you1 = x1 * z2 * z2; let you2 = x2 * z1 * z1; let s1 = y1 * z2 * z2 * z2; @@ -319,7 +322,7 @@ pub mod curvegroup { // Point doubling pub fn double(self, p: Point) -> Point { - let Point {x, y, z} = p; + let Point { x, y, z } = p; if p.is_zero() { p @@ -344,7 +347,12 @@ pub mod curvegroup { for i in 0..N { out = self.add( self.add(out, out), - if(bits[N - i - 1] == 0) {Point::zero()} else {p}); + if (bits[N - i - 1] == 0) { + Point::zero() + } else { + p + }, + ); } out diff --git a/noir/noir-repo/noir_stdlib/src/ec/tecurve.nr b/noir/noir-repo/noir_stdlib/src/ec/tecurve.nr index 0eb1521b19d..0088896015d 100644 --- a/noir/noir-repo/noir_stdlib/src/ec/tecurve.nr +++ b/noir/noir-repo/noir_stdlib/src/ec/tecurve.nr @@ -17,12 +17,12 @@ pub mod affine { pub a: Field, pub d: Field, // Generator as point in Cartesian coordinates - pub gen: Point + pub gen: Point, } // Point in Cartesian coordinates pub struct Point { pub x: Field, - pub y: Field + pub y: Field, } impl Point { @@ -39,7 +39,7 @@ pub mod affine { // Conversion to CurveGroup coordinates pub fn into_group(self) -> curvegroup::Point { - let Self {x, y} = self; + let Self { x, y } = self; curvegroup::Point::new(x, y, x * y, 1) } @@ -51,7 +51,7 @@ pub mod affine { // Negation pub fn negate(self) -> Self { - let Self {x, y} = self; + let Self { x, y } = self; Point::new(0 - x, y) } @@ -60,7 +60,7 @@ pub mod affine { if self.is_zero() { MPoint::zero() } else { - let Self {x, y} = self; + let Self { x, y } = self; let x0 = (1 + y) / (1 - y); let y0 = (1 + y) / (x * (1 - y)); @@ -71,8 +71,8 @@ pub mod affine { impl Eq for Point { fn eq(self, p: Self) -> bool { - let Self {x: x1, y: y1} = self; - let Self {x: x2, y: y2} = p; + let Self { x: x1, y: y1 } = self; + let Self { x: x2, y: y2 } = p; (x1 == x2) & (y1 == y2) } @@ -94,14 +94,14 @@ pub mod affine { // Conversion to CurveGroup coordinates pub fn into_group(self) -> curvegroup::Curve { - let Curve{a, d, gen} = self; + let Curve { a, d, gen } = self; curvegroup::Curve { a, d, gen: gen.into_group() } } // Membership check pub fn contains(self, p: Point) -> bool { - let Point {x, y} = p; + let Point { x, y } = p; self.a * x * x + y * y == 1 + self.d * x * x * y * y } @@ -112,8 +112,8 @@ pub mod affine { // Mixed point addition, i.e. first argument in affine, second in CurveGroup coordinates. pub fn mixed_add(self, p1: Point, p2: curvegroup::Point) -> curvegroup::Point { - let Point{x: x1, y: y1} = p1; - let curvegroup::Point{x: x2, y: y2, t: t2, z: z2} = p2; + let Point { x: x1, y: y1 } = p1; + let curvegroup::Point { x: x2, y: y2, t: t2, z: z2 } = p2; let a = x1 * x2; let b = y1 * y2; @@ -210,14 +210,14 @@ pub mod curvegroup { pub a: Field, pub d: Field, // Generator as point in projective coordinates - pub gen: Point + pub gen: Point, } // Point in extended twisted Edwards coordinates pub struct Point { pub x: Field, pub y: Field, pub t: Field, - pub z: Field + pub z: Field, } impl Point { @@ -228,13 +228,13 @@ pub mod curvegroup { // Check if zero pub fn is_zero(self) -> bool { - let Self {x, y, t, z} = self; + let Self { x, y, t, z } = self; (x == 0) & (y == z) & (y != 0) & (t == 0) } // Conversion to affine coordinates pub fn into_affine(self) -> affine::Point { - let Self {x, y, t: _t, z} = self; + let Self { x, y, t: _t, z } = self; affine::Point::new(x / z, y / z) } @@ -246,7 +246,7 @@ pub mod curvegroup { // Negation pub fn negate(self) -> Self { - let Self {x, y, t, z} = self; + let Self { x, y, t, z } = self; Point::new(0 - x, y, 0 - t, z) } @@ -259,8 +259,8 @@ pub mod curvegroup { impl Eq for Point { fn eq(self, p: Self) -> bool { - let Self {x: x1, y: y1, t: _t1, z: z1} = self; - let Self {x: x2, y: y2, t: _t2, z:z2} = p; + let Self { x: x1, y: y1, t: _t1, z: z1 } = self; + let Self { x: x2, y: y2, t: _t2, z: z2 } = p; (x1 * z2 == x2 * z1) & (y1 * z2 == y2 * z1) } @@ -282,14 +282,14 @@ pub mod curvegroup { // Conversion to affine coordinates pub fn into_affine(self) -> affine::Curve { - let Curve{a, d, gen} = self; + let Curve { a, d, gen } = self; affine::Curve { a, d, gen: gen.into_affine() } } // Membership check pub fn contains(self, p: Point) -> bool { - let Point {x, y, t, z} = p; + let Point { x, y, t, z } = p; (z != 0) & (z * t == x * y) @@ -298,8 +298,8 @@ pub mod curvegroup { // Point addition 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; + let Point { x: x1, y: y1, t: t1, z: z1 } = p1; + let Point { x: x2, y: y2, t: t2, z: z2 } = p2; let a = x1 * x2; let b = y1 * y2; @@ -320,7 +320,7 @@ pub mod curvegroup { // Point doubling, cf. section 3.3 pub fn double(self, p: Point) -> Point { - let Point{x, y, t: _t, z} = p; + let Point { x, y, t: _t, z } = p; let a = x * x; let b = y * y; @@ -347,7 +347,12 @@ pub mod curvegroup { for i in 0..N { out = self.add( self.add(out, out), - if(bits[N - i - 1] == 0) {Point::zero()} else {p}); + if (bits[N - i - 1] == 0) { + Point::zero() + } else { + p + }, + ); } out diff --git a/noir/noir-repo/noir_stdlib/src/ecdsa_secp256k1.nr b/noir/noir-repo/noir_stdlib/src/ecdsa_secp256k1.nr index 8a70184dca8..ec39e999715 100644 --- a/noir/noir-repo/noir_stdlib/src/ecdsa_secp256k1.nr +++ b/noir/noir-repo/noir_stdlib/src/ecdsa_secp256k1.nr @@ -4,7 +4,7 @@ pub fn verify_signature( public_key_x: [u8; 32], public_key_y: [u8; 32], signature: [u8; 64], - message_hash: [u8; N] + message_hash: [u8; N], ) -> bool // docs:end:ecdsa_secp256k1 {} @@ -15,7 +15,7 @@ pub fn verify_signature_slice( public_key_x: [u8; 32], public_key_y: [u8; 32], signature: [u8; 64], - message_hash: [u8] + message_hash: [u8], ) -> bool // docs:end:ecdsa_secp256k1_slice {} diff --git a/noir/noir-repo/noir_stdlib/src/ecdsa_secp256r1.nr b/noir/noir-repo/noir_stdlib/src/ecdsa_secp256r1.nr index 8772fa7c2ca..c7905b24f6f 100644 --- a/noir/noir-repo/noir_stdlib/src/ecdsa_secp256r1.nr +++ b/noir/noir-repo/noir_stdlib/src/ecdsa_secp256r1.nr @@ -4,7 +4,7 @@ pub fn verify_signature( public_key_x: [u8; 32], public_key_y: [u8; 32], signature: [u8; 64], - message_hash: [u8; N] + message_hash: [u8; N], ) -> bool // docs:end:ecdsa_secp256r1 {} @@ -15,7 +15,7 @@ pub fn verify_signature_slice( public_key_x: [u8; 32], public_key_y: [u8; 32], signature: [u8; 64], - message_hash: [u8] + message_hash: [u8], ) -> bool // docs:end:ecdsa_secp256r1_slice {} diff --git a/noir/noir-repo/noir_stdlib/src/eddsa.nr b/noir/noir-repo/noir_stdlib/src/eddsa.nr index cfdbbe9c3d0..89a0b05b072 100644 --- a/noir/noir-repo/noir_stdlib/src/eddsa.nr +++ b/noir/noir-repo/noir_stdlib/src/eddsa.nr @@ -11,7 +11,7 @@ pub fn eddsa_poseidon_verify( signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, - message: Field + message: Field, ) -> bool { eddsa_verify::( pub_key_x, @@ -19,7 +19,7 @@ pub fn eddsa_poseidon_verify( signature_s, signature_r8_x, signature_r8_y, - message + message, ) } @@ -29,9 +29,11 @@ pub fn eddsa_verify( signature_s: Field, signature_r8_x: Field, signature_r8_y: Field, - message: Field -) -> bool -where H: Hasher + Default { + message: Field, +) -> bool +where + H: Hasher + Default, +{ // Verifies by testing: // S * B8 = R8 + H(R8, A, m) * A8 let bjj = baby_jubjub(); diff --git a/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr b/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr index ad7196b4494..dd5e4285c00 100644 --- a/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr +++ b/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr @@ -7,7 +7,7 @@ use crate::cmp::Eq; pub struct EmbeddedCurvePoint { pub x: Field, pub y: Field, - pub is_infinite: bool + pub is_infinite: bool, } impl EmbeddedCurvePoint { @@ -68,7 +68,7 @@ impl EmbeddedCurveScalar { #[field(bn254)] pub fn from_field(scalar: Field) -> EmbeddedCurveScalar { - let (a,b) = crate::field::bn254::decompose(scalar); + let (a, b) = crate::field::bn254::decompose(scalar); EmbeddedCurveScalar { lo: a, hi: b } } @@ -79,8 +79,8 @@ impl EmbeddedCurveScalar { let mut lo = 0 as Field; let mut hi = 0 as Field; for i in 0..16 { - lo = lo + (bytes[offset+31 - i] as Field) * v; - hi = hi + (bytes[offset+15 - i] as Field) * v; + lo = lo + (bytes[offset + 31 - i] as Field) * v; + hi = hi + (bytes[offset + 15 - i] as Field) * v; v = v * 256; } let sig_s = crate::embedded_curve_ops::EmbeddedCurveScalar { lo, hi }; @@ -98,12 +98,12 @@ impl Eq for EmbeddedCurveScalar { // For bn254, We have Grumpkin and Baby JubJub. // For bls12-381, we have JubJub and Bandersnatch. // -// The embedded curve being used is decided by the +// The embedded curve being used is decided by the // underlying proof system. // docs:start:multi_scalar_mul pub fn multi_scalar_mul( points: [EmbeddedCurvePoint; N], - scalars: [EmbeddedCurveScalar; N] + scalars: [EmbeddedCurveScalar; N], ) -> EmbeddedCurvePoint // docs:end:multi_scalar_mul { @@ -112,16 +112,20 @@ pub fn multi_scalar_mul( } #[foreign(multi_scalar_mul)] -fn multi_scalar_mul_array_return(points: [EmbeddedCurvePoint; N], scalars: [EmbeddedCurveScalar; N]) -> [Field; 3] {} - -#[foreign(multi_scalar_mul)] -pub(crate) fn multi_scalar_mul_slice(points: [EmbeddedCurvePoint], scalars: [EmbeddedCurveScalar]) -> [Field; 3] {} +pub(crate) fn multi_scalar_mul_array_return( + points: [EmbeddedCurvePoint; N], + scalars: [EmbeddedCurveScalar; N], +) -> [Field; 3] {} // docs:start:fixed_base_scalar_mul pub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint // docs:end:fixed_base_scalar_mul { - let g1 = EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let g1 = EmbeddedCurvePoint { + x: 1, + y: 17631683881184975370165255887551781615748388533673675138860, + is_infinite: false, + }; multi_scalar_mul([g1], [scalar]) } @@ -130,13 +134,20 @@ pub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint // This is a hack because returning an `EmbeddedCurvePoint` from a foreign function in brillig returns a [BrilligVariable::SingleAddr; 2] rather than BrilligVariable::BrilligArray // as is defined in the brillig bytecode format. This is a workaround which allows us to fix this without modifying the serialization format. // docs:start:embedded_curve_add -pub fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { +pub fn embedded_curve_add( + point1: EmbeddedCurvePoint, + point2: EmbeddedCurvePoint, +) -> EmbeddedCurvePoint { // docs:end:embedded_curve_add let x_coordinates_match = point1.x == point2.x; let y_coordinates_match = point1.y == point2.y; let double_predicate = (x_coordinates_match & y_coordinates_match); let infinity_predicate = (x_coordinates_match & !y_coordinates_match); - let point1_1 = EmbeddedCurvePoint { x: point1.x + (x_coordinates_match as Field), y: point1.y, is_infinite: x_coordinates_match }; + let point1_1 = EmbeddedCurvePoint { + x: point1.x + (x_coordinates_match as Field), + y: point1.y, + is_infinite: x_coordinates_match, + }; // point1_1 is guaranteed to have a different abscissa than point2 let mut result = embedded_curve_add_unsafe(point1_1, point2); result.is_infinite = x_coordinates_match; @@ -147,7 +158,7 @@ pub fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint // infinity if x_match, !y_match if point1.is_infinite { - result= point2; + result = point2; } if point2.is_infinite { result = point1; @@ -158,7 +169,10 @@ pub fn embedded_curve_add(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint } #[foreign(embedded_curve_add)] -fn embedded_curve_add_array_return(_point1: EmbeddedCurvePoint, _point2: EmbeddedCurvePoint) -> [Field; 3] {} +fn embedded_curve_add_array_return( + _point1: EmbeddedCurvePoint, + _point2: EmbeddedCurvePoint, +) -> [Field; 3] {} /// This function assumes that: /// The points are on the curve, and @@ -166,7 +180,10 @@ fn embedded_curve_add_array_return(_point1: EmbeddedCurvePoint, _point2: Embedde /// Neither point is the infinity point. /// If it is used with correct input, the function ensures the correct non-zero result is returned. /// Except for points on the curve, the other assumptions are checked by the function. It will cause assertion failure if they are not respected. -pub fn embedded_curve_add_not_nul(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { +pub fn embedded_curve_add_not_nul( + point1: EmbeddedCurvePoint, + point2: EmbeddedCurvePoint, +) -> EmbeddedCurvePoint { assert(point1.x != point2.x); assert(!point1.is_infinite); assert(!point2.is_infinite); @@ -178,7 +195,10 @@ pub fn embedded_curve_add_not_nul(point1: EmbeddedCurvePoint, point2: EmbeddedCu /// If they have the same value but are different variables, the result will be incorrect because in this case /// it assumes (but does not check) that the points' x-coordinates are not equal. /// It also assumes neither point is the infinity point. -pub fn embedded_curve_add_unsafe(point1: EmbeddedCurvePoint, point2: EmbeddedCurvePoint) -> EmbeddedCurvePoint { +pub fn embedded_curve_add_unsafe( + point1: EmbeddedCurvePoint, + point2: EmbeddedCurvePoint, +) -> EmbeddedCurvePoint { let point_array = embedded_curve_add_array_return(point1, point2); let x = point_array[0]; let y = point_array[1]; diff --git a/noir/noir-repo/noir_stdlib/src/field/bn254.nr b/noir/noir-repo/noir_stdlib/src/field/bn254.nr index 9349e67aed3..356b47e63cf 100644 --- a/noir/noir-repo/noir_stdlib/src/field/bn254.nr +++ b/noir/noir-repo/noir_stdlib/src/field/bn254.nr @@ -140,7 +140,9 @@ pub fn lt(a: Field, b: Field) -> bool { mod tests { // TODO: Allow imports from "super" - use crate::field::bn254::{decompose, compute_lt, assert_gt, gt, TWO_POW_128, compute_lte, PLO, PHI}; + use crate::field::bn254::{ + decompose, compute_lt, assert_gt, gt, TWO_POW_128, compute_lte, PLO, PHI, + }; #[test] fn check_decompose() { diff --git a/noir/noir-repo/noir_stdlib/src/field/mod.nr b/noir/noir-repo/noir_stdlib/src/field/mod.nr index 4a329aaeb59..915ea8f939e 100644 --- a/noir/noir-repo/noir_stdlib/src/field/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/field/mod.nr @@ -51,9 +51,9 @@ impl Field { /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array /// This array will be zero padded should not all bytes be necessary to represent `self`. - /// + /// /// # Failures - /// The length N of the array must be big enough to contain all the bytes of the 'self', + /// The length N of the array must be big enough to contain all the bytes of the 'self', /// and no more than the number of bytes required to represent the field modulus /// /// # Safety @@ -66,7 +66,7 @@ impl Field { if !is_unconstrained() { // Ensure that the byte decomposition does not overflow the modulus - let p = modulus_le_bytes(); + let p = modulus_le_bytes(); assert(bytes.len() <= p.len()); let mut ok = bytes.len() != p.len(); for i in 0..N { @@ -84,9 +84,9 @@ impl Field { /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus /// This array will be zero padded should not all bytes be necessary to represent `self`. - /// + /// /// # Failures - /// The length N of the array must be big enough to contain all the bytes of the 'self', + /// The length N of the array must be big enough to contain all the bytes of the 'self', /// and no more than the number of bytes required to represent the field modulus /// /// # Safety @@ -99,7 +99,7 @@ impl Field { if !is_unconstrained() { // Ensure that the byte decomposition does not overflow the modulus - let p = modulus_be_bytes(); + let p = modulus_be_bytes(); assert(bytes.len() <= p.len()); let mut ok = bytes.len() != p.len(); for i in 0..N { @@ -151,7 +151,7 @@ impl Field { for i in 1..33 { r *= r; - r = (b[32-i] as Field) * (r * self) + (1 - b[32-i] as Field) * r; + r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r; } r } @@ -189,7 +189,7 @@ impl Field { let mut result = 0; for i in 0..N { - result += (bytes[N-1-i] as Field) * v; + result += (bytes[N - 1 - i] as Field) * v; v = v * 256; } result diff --git a/noir/noir-repo/noir_stdlib/src/hash/keccak.nr b/noir/noir-repo/noir_stdlib/src/hash/keccak.nr index 37eb4dfe8a6..50fbab8a416 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/keccak.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/keccak.nr @@ -44,7 +44,7 @@ pub(crate) fn keccak256(input: [u8; N], message_size: u32) -> [u8; 3 let mut sliced = 0; let mut v = 1; for k in 0..WORD_SIZE { - sliced += v * (block_bytes[limb_start+k] as Field); + sliced += v * (block_bytes[limb_start + k] as Field); v *= 256; } @@ -52,7 +52,7 @@ pub(crate) fn keccak256(input: [u8; N], message_size: u32) -> [u8; 3 } //2. sponge_absorb - let mut state : [u64; NUM_KECCAK_LANES]= [0; NUM_KECCAK_LANES]; + let mut state: [u64; NUM_KECCAK_LANES] = [0; NUM_KECCAK_LANES]; // When in an unconstrained runtime we can take advantage of runtime loop bounds, // thus allowing us to simplify the loop body. if is_unconstrained() { @@ -92,7 +92,7 @@ pub(crate) fn keccak256(input: [u8; N], message_size: u32) -> [u8; 3 let lane = state[i] as Field; let lane_le: [u8; 8] = lane.to_le_bytes(); for j in 0..8 { - result[8*i+j] = lane_le[j]; + result[8 * i + j] = lane_le[j]; } } result @@ -105,7 +105,9 @@ mod tests { fn smoke_test() { let input = [0xbd]; let result = [ - 0x5a, 0x50, 0x2f, 0x9f, 0xca, 0x46, 0x7b, 0x26, 0x6d, 0x5b, 0x78, 0x33, 0x65, 0x19, 0x37, 0xe8, 0x05, 0x27, 0x0c, 0xa3, 0xf3, 0xaf, 0x1c, 0x0d, 0xd2, 0x46, 0x2d, 0xca, 0x4b, 0x3b, 0x1a, 0xbf + 0x5a, 0x50, 0x2f, 0x9f, 0xca, 0x46, 0x7b, 0x26, 0x6d, 0x5b, 0x78, 0x33, 0x65, 0x19, + 0x37, 0xe8, 0x05, 0x27, 0x0c, 0xa3, 0xf3, 0xaf, 0x1c, 0x0d, 0xd2, 0x46, 0x2d, 0xca, + 0x4b, 0x3b, 0x1a, 0xbf, ]; assert_eq(keccak256(input, input.len()), result); } @@ -115,7 +117,9 @@ mod tests { // "hello world" let input = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33]; let result = [ - 0xec, 0xd0, 0xe1, 0x8, 0xa9, 0x8e, 0x19, 0x2a, 0xf1, 0xd2, 0xc2, 0x50, 0x55, 0xf4, 0xe3, 0xbe, 0xd7, 0x84, 0xb5, 0xc8, 0x77, 0x20, 0x4e, 0x73, 0x21, 0x9a, 0x52, 0x3, 0x25, 0x1f, 0xea, 0xab + 0xec, 0xd0, 0xe1, 0x8, 0xa9, 0x8e, 0x19, 0x2a, 0xf1, 0xd2, 0xc2, 0x50, 0x55, 0xf4, 0xe3, + 0xbe, 0xd7, 0x84, 0xb5, 0xc8, 0x77, 0x20, 0x4e, 0x73, 0x21, 0x9a, 0x52, 0x3, 0x25, 0x1f, + 0xea, 0xab, ]; assert_eq(keccak256(input, input.len()), result); } @@ -123,10 +127,13 @@ mod tests { #[test] fn var_size_hash() { let input = [ - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, ]; let result = [ - 226, 37, 115, 94, 94, 196, 72, 116, 194, 105, 79, 233, 65, 12, 30, 94, 181, 131, 170, 219, 171, 166, 236, 88, 143, 67, 255, 160, 248, 214, 39, 129 + 226, 37, 115, 94, 94, 196, 72, 116, 194, 105, 79, 233, 65, 12, 30, 94, 181, 131, 170, + 219, 171, 166, 236, 88, 143, 67, 255, 160, 248, 214, 39, 129, ]; assert_eq(keccak256(input, 13), result); } diff --git a/noir/noir-repo/noir_stdlib/src/hash/mimc.nr b/noir/noir-repo/noir_stdlib/src/hash/mimc.nr index 84ee177b663..6045ae3dbdb 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/mimc.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/mimc.nr @@ -22,100 +22,100 @@ fn mimc(x: Field, k: Field, constants: [Field; N], exp: Field) -> Fi } global MIMC_BN254_ROUNDS: u32 = 91; -//generated from seed "mimc" using keccak256 +//generated from seed "mimc" using keccak256 global MIMC_BN254_CONSTANTS: [Field; MIMC_BN254_ROUNDS] = [ - 0, - 20888961410941983456478427210666206549300505294776164667214940546594746570981, - 15265126113435022738560151911929040668591755459209400716467504685752745317193, - 8334177627492981984476504167502758309043212251641796197711684499645635709656, - 1374324219480165500871639364801692115397519265181803854177629327624133579404, - 11442588683664344394633565859260176446561886575962616332903193988751292992472, - 2558901189096558760448896669327086721003508630712968559048179091037845349145, - 11189978595292752354820141775598510151189959177917284797737745690127318076389, - 3262966573163560839685415914157855077211340576201936620532175028036746741754, - 17029914891543225301403832095880481731551830725367286980611178737703889171730, - 4614037031668406927330683909387957156531244689520944789503628527855167665518, - 19647356996769918391113967168615123299113119185942498194367262335168397100658, - 5040699236106090655289931820723926657076483236860546282406111821875672148900, - 2632385916954580941368956176626336146806721642583847728103570779270161510514, - 17691411851977575435597871505860208507285462834710151833948561098560743654671, - 11482807709115676646560379017491661435505951727793345550942389701970904563183, - 8360838254132998143349158726141014535383109403565779450210746881879715734773, - 12663821244032248511491386323242575231591777785787269938928497649288048289525, - 3067001377342968891237590775929219083706800062321980129409398033259904188058, - 8536471869378957766675292398190944925664113548202769136103887479787957959589, - 19825444354178182240559170937204690272111734703605805530888940813160705385792, - 16703465144013840124940690347975638755097486902749048533167980887413919317592, - 13061236261277650370863439564453267964462486225679643020432589226741411380501, - 10864774797625152707517901967943775867717907803542223029967000416969007792571, - 10035653564014594269791753415727486340557376923045841607746250017541686319774, - 3446968588058668564420958894889124905706353937375068998436129414772610003289, - 4653317306466493184743870159523234588955994456998076243468148492375236846006, - 8486711143589723036499933521576871883500223198263343024003617825616410932026, - 250710584458582618659378487568129931785810765264752039738223488321597070280, - 2104159799604932521291371026105311735948154964200596636974609406977292675173, - 16313562605837709339799839901240652934758303521543693857533755376563489378839, - 6032365105133504724925793806318578936233045029919447519826248813478479197288, - 14025118133847866722315446277964222215118620050302054655768867040006542798474, - 7400123822125662712777833064081316757896757785777291653271747396958201309118, - 1744432620323851751204287974553233986555641872755053103823939564833813704825, - 8316378125659383262515151597439205374263247719876250938893842106722210729522, - 6739722627047123650704294650168547689199576889424317598327664349670094847386, - 21211457866117465531949733809706514799713333930924902519246949506964470524162, - 13718112532745211817410303291774369209520657938741992779396229864894885156527, - 5264534817993325015357427094323255342713527811596856940387954546330728068658, - 18884137497114307927425084003812022333609937761793387700010402412840002189451, - 5148596049900083984813839872929010525572543381981952060869301611018636120248, - 19799686398774806587970184652860783461860993790013219899147141137827718662674, - 19240878651604412704364448729659032944342952609050243268894572835672205984837, - 10546185249390392695582524554167530669949955276893453512788278945742408153192, - 5507959600969845538113649209272736011390582494851145043668969080335346810411, - 18177751737739153338153217698774510185696788019377850245260475034576050820091, - 19603444733183990109492724100282114612026332366576932662794133334264283907557, - 10548274686824425401349248282213580046351514091431715597441736281987273193140, - 1823201861560942974198127384034483127920205835821334101215923769688644479957, - 11867589662193422187545516240823411225342068709600734253659804646934346124945, - 18718569356736340558616379408444812528964066420519677106145092918482774343613, - 10530777752259630125564678480897857853807637120039176813174150229243735996839, - 20486583726592018813337145844457018474256372770211860618687961310422228379031, - 12690713110714036569415168795200156516217175005650145422920562694422306200486, - 17386427286863519095301372413760745749282643730629659997153085139065756667205, - 2216432659854733047132347621569505613620980842043977268828076165669557467682, - 6309765381643925252238633914530877025934201680691496500372265330505506717193, - 20806323192073945401862788605803131761175139076694468214027227878952047793390, - 4037040458505567977365391535756875199663510397600316887746139396052445718861, - 19948974083684238245321361840704327952464170097132407924861169241740046562673, - 845322671528508199439318170916419179535949348988022948153107378280175750024, - 16222384601744433420585982239113457177459602187868460608565289920306145389382, - 10232118865851112229330353999139005145127746617219324244541194256766741433339, - 6699067738555349409504843460654299019000594109597429103342076743347235369120, - 6220784880752427143725783746407285094967584864656399181815603544365010379208, - 6129250029437675212264306655559561251995722990149771051304736001195288083309, - 10773245783118750721454994239248013870822765715268323522295722350908043393604, - 4490242021765793917495398271905043433053432245571325177153467194570741607167, - 19596995117319480189066041930051006586888908165330319666010398892494684778526, - 837850695495734270707668553360118467905109360511302468085569220634750561083, - 11803922811376367215191737026157445294481406304781326649717082177394185903907, - 10201298324909697255105265958780781450978049256931478989759448189112393506592, - 13564695482314888817576351063608519127702411536552857463682060761575100923924, - 9262808208636973454201420823766139682381973240743541030659775288508921362724, - 173271062536305557219323722062711383294158572562695717740068656098441040230, - 18120430890549410286417591505529104700901943324772175772035648111937818237369, - 20484495168135072493552514219686101965206843697794133766912991150184337935627, - 19155651295705203459475805213866664350848604323501251939850063308319753686505, - 11971299749478202793661982361798418342615500543489781306376058267926437157297, - 18285310723116790056148596536349375622245669010373674803854111592441823052978, - 7069216248902547653615508023941692395371990416048967468982099270925308100727, - 6465151453746412132599596984628739550147379072443683076388208843341824127379, - 16143532858389170960690347742477978826830511669766530042104134302796355145785, - 19362583304414853660976404410208489566967618125972377176980367224623492419647, - 1702213613534733786921602839210290505213503664731919006932367875629005980493, - 10781825404476535814285389902565833897646945212027592373510689209734812292327, - 4212716923652881254737947578600828255798948993302968210248673545442808456151, - 7594017890037021425366623750593200398174488805473151513558919864633711506220, - 18979889247746272055963929241596362599320706910852082477600815822482192194401, - 13602139229813231349386885113156901793661719180900395818909719758150455500533 - ]; + 0, + 20888961410941983456478427210666206549300505294776164667214940546594746570981, + 15265126113435022738560151911929040668591755459209400716467504685752745317193, + 8334177627492981984476504167502758309043212251641796197711684499645635709656, + 1374324219480165500871639364801692115397519265181803854177629327624133579404, + 11442588683664344394633565859260176446561886575962616332903193988751292992472, + 2558901189096558760448896669327086721003508630712968559048179091037845349145, + 11189978595292752354820141775598510151189959177917284797737745690127318076389, + 3262966573163560839685415914157855077211340576201936620532175028036746741754, + 17029914891543225301403832095880481731551830725367286980611178737703889171730, + 4614037031668406927330683909387957156531244689520944789503628527855167665518, + 19647356996769918391113967168615123299113119185942498194367262335168397100658, + 5040699236106090655289931820723926657076483236860546282406111821875672148900, + 2632385916954580941368956176626336146806721642583847728103570779270161510514, + 17691411851977575435597871505860208507285462834710151833948561098560743654671, + 11482807709115676646560379017491661435505951727793345550942389701970904563183, + 8360838254132998143349158726141014535383109403565779450210746881879715734773, + 12663821244032248511491386323242575231591777785787269938928497649288048289525, + 3067001377342968891237590775929219083706800062321980129409398033259904188058, + 8536471869378957766675292398190944925664113548202769136103887479787957959589, + 19825444354178182240559170937204690272111734703605805530888940813160705385792, + 16703465144013840124940690347975638755097486902749048533167980887413919317592, + 13061236261277650370863439564453267964462486225679643020432589226741411380501, + 10864774797625152707517901967943775867717907803542223029967000416969007792571, + 10035653564014594269791753415727486340557376923045841607746250017541686319774, + 3446968588058668564420958894889124905706353937375068998436129414772610003289, + 4653317306466493184743870159523234588955994456998076243468148492375236846006, + 8486711143589723036499933521576871883500223198263343024003617825616410932026, + 250710584458582618659378487568129931785810765264752039738223488321597070280, + 2104159799604932521291371026105311735948154964200596636974609406977292675173, + 16313562605837709339799839901240652934758303521543693857533755376563489378839, + 6032365105133504724925793806318578936233045029919447519826248813478479197288, + 14025118133847866722315446277964222215118620050302054655768867040006542798474, + 7400123822125662712777833064081316757896757785777291653271747396958201309118, + 1744432620323851751204287974553233986555641872755053103823939564833813704825, + 8316378125659383262515151597439205374263247719876250938893842106722210729522, + 6739722627047123650704294650168547689199576889424317598327664349670094847386, + 21211457866117465531949733809706514799713333930924902519246949506964470524162, + 13718112532745211817410303291774369209520657938741992779396229864894885156527, + 5264534817993325015357427094323255342713527811596856940387954546330728068658, + 18884137497114307927425084003812022333609937761793387700010402412840002189451, + 5148596049900083984813839872929010525572543381981952060869301611018636120248, + 19799686398774806587970184652860783461860993790013219899147141137827718662674, + 19240878651604412704364448729659032944342952609050243268894572835672205984837, + 10546185249390392695582524554167530669949955276893453512788278945742408153192, + 5507959600969845538113649209272736011390582494851145043668969080335346810411, + 18177751737739153338153217698774510185696788019377850245260475034576050820091, + 19603444733183990109492724100282114612026332366576932662794133334264283907557, + 10548274686824425401349248282213580046351514091431715597441736281987273193140, + 1823201861560942974198127384034483127920205835821334101215923769688644479957, + 11867589662193422187545516240823411225342068709600734253659804646934346124945, + 18718569356736340558616379408444812528964066420519677106145092918482774343613, + 10530777752259630125564678480897857853807637120039176813174150229243735996839, + 20486583726592018813337145844457018474256372770211860618687961310422228379031, + 12690713110714036569415168795200156516217175005650145422920562694422306200486, + 17386427286863519095301372413760745749282643730629659997153085139065756667205, + 2216432659854733047132347621569505613620980842043977268828076165669557467682, + 6309765381643925252238633914530877025934201680691496500372265330505506717193, + 20806323192073945401862788605803131761175139076694468214027227878952047793390, + 4037040458505567977365391535756875199663510397600316887746139396052445718861, + 19948974083684238245321361840704327952464170097132407924861169241740046562673, + 845322671528508199439318170916419179535949348988022948153107378280175750024, + 16222384601744433420585982239113457177459602187868460608565289920306145389382, + 10232118865851112229330353999139005145127746617219324244541194256766741433339, + 6699067738555349409504843460654299019000594109597429103342076743347235369120, + 6220784880752427143725783746407285094967584864656399181815603544365010379208, + 6129250029437675212264306655559561251995722990149771051304736001195288083309, + 10773245783118750721454994239248013870822765715268323522295722350908043393604, + 4490242021765793917495398271905043433053432245571325177153467194570741607167, + 19596995117319480189066041930051006586888908165330319666010398892494684778526, + 837850695495734270707668553360118467905109360511302468085569220634750561083, + 11803922811376367215191737026157445294481406304781326649717082177394185903907, + 10201298324909697255105265958780781450978049256931478989759448189112393506592, + 13564695482314888817576351063608519127702411536552857463682060761575100923924, + 9262808208636973454201420823766139682381973240743541030659775288508921362724, + 173271062536305557219323722062711383294158572562695717740068656098441040230, + 18120430890549410286417591505529104700901943324772175772035648111937818237369, + 20484495168135072493552514219686101965206843697794133766912991150184337935627, + 19155651295705203459475805213866664350848604323501251939850063308319753686505, + 11971299749478202793661982361798418342615500543489781306376058267926437157297, + 18285310723116790056148596536349375622245669010373674803854111592441823052978, + 7069216248902547653615508023941692395371990416048967468982099270925308100727, + 6465151453746412132599596984628739550147379072443683076388208843341824127379, + 16143532858389170960690347742477978826830511669766530042104134302796355145785, + 19362583304414853660976404410208489566967618125972377176980367224623492419647, + 1702213613534733786921602839210290505213503664731919006932367875629005980493, + 10781825404476535814285389902565833897646945212027592373510689209734812292327, + 4212716923652881254737947578600828255798948993302968210248673545442808456151, + 7594017890037021425366623750593200398174488805473151513558919864633711506220, + 18979889247746272055963929241596362599320706910852082477600815822482192194401, + 13602139229813231349386885113156901793661719180900395818909719758150455500533, +]; //mimc implementation with hardcoded parameters for BN254 curve. #[field(bn254)] diff --git a/noir/noir-repo/noir_stdlib/src/hash/mod.nr b/noir/noir-repo/noir_stdlib/src/hash/mod.nr index 7cd4b8e292e..609017d70aa 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/mod.nr @@ -7,8 +7,9 @@ pub mod sha512; use crate::default::Default; use crate::uint128::U128; -use crate::collections::vec::Vec; -use crate::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_slice}; +use crate::embedded_curve_ops::{ + EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return, +}; use crate::meta::derive_via; // Kept for backwards compatibility @@ -33,7 +34,10 @@ pub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint } #[inline_always] -pub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> EmbeddedCurvePoint { +pub fn pedersen_commitment_with_separator( + input: [Field; N], + separator: u32, +) -> EmbeddedCurvePoint { let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N]; for i in 0..N { // we use the unsafe version because the multi_scalar_mul will constrain the scalars. @@ -52,24 +56,29 @@ pub fn pedersen_hash(input: [Field; N]) -> Field #[no_predicates] pub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field { - let mut scalars: Vec = Vec::from_slice([EmbeddedCurveScalar { lo: 0, hi: 0 }; N].as_slice()); //Vec::new(); + let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1]; + let mut generators: [EmbeddedCurvePoint; N + 1] = + [EmbeddedCurvePoint::point_at_infinity(); N + 1]; + let domain_generators: [EmbeddedCurvePoint; N] = + derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), separator); for i in 0..N { - scalars.set(i, from_field_unsafe(input[i])); + scalars[i] = from_field_unsafe(input[i]); + generators[i] = domain_generators[i]; } - scalars.push(EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field }); - let domain_generators :[EmbeddedCurvePoint; N]= derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), separator); - let mut vec_generators = Vec::new(); - for i in 0..N { - vec_generators.push(domain_generators[i]); - } - let length_generator : [EmbeddedCurvePoint; 1] = derive_generators("pedersen_hash_length".as_bytes(), 0); - vec_generators.push(length_generator[0]); - multi_scalar_mul_slice(vec_generators.slice, scalars.slice)[0] + scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field }; + + let length_generator: [EmbeddedCurvePoint; 1] = + derive_generators("pedersen_hash_length".as_bytes(), 0); + generators[N] = length_generator[0]; + multi_scalar_mul_array_return(generators, scalars)[0] } #[field(bn254)] -pub fn derive_generators(domain_separator_bytes: [u8; M], starting_index: u32) -> [EmbeddedCurvePoint; N] { +pub fn derive_generators( + domain_separator_bytes: [u8; M], + starting_index: u32, +) -> [EmbeddedCurvePoint; N] { crate::assert_constant(domain_separator_bytes); // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index __derive_generators(domain_separator_bytes, starting_index) @@ -77,16 +86,17 @@ pub fn derive_generators(domain_separator_bytes: [u8; M] #[builtin(derive_pedersen_generators)] #[field(bn254)] -fn __derive_generators(domain_separator_bytes: [u8; M], starting_index: u32) -> [EmbeddedCurvePoint; N] {} +fn __derive_generators( + domain_separator_bytes: [u8; M], + starting_index: u32, +) -> [EmbeddedCurvePoint; N] {} #[field(bn254)] // Same as from_field but: // does not assert the limbs are 128 bits // does not assert the decomposition does not overflow the EmbeddedCurveScalar fn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar { - let (xlo, xhi) = unsafe { - crate::field::bn254::decompose_hint(scalar) - }; + let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) }; // Check that the decomposition is correct assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi); EmbeddedCurveScalar { lo: xlo, hi: xhi } @@ -119,7 +129,9 @@ pub fn poseidon2_permutation(_input: [Field; N], _state_length: u32) // Hash trait shall be implemented per type. #[derive_via(derive_hash)] pub trait Hash { - fn hash(self, state: &mut H) where H: Hasher; + fn hash(self, state: &mut H) + where + H: Hasher; } // docs:start:derive_hash @@ -127,7 +139,14 @@ comptime fn derive_hash(s: StructDefinition) -> Quoted { let name = quote { Hash }; let signature = quote { fn hash(_self: Self, _state: &mut H) where H: std::hash::Hasher }; let for_each_field = |name| quote { _self.$name.hash(_state); }; - crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, |fields| fields) + crate::meta::make_trait_impl( + s, + name, + signature, + for_each_field, + quote {}, + |fields| fields, + ) } // docs:end:derive_hash @@ -140,7 +159,10 @@ pub trait Hasher { } // BuildHasher is a factory trait, responsible for production of specific Hasher. -pub trait BuildHasher where H: Hasher { +pub trait BuildHasher +where + H: Hasher, +{ fn build_hasher(self) -> H; } @@ -148,7 +170,8 @@ pub struct BuildHasherDefault; impl BuildHasher for BuildHasherDefault where - H: Hasher + Default { + H: Hasher + Default, +{ fn build_hasher(_self: Self) -> H { H::default() } @@ -156,99 +179,151 @@ where impl Default for BuildHasherDefault where - H: Hasher + Default { + H: Hasher + Default, +{ fn default() -> Self { BuildHasherDefault {} } } impl Hash for Field { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self); } } impl Hash for u1 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for u8 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for u16 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for u32 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for u64 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for i8 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for i16 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for i32 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for i64 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for bool { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self as Field); } } impl Hash for () { - fn hash(_self: Self, _state: &mut H) where H: Hasher {} + fn hash(_self: Self, _state: &mut H) + where + H: Hasher, + {} } impl Hash for U128 { - fn hash(self, state: &mut H) where H: Hasher { + fn hash(self, state: &mut H) + where + H: Hasher, + { H::write(state, self.lo as Field); H::write(state, self.hi as Field); } } -impl Hash for [T; N] where T: Hash { - fn hash(self, state: &mut H) where H: Hasher { +impl Hash for [T; N] +where + T: Hash, +{ + fn hash(self, state: &mut H) + where + H: Hasher, + { for elem in self { elem.hash(state); } } } -impl Hash for [T] where T: Hash { - fn hash(self, state: &mut H) where H: Hasher { +impl Hash for [T] +where + T: Hash, +{ + fn hash(self, state: &mut H) + where + H: Hasher, + { self.len().hash(state); for elem in self { elem.hash(state); @@ -256,23 +331,47 @@ impl Hash for [T] where T: Hash { } } -impl Hash for (A, B) where A: Hash, B: Hash { - fn hash(self, state: &mut H) where H: Hasher { +impl Hash for (A, B) +where + A: Hash, + B: Hash, +{ + fn hash(self, state: &mut H) + where + H: Hasher, + { self.0.hash(state); self.1.hash(state); } } -impl Hash for (A, B, C) where A: Hash, B: Hash, C: Hash { - fn hash(self, state: &mut H) where H: Hasher { +impl Hash for (A, B, C) +where + A: Hash, + B: Hash, + C: Hash, +{ + fn hash(self, state: &mut H) + where + H: Hasher, + { self.0.hash(state); self.1.hash(state); self.2.hash(state); } } -impl Hash for (A, B, C, D) where A: Hash, B: Hash, C: Hash, D: Hash { - fn hash(self, state: &mut H) where H: Hasher { +impl Hash for (A, B, C, D) +where + A: Hash, + B: Hash, + C: Hash, + D: Hash, +{ + fn hash(self, state: &mut H) + where + H: Hasher, + { self.0.hash(state); self.1.hash(state); self.2.hash(state); @@ -280,8 +379,18 @@ impl Hash for (A, B, C, D) where A: Hash, B: Hash, C: Hash, D: Hash } } -impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: Hash, E: Hash { - fn hash(self, state: &mut H) where H: Hasher { +impl Hash for (A, B, C, D, E) +where + A: Hash, + B: Hash, + C: Hash, + D: Hash, + E: Hash, +{ + fn hash(self, state: &mut H) + where + H: Hasher, + { self.0.hash(state); self.1.hash(state); self.2.hash(state); @@ -296,104 +405,124 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: #[test] fn assert_pedersen() { assert_eq( - pedersen_hash_with_separator([1], 1), 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f + pedersen_hash_with_separator([1], 1), + 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f, ); assert_eq( - pedersen_commitment_with_separator([1], 1), EmbeddedCurvePoint { - x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402, - y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126, - is_infinite: false - } + pedersen_commitment_with_separator([1], 1), + EmbeddedCurvePoint { + x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402, + y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2], 2), 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255 + pedersen_hash_with_separator([1, 2], 2), + 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255, ); assert_eq( - pedersen_commitment_with_separator([1, 2], 2), EmbeddedCurvePoint { - x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753, - y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2], 2), + EmbeddedCurvePoint { + x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753, + y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3], 3), 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4 + pedersen_hash_with_separator([1, 2, 3], 3), + 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3], 3), EmbeddedCurvePoint { - x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85, - y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3], 3), + EmbeddedCurvePoint { + x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85, + y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3, 4], 4), 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc + pedersen_hash_with_separator([1, 2, 3, 4], 4), + 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3, 4], 4), EmbeddedCurvePoint { - x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9, - y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3, 4], 4), + EmbeddedCurvePoint { + x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9, + y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3, 4, 5], 5), 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22 + pedersen_hash_with_separator([1, 2, 3, 4, 5], 5), + 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5), EmbeddedCurvePoint { - x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29, - y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5), + EmbeddedCurvePoint { + x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29, + y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6), 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572 + pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6), + 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6), EmbeddedCurvePoint { - x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697, - y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6), + EmbeddedCurvePoint { + x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697, + y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7), 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3 + pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7), + 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7), EmbeddedCurvePoint { - x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939, - y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7), + EmbeddedCurvePoint { + x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939, + y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8), 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c + pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8), + 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8), EmbeddedCurvePoint { - x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443, - y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8), + EmbeddedCurvePoint { + x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443, + y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9), 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7 + pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9), + 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9), EmbeddedCurvePoint { - x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d, - y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9), + EmbeddedCurvePoint { + x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d, + y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2, + is_infinite: false, + }, ); assert_eq( - pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10), 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94 + pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10), + 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94, ); assert_eq( - pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10), EmbeddedCurvePoint { - x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c, - y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245, - is_infinite: false - } + pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10), + EmbeddedCurvePoint { + x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c, + y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245, + is_infinite: false, + }, ); } diff --git a/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254.nr b/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254.nr index ce4b904ed5c..23591fb69c8 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254.nr @@ -16,7 +16,7 @@ pub fn sponge(msg: [Field; N]) -> 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]; + state[i + 1] = input[i]; } perm::x5_2(state)[0] @@ -26,7 +26,7 @@ pub fn hash_1(input: [Field; 1]) -> 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]; + state[i + 1] = input[i]; } perm::x5_3(state)[0] @@ -36,7 +36,7 @@ pub fn hash_2(input: [Field; 2]) -> 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]; + state[i + 1] = input[i]; } perm::x5_4(state)[0] @@ -46,7 +46,7 @@ pub fn hash_3(input: [Field; 3]) -> 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]; + state[i + 1] = input[i]; } perm::x5_5(state)[0] @@ -56,7 +56,7 @@ pub fn hash_4(input: [Field; 4]) -> 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]; + state[i + 1] = input[i]; } perm::x5_6(state)[0] @@ -66,7 +66,7 @@ pub fn hash_5(input: [Field; 5]) -> 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]; + state[i + 1] = input[i]; } perm::x5_7(state)[0] @@ -76,7 +76,7 @@ pub fn hash_6(input: [Field; 6]) -> 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]; + state[i + 1] = input[i]; } perm::x5_8(state)[0] @@ -86,7 +86,7 @@ pub fn hash_7(input: [Field; 7]) -> 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]; + state[i + 1] = input[i]; } perm::x5_9(state)[0] @@ -96,7 +96,7 @@ pub fn hash_8(input: [Field; 8]) -> 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]; + state[i + 1] = input[i]; } perm::x5_10(state)[0] @@ -106,7 +106,7 @@ pub fn hash_9(input: [Field; 9]) -> 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]; + state[i + 1] = input[i]; } perm::x5_11(state)[0] @@ -116,7 +116,7 @@ pub fn hash_10(input: [Field; 10]) -> 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]; + state[i + 1] = input[i]; } perm::x5_12(state)[0] @@ -126,7 +126,7 @@ pub fn hash_11(input: [Field; 11]) -> 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]; + state[i + 1] = input[i]; } perm::x5_13(state)[0] @@ -136,7 +136,7 @@ pub fn hash_12(input: [Field; 12]) -> 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]; + state[i + 1] = input[i]; } perm::x5_14(state)[0] @@ -146,7 +146,7 @@ pub fn hash_13(input: [Field; 13]) -> 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]; + state[i + 1] = input[i]; } perm::x5_15(state)[0] @@ -156,7 +156,7 @@ pub fn hash_14(input: [Field; 14]) -> 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]; + state[i + 1] = input[i]; } perm::x5_16(state)[0] @@ -166,7 +166,7 @@ pub fn hash_15(input: [Field; 15]) -> 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]; + state[i + 1] = input[i]; } perm::x5_17(state)[0] diff --git a/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/consts.nr b/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/consts.nr index 3b28ced5835..835ed3ea476 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/consts.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/consts.nr @@ -1,6 +1,5 @@ // Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage // Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 - // Constants for various Poseidon instances in the case of the prime field of the same order as BN254. // Consistent with https://github.com/iden3/circomlib/blob/master/circuits/poseidon.circom and https://github.com/iden3/circomlib/blob/master/circuits/poseidon_constants.circom use crate::hash::poseidon::PoseidonConfig; diff --git a/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/perm.nr b/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/perm.nr index b7dc05ef9de..3a12f59fe77 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/perm.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/poseidon/bn254/perm.nr @@ -4,144 +4,112 @@ use crate::hash::poseidon::permute; #[field(bn254)] pub fn x5_2(mut state: [Field; 2]) -> [Field; 2] { - state = permute( - consts::x5_2_config(), - state); + state = permute(consts::x5_2_config(), state); state } #[field(bn254)] pub fn x5_3(mut state: [Field; 3]) -> [Field; 3] { - state = permute( - consts::x5_3_config(), - state); + state = permute(consts::x5_3_config(), state); state } #[field(bn254)] pub fn x5_4(mut state: [Field; 4]) -> [Field; 4] { - state = permute( - consts::x5_4_config(), - state); + state = permute(consts::x5_4_config(), state); state } #[field(bn254)] pub fn x5_5(mut state: [Field; 5]) -> [Field; 5] { - state = permute( - consts::x5_5_config(), - state); + state = permute(consts::x5_5_config(), state); state } #[field(bn254)] pub fn x5_6(mut state: [Field; 6]) -> [Field; 6] { - state = permute( - consts::x5_6_config(), - state); + state = permute(consts::x5_6_config(), state); state } #[field(bn254)] pub fn x5_7(mut state: [Field; 7]) -> [Field; 7] { - state = permute( - consts::x5_7_config(), - state); + state = permute(consts::x5_7_config(), state); state } #[field(bn254)] pub fn x5_8(mut state: [Field; 8]) -> [Field; 8] { - state = permute( - consts::x5_8_config(), - state); + state = permute(consts::x5_8_config(), state); state } #[field(bn254)] pub fn x5_9(mut state: [Field; 9]) -> [Field; 9] { - state = permute( - consts::x5_9_config(), - state); + state = permute(consts::x5_9_config(), state); state } #[field(bn254)] pub fn x5_10(mut state: [Field; 10]) -> [Field; 10] { - state = permute( - consts::x5_10_config(), - state); + state = permute(consts::x5_10_config(), state); state } #[field(bn254)] pub fn x5_11(mut state: [Field; 11]) -> [Field; 11] { - state = permute( - consts::x5_11_config(), - state); + state = permute(consts::x5_11_config(), state); state } #[field(bn254)] pub fn x5_12(mut state: [Field; 12]) -> [Field; 12] { - state = permute( - consts::x5_12_config(), - state); + state = permute(consts::x5_12_config(), state); state } #[field(bn254)] pub fn x5_13(mut state: [Field; 13]) -> [Field; 13] { - state = permute( - consts::x5_13_config(), - state); + state = permute(consts::x5_13_config(), state); state } #[field(bn254)] pub fn x5_14(mut state: [Field; 14]) -> [Field; 14] { - state = permute( - consts::x5_14_config(), - state); + state = permute(consts::x5_14_config(), state); state } #[field(bn254)] pub fn x5_15(mut state: [Field; 15]) -> [Field; 15] { - state = permute( - consts::x5_15_config(), - state); + state = permute(consts::x5_15_config(), state); state } #[field(bn254)] pub fn x5_16(mut state: [Field; 16]) -> [Field; 16] { - state = permute( - consts::x5_16_config(), - state); + state = permute(consts::x5_16_config(), state); state } #[field(bn254)] pub fn x5_17(mut state: [Field; 17]) -> [Field; 17] { - state = permute( - consts::x5_17_config(), - state); + state = permute(consts::x5_17_config(), state); state } diff --git a/noir/noir-repo/noir_stdlib/src/hash/poseidon/mod.nr b/noir/noir-repo/noir_stdlib/src/hash/poseidon/mod.nr index 9553d352d28..0af7951b8dc 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/poseidon/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/poseidon/mod.nr @@ -5,14 +5,14 @@ use crate::default::Default; // A config struct defining the parameters of the Poseidon instance to use. // // A thorough writeup of this method (along with an unoptimized method) can be found at: https://spec.filecoin.io/algorithms/crypto/poseidon/ -pub struct PoseidonConfig { +pub struct PoseidonConfig { // State width, should be equal to `T` t: Field, // Number of full rounds. should be even rf: u8, // Number of partial rounds rp: u8, - // S-box power; depends on the underlying field + // S-box power; depends on the underlying field alpha: Field, // The round constants for the round_constants: [Field; N], @@ -35,7 +35,7 @@ pub fn config( round_constants: [Field; N], mds: [[Field; T]; T], presparse_mds: [[Field; T]; T], - sparse_mds: [Field; X] + sparse_mds: [Field; X], ) -> PoseidonConfig { // Input checks assert_eq(rf & 1, 0); @@ -48,9 +48,10 @@ pub fn config( pub fn permute( pos_conf: PoseidonConfig, - mut state: [Field; T] + mut state: [Field; T], ) -> [Field; T] { - let PoseidonConfig {t, rf, rp, alpha, round_constants, mds, presparse_mds, sparse_mds } = pos_conf; + let PoseidonConfig { t, rf, rp, alpha, round_constants, mds, presparse_mds, sparse_mds } = + pos_conf; for i in 0..state.len() { state[i] += round_constants[i]; @@ -76,7 +77,7 @@ pub fn permute( for _r in 0..rp { state[0] = state[0].pow_32(alpha); - state[0] += round_constants[(rf/2 + 1) as u32 * T + _r as u32]; + state[0] += round_constants[(rf / 2 + 1) as u32 * T + _r as u32]; crate::as_witness(state[0]); { let mut newState0 = 0; @@ -99,7 +100,7 @@ pub fn permute( for _r in 0..rf / 2 - 1 { state = sigma(state); for i in 0..state.len() { - state[i] += round_constants[(rf/2+1) as u32 * T + rp as u32 + (_r as u32) * T + i]; + state[i] += round_constants[(rf / 2 + 1) as u32 * T + rp as u32 + (_r as u32) * T + i]; } state = apply_matrix(mds, state); } @@ -130,7 +131,7 @@ fn absorb( mut state: [Field; T], rate: Field, capacity: Field, - msg: [Field; O] // Arbitrary length message + msg: [Field; O], // Arbitrary length message ) -> [Field; T] { assert_eq(pos_conf.t, rate + capacity); @@ -139,7 +140,7 @@ fn absorb( for k in 0..msg.len() { // Add current block to state state[capacity + i] += msg[k]; - i = i+1; + i = i + 1; // Enough to absorb if i == rate { state = permute(pos_conf, state); @@ -165,7 +166,7 @@ fn sigma(x: [Field; O]) -> [Field; O] { y } -pub struct PoseidonHasher{ +pub struct PoseidonHasher { _state: [Field], } @@ -179,46 +180,167 @@ impl Hasher for PoseidonHasher { result = bn254::hash_1([self._state[0]]); } if len == 2 { - result = bn254::hash_2([self._state[0],self._state[1]]); + result = bn254::hash_2([self._state[0], self._state[1]]); } if len == 3 { - result = bn254::hash_3([self._state[0],self._state[1],self._state[2]]); + result = bn254::hash_3([self._state[0], self._state[1], self._state[2]]); } if len == 4 { - result = bn254::hash_4([self._state[0],self._state[1],self._state[2],self._state[3]]); + result = bn254::hash_4([self._state[0], self._state[1], self._state[2], self._state[3]]); } if len == 5 { - result = bn254::hash_5([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4]]); + result = bn254::hash_5([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + ]); } if len == 6 { - result = bn254::hash_6([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5]]); + result = bn254::hash_6([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + ]); } if len == 7 { - result = bn254::hash_7([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6]]); + result = bn254::hash_7([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + ]); } if len == 8 { - result = bn254::hash_8([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7]]); + result = bn254::hash_8([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + ]); } if len == 9 { - result = bn254::hash_9([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7], self._state[8]]); + result = bn254::hash_9([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + self._state[8], + ]); } if len == 10 { - result = bn254::hash_10([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7], self._state[8], self._state[9]]); + result = bn254::hash_10([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + self._state[8], + self._state[9], + ]); } if len == 11 { - result = bn254::hash_11([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7], self._state[8], self._state[9], self._state[10]]); + result = bn254::hash_11([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + self._state[8], + self._state[9], + self._state[10], + ]); } if len == 12 { - result = bn254::hash_12([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7], self._state[8], self._state[9], self._state[10], self._state[11]]); + result = bn254::hash_12([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + self._state[8], + self._state[9], + self._state[10], + self._state[11], + ]); } if len == 13 { - result = bn254::hash_13([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7], self._state[8], self._state[9], self._state[10], self._state[11], self._state[12]]); + result = bn254::hash_13([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + self._state[8], + self._state[9], + self._state[10], + self._state[11], + self._state[12], + ]); } if len == 14 { - result = bn254::hash_14([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7], self._state[8], self._state[9], self._state[10], self._state[11], self._state[12], self._state[13]]); + result = bn254::hash_14([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + self._state[8], + self._state[9], + self._state[10], + self._state[11], + self._state[12], + self._state[13], + ]); } if len == 15 { - result = bn254::hash_15([self._state[0],self._state[1],self._state[2],self._state[3],self._state[4], self._state[5], self._state[6], self._state[7], self._state[8], self._state[9], self._state[10], self._state[11], self._state[12], self._state[13], self._state[14]]); + result = bn254::hash_15([ + self._state[0], + self._state[1], + self._state[2], + self._state[3], + self._state[4], + self._state[5], + self._state[6], + self._state[7], + self._state[8], + self._state[9], + self._state[10], + self._state[11], + self._state[12], + self._state[13], + self._state[14], + ]); } result @@ -244,17 +366,29 @@ mod poseidon_tests { { let mut state = [0, 1, 2]; let mut expected = [ - 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a, 0x0fca49b798923ab0239de1c9e7a4a9a2210312b6a2f616d18b5a87f9b628ae29, 0x0e7ae82e40091e63cbd4f16a6d16310b3729d4b6e138fcf54110e2867045a30c + 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a, + 0x0fca49b798923ab0239de1c9e7a4a9a2210312b6a2f616d18b5a87f9b628ae29, + 0x0e7ae82e40091e63cbd4f16a6d16310b3729d4b6e138fcf54110e2867045a30c, ]; - assert_eq(expected, poseidon::bn254::perm::x5_3(state), "Failed to reproduce output for [0, 1, 2]"); + assert_eq( + expected, + poseidon::bn254::perm::x5_3(state), + "Failed to reproduce output for [0, 1, 2]", + ); } { let mut state = [0, 1, 2, 3, 4]; let mut expected = [ - 0x299c867db6c1fdd79dcefa40e4510b9837e60ebb1ce0663dbaa525df65250465, 0x1148aaef609aa338b27dafd89bb98862d8bb2b429aceac47d86206154ffe053d, 0x24febb87fed7462e23f6665ff9a0111f4044c38ee1672c1ac6b0637d34f24907, 0x0eb08f6d809668a981c186beaf6110060707059576406b248e5d9cf6e78b3d3e, 0x07748bc6877c9b82c8b98666ee9d0626ec7f5be4205f79ee8528ef1c4a376fc7 + 0x299c867db6c1fdd79dcefa40e4510b9837e60ebb1ce0663dbaa525df65250465, + 0x1148aaef609aa338b27dafd89bb98862d8bb2b429aceac47d86206154ffe053d, + 0x24febb87fed7462e23f6665ff9a0111f4044c38ee1672c1ac6b0637d34f24907, + 0x0eb08f6d809668a981c186beaf6110060707059576406b248e5d9cf6e78b3d3e, + 0x07748bc6877c9b82c8b98666ee9d0626ec7f5be4205f79ee8528ef1c4a376fc7, ]; assert_eq( - expected, poseidon::bn254::perm::x5_5(state), "Failed to reproduce output for [0, 1, 2, 3, 4]" + expected, + poseidon::bn254::perm::x5_5(state), + "Failed to reproduce output for [0, 1, 2, 3, 4]", ); } } diff --git a/noir/noir-repo/noir_stdlib/src/hash/poseidon2.nr b/noir/noir-repo/noir_stdlib/src/hash/poseidon2.nr index fb813120fef..517c2cd8f5f 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/poseidon2.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/poseidon2.nr @@ -4,8 +4,8 @@ use crate::default::Default; comptime global RATE: u32 = 3; pub struct Poseidon2 { - cache: [Field;3], - state: [Field;4], + cache: [Field; 3], + state: [Field; 4], cache_size: u32, squeeze_mode: bool, // 0 => absorb, 1 => squeeze } @@ -21,7 +21,8 @@ impl Poseidon2 { } pub(crate) fn new(iv: Field) -> Poseidon2 { - let mut result = Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false }; + let mut result = + Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false }; result.state[RATE] = iv; result } @@ -62,9 +63,13 @@ impl Poseidon2 { self.state[0] } - fn hash_internal(input: [Field; N], in_len: u32, is_variable_length: bool) -> Field { + fn hash_internal( + input: [Field; N], + in_len: u32, + is_variable_length: bool, + ) -> Field { let two_pow_64 = 18446744073709551616; - let iv : Field = (in_len as Field) * two_pow_64; + let iv: Field = (in_len as Field) * two_pow_64; let mut sponge = Poseidon2::new(iv); for i in 0..input.len() { if i < in_len { @@ -82,13 +87,13 @@ impl Poseidon2 { } } -pub struct Poseidon2Hasher{ +pub struct Poseidon2Hasher { _state: [Field], } impl Hasher for Poseidon2Hasher { fn finish(self) -> Field { - let iv : Field = (self._state.len() as Field) * 18446744073709551616; // iv = (self._state.len() << 64) + let iv: Field = (self._state.len() as Field) * 18446744073709551616; // iv = (self._state.len() << 64) let mut sponge = Poseidon2::new(iv); for i in 0..self._state.len() { sponge.absorb(self._state[i]); diff --git a/noir/noir-repo/noir_stdlib/src/hash/sha256.nr b/noir/noir-repo/noir_stdlib/src/hash/sha256.nr index 6c56a722fa7..b5d2624d3e7 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/sha256.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/sha256.nr @@ -3,96 +3,63 @@ use crate::runtime::is_unconstrained; // Implementation of SHA-256 mapping a byte array of variable length to // 32 bytes. +// A message block is up to 64 bytes taken from the input. +global BLOCK_SIZE = 64; + +// The first index in the block where the 8 byte message size will be written. +global MSG_SIZE_PTR = 56; + +// Size of the message block when packed as 4-byte integer array. +global INT_BLOCK_SIZE = 16; + +// Index of a byte in a 64 byte block; ie. 0..=63 +type BLOCK_BYTE_PTR = u32; + +// The foreign function to compress blocks works on 16 pieces of 4-byte integers, instead of 64 bytes. +type INT_BLOCK = [u32; INT_BLOCK_SIZE]; + +// A message block is a slice of the original message of a fixed size, +// potentially padded with zeroes. +type MSG_BLOCK = [u8; BLOCK_SIZE]; + +// The hash is 32 bytes. +type HASH = [u8; 32]; + +// The state accumulates the blocks. +// Its overall size is the same as the `HASH`. +type STATE = [u32; 8]; + // Deprecated in favour of `sha256_var` // docs:start:sha256 -pub fn sha256(input: [u8; N]) -> [u8; 32] +pub fn sha256(input: [u8; N]) -> HASH // docs:end:sha256 { digest(input) } #[foreign(sha256_compression)] -pub fn sha256_compression(_input: [u32; 16], _state: [u32; 8]) -> [u32; 8] {} +pub fn sha256_compression(_input: INT_BLOCK, _state: STATE) -> STATE {} // SHA-256 hash function #[no_predicates] -pub fn digest(msg: [u8; N]) -> [u8; 32] { +pub fn digest(msg: [u8; N]) -> HASH { sha256_var(msg, N as u64) } -// Convert 64-byte array to array of 16 u32s -fn msg_u8_to_u32(msg: [u8; 64]) -> [u32; 16] { - let mut msg32: [u32; 16] = [0; 16]; - - for i in 0..16 { - let mut msg_field: Field = 0; - for j in 0..4 { - msg_field = msg_field * 256 + msg[64 - 4*(i + 1) + j] as Field; - } - msg32[15 - i] = msg_field as u32; - } - - msg32 -} - -unconstrained fn build_msg_block_iter(msg: [u8; N], message_size: u32, msg_start: u32) -> ([u8; 64], u32) { - let mut msg_block: [u8; BLOCK_SIZE] = [0; BLOCK_SIZE]; - // We insert `BLOCK_SIZE` bytes (or up to the end of the message) - let block_input = if msg_start + BLOCK_SIZE > message_size { - if message_size < msg_start { - // This function is sometimes called with `msg_start` past the end of the message. - // In this case we return an empty block and zero pointer to signal that the result should be ignored. - 0 - } else { - message_size - msg_start - } - } else { - BLOCK_SIZE - }; - for k in 0..block_input { - msg_block[k] = msg[msg_start + k]; - } - (msg_block, block_input) -} - -// Verify the block we are compressing was appropriately constructed -fn verify_msg_block( - msg: [u8; N], - message_size: u32, - msg_block: [u8; 64], - msg_start: u32 -) -> u32 { - let mut msg_byte_ptr: u32 = 0; // Message byte pointer - let mut msg_end = msg_start + BLOCK_SIZE; - if msg_end > N { - msg_end = N; - } - - for k in msg_start..msg_end { - if k < message_size { - assert_eq(msg_block[msg_byte_ptr], msg[k]); - msg_byte_ptr = msg_byte_ptr + 1; - } - } - - msg_byte_ptr -} - -global BLOCK_SIZE = 64; - // Variable size SHA-256 hash -pub fn sha256_var(msg: [u8; N], message_size: u64) -> [u8; 32] { +pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { let message_size = message_size as u32; let num_blocks = N / BLOCK_SIZE; - let mut msg_block: [u8; BLOCK_SIZE] = [0; BLOCK_SIZE]; - let mut h: [u32; 8] = [1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]; // Intermediate hash, starting with the canonical initial value + let mut msg_block: MSG_BLOCK = [0; BLOCK_SIZE]; + let mut h: STATE = [ + 1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, + 1541459225, + ]; // Intermediate hash, starting with the canonical initial value let mut msg_byte_ptr = 0; // Pointer into msg_block - for i in 0..num_blocks { let msg_start = BLOCK_SIZE * i; - let (new_msg_block, new_msg_byte_ptr) = unsafe { - build_msg_block_iter(msg, message_size, msg_start) - }; + let (new_msg_block, new_msg_byte_ptr) = + unsafe { build_msg_block(msg, message_size, msg_start) }; if msg_start < message_size { msg_block = new_msg_block; } @@ -120,9 +87,8 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> [u8; 32] { // or our message cannot be evenly split into blocks. if modulo != 0 { let msg_start = BLOCK_SIZE * num_blocks; - let (new_msg_block, new_msg_byte_ptr) = unsafe { - build_msg_block_iter(msg, message_size, msg_start) - }; + let (new_msg_block, new_msg_byte_ptr) = + unsafe { build_msg_block(msg, message_size, msg_start) }; if msg_start < message_size { msg_block = new_msg_block; @@ -132,116 +98,168 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> [u8; 32] { let new_msg_byte_ptr = verify_msg_block(msg, message_size, msg_block, msg_start); if msg_start < message_size { msg_byte_ptr = new_msg_byte_ptr; + verify_msg_block_padding(msg_block, msg_byte_ptr); } } else if msg_start < message_size { msg_byte_ptr = new_msg_byte_ptr; } } + // If we had modulo == 0 then it means the last block was full, + // and we can reset the pointer to zero to overwrite it. if msg_byte_ptr == BLOCK_SIZE { msg_byte_ptr = 0; } - // This variable is used to get around the compiler under-constrained check giving a warning. - // We want to check against a constant zero, but if it does not come from the circuit inputs - // or return values the compiler check will issue a warning. - let zero = msg_block[0] - msg_block[0]; - // Pad the rest such that we have a [u32; 2] block at the end representing the length // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]). + // Here we rely on the fact that everything beyond the available input is set to 0. msg_block[msg_byte_ptr] = 1 << 7; let last_block = msg_block; msg_byte_ptr = msg_byte_ptr + 1; - unsafe { - let (new_msg_block, new_msg_byte_ptr) = pad_msg_block(msg_block, msg_byte_ptr); - msg_block = new_msg_block; - if crate::runtime::is_unconstrained() { - msg_byte_ptr = new_msg_byte_ptr; - } + // If we don't have room to write the size, compress the block and reset it. + if msg_byte_ptr > MSG_SIZE_PTR { + h = sha256_compression(msg_u8_to_u32(msg_block), h); + // `attach_len_to_msg_block` will zero out everything after the `msg_byte_ptr`. + msg_byte_ptr = 0; } - if !crate::runtime::is_unconstrained() { - for i in 0..BLOCK_SIZE { - assert_eq(msg_block[i], last_block[i]); - } + msg_block = unsafe { attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size) }; - // If i >= 57, there aren't enough bits in the current message block to accomplish this, so - // the 1 and 0s fill up the current block, which we then compress accordingly. - // Not enough bits (64) to store length. Fill up with zeros. - for _i in 57..BLOCK_SIZE { - if msg_byte_ptr <= 63 & msg_byte_ptr >= 57 { - assert_eq(msg_block[msg_byte_ptr], zero); - msg_byte_ptr += 1; - } - } + if !crate::runtime::is_unconstrained() { + verify_msg_len(msg_block, last_block, msg_byte_ptr, message_size); } - if msg_byte_ptr >= 57 { - h = sha256_compression(msg_u8_to_u32(msg_block), h); + hash_final_block(msg_block, h) +} - msg_byte_ptr = 0; +// Convert 64-byte array to array of 16 u32s +fn msg_u8_to_u32(msg: MSG_BLOCK) -> INT_BLOCK { + let mut msg32: INT_BLOCK = [0; INT_BLOCK_SIZE]; + + for i in 0..INT_BLOCK_SIZE { + let mut msg_field: Field = 0; + for j in 0..4 { + msg_field = msg_field * 256 + msg[64 - 4 * (i + 1) + j] as Field; + } + msg32[15 - i] = msg_field as u32; } - msg_block = unsafe { - attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size) - }; + msg32 +} - if !crate::runtime::is_unconstrained() { - for i in 0..56 { - let predicate = (i < msg_byte_ptr) as u8; - let expected_byte = predicate * last_block[i]; - assert_eq(msg_block[i], expected_byte); +// Take `BLOCK_SIZE` number of bytes from `msg` starting at `msg_start`. +// Returns the block and the length that has been copied rather than padded with zeroes. +unconstrained fn build_msg_block( + msg: [u8; N], + message_size: u32, + msg_start: u32, +) -> (MSG_BLOCK, BLOCK_BYTE_PTR) { + let mut msg_block: MSG_BLOCK = [0; BLOCK_SIZE]; + // We insert `BLOCK_SIZE` bytes (or up to the end of the message) + let block_input = if msg_start + BLOCK_SIZE > message_size { + if message_size < msg_start { + // This function is sometimes called with `msg_start` past the end of the message. + // In this case we return an empty block and zero pointer to signal that the result should be ignored. + 0 + } else { + message_size - msg_start } + } else { + BLOCK_SIZE + }; + for k in 0..block_input { + msg_block[k] = msg[msg_start + k]; + } + (msg_block, block_input) +} - // We verify the message length was inserted correctly by reversing the byte decomposition. - let len = 8 * message_size; - let mut reconstructed_len: Field = 0; - for i in 56..64 { - reconstructed_len = 256 * reconstructed_len + msg_block[i] as Field; +// Verify the block we are compressing was appropriately constructed by `build_msg_block` +// and matches the input data. Returns the index of the first unset item. +fn verify_msg_block( + msg: [u8; N], + message_size: u32, + msg_block: MSG_BLOCK, + msg_start: u32, +) -> BLOCK_BYTE_PTR { + let mut msg_byte_ptr: u32 = 0; // Message byte pointer + let mut msg_end = msg_start + BLOCK_SIZE; + if msg_end > N { + msg_end = N; + } + + for k in msg_start..msg_end { + if k < message_size { + assert_eq(msg_block[msg_byte_ptr], msg[k]); + msg_byte_ptr = msg_byte_ptr + 1; } - assert_eq(reconstructed_len, len as Field); } - hash_final_block(msg_block, h) + msg_byte_ptr } -unconstrained fn pad_msg_block( - mut msg_block: [u8; 64], - mut msg_byte_ptr: u32 -) -> ([u8; BLOCK_SIZE], u32) { - // If i >= 57, there aren't enough bits in the current message block to accomplish this, so - // the 1 and 0s fill up the current block, which we then compress accordingly. - if msg_byte_ptr >= 57 { - // Not enough bits (64) to store length. Fill up with zeros. - for i in msg_byte_ptr..BLOCK_SIZE { - msg_block[i] = 0; +// Verify the block we are compressing was appropriately padded with zeroes by `build_msg_block`. +// This is only relevant for the last, potentially partially filled block. +fn verify_msg_block_padding(msg_block: MSG_BLOCK, msg_byte_ptr: BLOCK_BYTE_PTR) { + // This variable is used to get around the compiler under-constrained check giving a warning. + // We want to check against a constant zero, but if it does not come from the circuit inputs + // or return values the compiler check will issue a warning. + let zero = msg_block[0] - msg_block[0]; + + for i in 0..BLOCK_SIZE { + if i >= msg_byte_ptr { + assert_eq(msg_block[i], zero); } - (msg_block, BLOCK_SIZE) - } else { - (msg_block, msg_byte_ptr) } } -unconstrained fn attach_len_to_msg_block(mut msg_block: [u8; BLOCK_SIZE], msg_byte_ptr: u32, message_size: u32) -> [u8; BLOCK_SIZE] { +// Zero out all bytes between the end of the message and where the length is appended, +// then write the length into the last 8 bytes of the block. +unconstrained fn attach_len_to_msg_block( + mut msg_block: MSG_BLOCK, + msg_byte_ptr: BLOCK_BYTE_PTR, + message_size: u32, +) -> MSG_BLOCK { // We assume that `msg_byte_ptr` is less than 57 because if not then it is reset to zero before calling this function. // In any case, fill blocks up with zeros until the last 64 (i.e. until msg_byte_ptr = 56). - - for i in msg_byte_ptr..56 { + for i in msg_byte_ptr..MSG_SIZE_PTR { msg_block[i] = 0; } let len = 8 * message_size; let len_bytes: [u8; 8] = (len as Field).to_be_bytes(); for i in 0..8 { - msg_block[56 + i] = len_bytes[i]; + msg_block[MSG_SIZE_PTR + i] = len_bytes[i]; } msg_block } -fn hash_final_block(msg_block: [u8; BLOCK_SIZE], mut state: [u32; 8]) -> [u8; 32] { - let mut out_h: [u8; 32] = [0; 32]; // Digest as sequence of bytes +// Verify that the message length was correctly written by `attach_len_to_msg_block`. +fn verify_msg_len( + msg_block: MSG_BLOCK, + last_block: MSG_BLOCK, + msg_byte_ptr: BLOCK_BYTE_PTR, + message_size: u32, +) { + for i in 0..MSG_SIZE_PTR { + let predicate = (i < msg_byte_ptr) as u8; + let expected_byte = predicate * last_block[i]; + assert_eq(msg_block[i], expected_byte); + } + + // We verify the message length was inserted correctly by reversing the byte decomposition. + let len = 8 * message_size; + let mut reconstructed_len: Field = 0; + for i in MSG_SIZE_PTR..BLOCK_SIZE { + reconstructed_len = 256 * reconstructed_len + msg_block[i] as Field; + } + assert_eq(reconstructed_len, len as Field); +} +// Perform the final compression, then transform the `STATE` into `HASH`. +fn hash_final_block(msg_block: MSG_BLOCK, mut state: STATE) -> HASH { + let mut out_h: HASH = [0; 32]; // Digest as sequence of bytes // Hash final padded block state = sha256_compression(msg_u8_to_u32(msg_block), state); @@ -249,7 +267,7 @@ fn hash_final_block(msg_block: [u8; BLOCK_SIZE], mut state: [u32; 8]) -> [u8; 32 for j in 0..8 { let h_bytes: [u8; 4] = (state[7 - j] as Field).to_le_bytes(); for k in 0..4 { - out_h[31 - 4*j - k] = h_bytes[k]; + out_h[31 - 4 * j - k] = h_bytes[k]; } } @@ -263,7 +281,9 @@ mod tests { fn smoke_test() { let input = [0xbd]; let result = [ - 0x68, 0x32, 0x57, 0x20, 0xaa, 0xbd, 0x7c, 0x82, 0xf3, 0x0f, 0x55, 0x4b, 0x31, 0x3d, 0x05, 0x70, 0xc9, 0x5a, 0xcc, 0xbb, 0x7d, 0xc4, 0xb5, 0xaa, 0xe1, 0x12, 0x04, 0xc0, 0x8f, 0xfe, 0x73, 0x2b + 0x68, 0x32, 0x57, 0x20, 0xaa, 0xbd, 0x7c, 0x82, 0xf3, 0x0f, 0x55, 0x4b, 0x31, 0x3d, + 0x05, 0x70, 0xc9, 0x5a, 0xcc, 0xbb, 0x7d, 0xc4, 0xb5, 0xaa, 0xe1, 0x12, 0x04, 0xc0, + 0x8f, 0xfe, 0x73, 0x2b, ]; assert_eq(sha256_var(input, input.len() as u64), result); } @@ -271,10 +291,14 @@ mod tests { #[test] fn msg_just_over_block() { let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116 + 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, + 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, + 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, + 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, ]; let result = [ - 91, 122, 146, 93, 52, 109, 133, 148, 171, 61, 156, 70, 189, 238, 153, 7, 222, 184, 94, 24, 65, 114, 192, 244, 207, 199, 87, 232, 192, 224, 171, 207 + 91, 122, 146, 93, 52, 109, 133, 148, 171, 61, 156, 70, 189, 238, 153, 7, 222, 184, 94, + 24, 65, 114, 192, 244, 207, 199, 87, 232, 192, 224, 171, 207, ]; assert_eq(sha256_var(input, input.len() as u64), result); } @@ -282,10 +306,33 @@ mod tests { #[test] fn msg_multiple_over_block() { let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115, 99, 105, 105, 13, 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49, 46, 48, 32, 40, 77, 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46, 48, 32, 92, 40, 51, 55, 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115, 117, 98, 106, 101, 99, 116, 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97, 103, 101, 45, 105, 100, 58, 60, 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45, 52, 56, 57, 68, 45, 57, 55, 55, 70, 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55, 64, 109, 101, 46, 99, 111, 109, 62, 13, 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32, 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32, 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, 107, 101, 119, 116, 101, 115, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, 100, 107, 105, 109, 45, 115, 105, 103, 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, 97, 61, 114, 115, 97, 45, 115, 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, 101, 100, 47, 114, 101, 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, 57, 51, 48, 51, 56, 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, 85, 52, 109, 48, 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, 117, 99, 75, 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, 109, 58, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, 86, 101, 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99 + 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, + 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, + 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, + 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115, + 99, 105, 105, 13, 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49, + 46, 48, 32, 40, 77, 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46, + 48, 32, 92, 40, 51, 55, 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115, + 117, 98, 106, 101, 99, 116, 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97, + 103, 101, 45, 105, 100, 58, 60, 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45, + 52, 56, 57, 68, 45, 57, 55, 55, 70, 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55, + 64, 109, 101, 46, 99, 111, 109, 62, 13, 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32, + 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32, + 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, 107, 101, 119, 116, 101, 115, 116, 64, + 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, 100, 107, 105, 109, 45, 115, 105, 103, + 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, 97, 61, 114, 115, 97, 45, 115, + 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, 101, 100, 47, 114, 101, + 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, + 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, 57, 51, 48, 51, 56, + 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, 85, 52, 109, 48, + 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, 117, 99, 75, + 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, 109, 58, 67, + 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, 86, 101, + 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99, ]; let result = [ - 116, 90, 151, 31, 78, 22, 138, 180, 211, 189, 69, 76, 227, 200, 155, 29, 59, 123, 154, 60, 47, 153, 203, 129, 157, 251, 48, 2, 79, 11, 65, 47 + 116, 90, 151, 31, 78, 22, 138, 180, 211, 189, 69, 76, 227, 200, 155, 29, 59, 123, 154, + 60, 47, 153, 203, 129, 157, 251, 48, 2, 79, 11, 65, 47, ]; assert_eq(sha256_var(input, input.len() as u64), result); } @@ -293,10 +340,14 @@ mod tests { #[test] fn msg_just_under_block() { let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 59 + 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, + 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, + 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, + 108, 97, 105, 110, 59, ]; let result = [ - 143, 140, 76, 173, 222, 123, 102, 68, 70, 149, 207, 43, 39, 61, 34, 79, 216, 252, 213, 165, 74, 16, 110, 74, 29, 64, 138, 167, 30, 1, 9, 119 + 143, 140, 76, 173, 222, 123, 102, 68, 70, 149, 207, 43, 39, 61, 34, 79, 216, 252, 213, + 165, 74, 16, 110, 74, 29, 64, 138, 167, 30, 1, 9, 119, ]; assert_eq(sha256_var(input, input.len() as u64), result); } @@ -304,10 +355,34 @@ mod tests { #[test] fn msg_big_not_block_multiple() { let input = [ - 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115, 99, 105, 105, 13, 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49, 46, 48, 32, 40, 77, 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46, 48, 32, 92, 40, 51, 55, 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115, 117, 98, 106, 101, 99, 116, 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97, 103, 101, 45, 105, 100, 58, 60, 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45, 52, 56, 57, 68, 45, 57, 55, 55, 70, 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55, 64, 109, 101, 46, 99, 111, 109, 62, 13, 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32, 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32, 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, 107, 101, 119, 116, 101, 115, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, 100, 107, 105, 109, 45, 115, 105, 103, 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, 97, 61, 114, 115, 97, 45, 115, 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, 101, 100, 47, 114, 101, 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, 57, 51, 48, 51, 56, 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, 85, 52, 109, 48, 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, 117, 99, 75, 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, 109, 58, 67, 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, 86, 101, 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99, 116, 58, 77, 101, 115, 115, 97, 103, 101, 45, 73, 100, 58, 68, 97, 116, 101, 58, 116, 111, 59, 32, 98, 61 + 102, 114, 111, 109, 58, 114, 117, 110, 110, 105, 101, 114, 46, 108, 101, 97, 103, 117, + 101, 115, 46, 48, 106, 64, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, 13, 10, 99, + 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 58, 116, 101, 120, 116, 47, 112, + 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, 61, 117, 115, 45, 97, 115, + 99, 105, 105, 13, 10, 109, 105, 109, 101, 45, 118, 101, 114, 115, 105, 111, 110, 58, 49, + 46, 48, 32, 40, 77, 97, 99, 32, 79, 83, 32, 88, 32, 77, 97, 105, 108, 32, 49, 54, 46, + 48, 32, 92, 40, 51, 55, 51, 49, 46, 53, 48, 48, 46, 50, 51, 49, 92, 41, 41, 13, 10, 115, + 117, 98, 106, 101, 99, 116, 58, 72, 101, 108, 108, 111, 13, 10, 109, 101, 115, 115, 97, + 103, 101, 45, 105, 100, 58, 60, 56, 70, 56, 49, 57, 68, 51, 50, 45, 66, 54, 65, 67, 45, + 52, 56, 57, 68, 45, 57, 55, 55, 70, 45, 52, 51, 56, 66, 66, 67, 52, 67, 65, 66, 50, 55, + 64, 109, 101, 46, 99, 111, 109, 62, 13, 10, 100, 97, 116, 101, 58, 83, 97, 116, 44, 32, + 50, 54, 32, 65, 117, 103, 32, 50, 48, 50, 51, 32, 49, 50, 58, 50, 53, 58, 50, 50, 32, + 43, 48, 52, 48, 48, 13, 10, 116, 111, 58, 122, 107, 101, 119, 116, 101, 115, 116, 64, + 103, 109, 97, 105, 108, 46, 99, 111, 109, 13, 10, 100, 107, 105, 109, 45, 115, 105, 103, + 110, 97, 116, 117, 114, 101, 58, 118, 61, 49, 59, 32, 97, 61, 114, 115, 97, 45, 115, + 104, 97, 50, 53, 54, 59, 32, 99, 61, 114, 101, 108, 97, 120, 101, 100, 47, 114, 101, + 108, 97, 120, 101, 100, 59, 32, 100, 61, 105, 99, 108, 111, 117, 100, 46, 99, 111, 109, + 59, 32, 115, 61, 49, 97, 49, 104, 97, 105, 59, 32, 116, 61, 49, 54, 57, 51, 48, 51, 56, + 51, 51, 55, 59, 32, 98, 104, 61, 55, 120, 81, 77, 68, 117, 111, 86, 86, 85, 52, 109, 48, + 87, 48, 87, 82, 86, 83, 114, 86, 88, 77, 101, 71, 83, 73, 65, 83, 115, 110, 117, 99, 75, + 57, 100, 74, 115, 114, 99, 43, 118, 85, 61, 59, 32, 104, 61, 102, 114, 111, 109, 58, 67, + 111, 110, 116, 101, 110, 116, 45, 84, 121, 112, 101, 58, 77, 105, 109, 101, 45, 86, 101, + 114, 115, 105, 111, 110, 58, 83, 117, 98, 106, 101, 99, 116, 58, 77, 101, 115, 115, 97, + 103, 101, 45, 73, 100, 58, 68, 97, 116, 101, 58, 116, 111, 59, 32, 98, 61, ]; let result = [ - 112, 144, 73, 182, 208, 98, 9, 238, 54, 229, 61, 145, 222, 17, 72, 62, 148, 222, 186, 55, 192, 82, 220, 35, 66, 47, 193, 200, 22, 38, 26, 186 + 112, 144, 73, 182, 208, 98, 9, 238, 54, 229, 61, 145, 222, 17, 72, 62, 148, 222, 186, + 55, 192, 82, 220, 35, 66, 47, 193, 200, 22, 38, 26, 186, ]; assert_eq(sha256_var(input, input.len() as u64), result); } @@ -315,10 +390,39 @@ mod tests { #[test] fn msg_big_with_padding() { let input = [ - 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17, 48, 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12, 201, 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48, 37, 2, 1, 2, 4, 32, 190, 82, 180, 235, 222, 33, 79, 50, 152, 136, 142, 35, 116, 224, 6, 242, 156, 141, 128, 248, 10, 61, 98, 86, 248, 45, 207, 210, 90, 232, 175, 38, 48, 37, 2, 1, 3, 4, 32, 0, 194, 104, 108, 237, 246, 97, 230, 116, 198, 69, 110, 26, 87, 17, 89, 110, 199, 108, 250, 36, 21, 39, 87, 110, 102, 250, 213, 174, 131, 171, 174, 48, 37, 2, 1, 11, 4, 32, 136, 155, 87, 144, 111, 15, 152, 127, 85, 25, 154, 81, 20, 58, 51, 75, 193, 116, 234, 0, 60, 30, 29, 30, 183, 141, 72, 247, 255, 203, 100, 124, 48, 37, 2, 1, 12, 4, 32, 41, 234, 106, 78, 31, 11, 114, 137, 237, 17, 92, 71, 134, 47, 62, 78, 189, 233, 201, 214, 53, 4, 47, 189, 201, 133, 6, 121, 34, 131, 64, 142, 48, 37, 2, 1, 13, 4, 32, 91, 222, 210, 193, 62, 222, 104, 82, 36, 41, 138, 253, 70, 15, 148, 208, 156, 45, 105, 171, 241, 195, 185, 43, 217, 162, 146, 201, 222, 89, 238, 38, 48, 37, 2, 1, 14, 4, 32, 76, 123, 216, 13, 51, 227, 72, 245, 59, 193, 238, 166, 103, 49, 23, 164, 171, 188, 194, 197, 156, 187, 249, 28, 198, 95, 69, 15, 182, 56, 54, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17, + 48, 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12, + 201, 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48, + 37, 2, 1, 2, 4, 32, 190, 82, 180, 235, 222, 33, 79, 50, 152, 136, 142, 35, 116, 224, 6, + 242, 156, 141, 128, 248, 10, 61, 98, 86, 248, 45, 207, 210, 90, 232, 175, 38, 48, 37, 2, + 1, 3, 4, 32, 0, 194, 104, 108, 237, 246, 97, 230, 116, 198, 69, 110, 26, 87, 17, 89, + 110, 199, 108, 250, 36, 21, 39, 87, 110, 102, 250, 213, 174, 131, 171, 174, 48, 37, 2, + 1, 11, 4, 32, 136, 155, 87, 144, 111, 15, 152, 127, 85, 25, 154, 81, 20, 58, 51, 75, + 193, 116, 234, 0, 60, 30, 29, 30, 183, 141, 72, 247, 255, 203, 100, 124, 48, 37, 2, 1, + 12, 4, 32, 41, 234, 106, 78, 31, 11, 114, 137, 237, 17, 92, 71, 134, 47, 62, 78, 189, + 233, 201, 214, 53, 4, 47, 189, 201, 133, 6, 121, 34, 131, 64, 142, 48, 37, 2, 1, 13, 4, + 32, 91, 222, 210, 193, 62, 222, 104, 82, 36, 41, 138, 253, 70, 15, 148, 208, 156, 45, + 105, 171, 241, 195, 185, 43, 217, 162, 146, 201, 222, 89, 238, 38, 48, 37, 2, 1, 14, 4, + 32, 76, 123, 216, 13, 51, 227, 72, 245, 59, 193, 238, 166, 103, 49, 23, 164, 171, 188, + 194, 197, 156, 187, 249, 28, 198, 95, 69, 15, 182, 56, 54, 38, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let result = [ - 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212, 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53 + 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212, + 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53, ]; let message_size = 297; assert_eq(sha256_var(input, message_size), result); @@ -327,10 +431,25 @@ mod tests { #[test] fn msg_big_no_padding() { let input = [ - 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17, 48, 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12, 201, 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48, 37, 2, 1, 2, 4, 32, 190, 82, 180, 235, 222, 33, 79, 50, 152, 136, 142, 35, 116, 224, 6, 242, 156, 141, 128, 248, 10, 61, 98, 86, 248, 45, 207, 210, 90, 232, 175, 38, 48, 37, 2, 1, 3, 4, 32, 0, 194, 104, 108, 237, 246, 97, 230, 116, 198, 69, 110, 26, 87, 17, 89, 110, 199, 108, 250, 36, 21, 39, 87, 110, 102, 250, 213, 174, 131, 171, 174, 48, 37, 2, 1, 11, 4, 32, 136, 155, 87, 144, 111, 15, 152, 127, 85, 25, 154, 81, 20, 58, 51, 75, 193, 116, 234, 0, 60, 30, 29, 30, 183, 141, 72, 247, 255, 203, 100, 124, 48, 37, 2, 1, 12, 4, 32, 41, 234, 106, 78, 31, 11, 114, 137, 237, 17, 92, 71, 134, 47, 62, 78, 189, 233, 201, 214, 53, 4, 47, 189, 201, 133, 6, 121, 34, 131, 64, 142, 48, 37, 2, 1, 13, 4, 32, 91, 222, 210, 193, 62, 222, 104, 82, 36, 41, 138, 253, 70, 15, 148, 208, 156, 45, 105, 171, 241, 195, 185, 43, 217, 162, 146, 201, 222, 89, 238, 38, 48, 37, 2, 1, 14, 4, 32, 76, 123, 216, 13, 51, 227, 72, 245, 59, 193, 238, 166, 103, 49, 23, 164, 171, 188, 194, 197, 156, 187, 249, 28, 198, 95, 69, 15, 182, 56, 54, 38 + 48, 130, 1, 37, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 48, 130, 1, 17, + 48, 37, 2, 1, 1, 4, 32, 176, 223, 31, 133, 108, 84, 158, 102, 70, 11, 165, 175, 196, 12, + 201, 130, 25, 131, 46, 125, 156, 194, 28, 23, 55, 133, 157, 164, 135, 136, 220, 78, 48, + 37, 2, 1, 2, 4, 32, 190, 82, 180, 235, 222, 33, 79, 50, 152, 136, 142, 35, 116, 224, 6, + 242, 156, 141, 128, 248, 10, 61, 98, 86, 248, 45, 207, 210, 90, 232, 175, 38, 48, 37, 2, + 1, 3, 4, 32, 0, 194, 104, 108, 237, 246, 97, 230, 116, 198, 69, 110, 26, 87, 17, 89, + 110, 199, 108, 250, 36, 21, 39, 87, 110, 102, 250, 213, 174, 131, 171, 174, 48, 37, 2, + 1, 11, 4, 32, 136, 155, 87, 144, 111, 15, 152, 127, 85, 25, 154, 81, 20, 58, 51, 75, + 193, 116, 234, 0, 60, 30, 29, 30, 183, 141, 72, 247, 255, 203, 100, 124, 48, 37, 2, 1, + 12, 4, 32, 41, 234, 106, 78, 31, 11, 114, 137, 237, 17, 92, 71, 134, 47, 62, 78, 189, + 233, 201, 214, 53, 4, 47, 189, 201, 133, 6, 121, 34, 131, 64, 142, 48, 37, 2, 1, 13, 4, + 32, 91, 222, 210, 193, 62, 222, 104, 82, 36, 41, 138, 253, 70, 15, 148, 208, 156, 45, + 105, 171, 241, 195, 185, 43, 217, 162, 146, 201, 222, 89, 238, 38, 48, 37, 2, 1, 14, 4, + 32, 76, 123, 216, 13, 51, 227, 72, 245, 59, 193, 238, 166, 103, 49, 23, 164, 171, 188, + 194, 197, 156, 187, 249, 28, 198, 95, 69, 15, 182, 56, 54, 38, ]; let result = [ - 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212, 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53 + 32, 85, 108, 174, 127, 112, 178, 182, 8, 43, 134, 123, 192, 211, 131, 66, 184, 240, 212, + 181, 240, 180, 106, 195, 24, 117, 54, 129, 19, 10, 250, 53, ]; assert_eq(sha256_var(input, input.len() as u64), result); } @@ -338,7 +457,30 @@ mod tests { #[test] fn same_msg_len_variable_padding() { let input = [ - 29, 81, 165, 84, 243, 114, 101, 37, 242, 146, 127, 99, 69, 145, 39, 72, 213, 39, 253, 179, 218, 37, 217, 201, 172, 93, 198, 50, 249, 70, 15, 30, 162, 112, 187, 40, 140, 9, 236, 53, 32, 44, 38, 163, 113, 254, 192, 197, 44, 89, 71, 130, 169, 242, 17, 211, 214, 72, 19, 178, 186, 168, 147, 127, 99, 101, 252, 227, 8, 147, 150, 85, 97, 158, 17, 107, 218, 244, 82, 113, 247, 91, 208, 214, 60, 244, 87, 137, 173, 201, 130, 18, 66, 56, 198, 149, 207, 189, 175, 120, 123, 224, 177, 167, 251, 159, 143, 110, 68, 183, 189, 70, 126, 32, 35, 164, 44, 30, 44, 12, 65, 18, 62, 239, 242, 2, 248, 104, 2, 178, 64, 28, 126, 36, 137, 24, 14, 116, 91, 98, 90, 159, 218, 102, 45, 11, 110, 223, 245, 184, 52, 99, 59, 245, 136, 175, 3, 72, 164, 146, 145, 116, 22, 66, 24, 49, 193, 121, 3, 60, 37, 41, 97, 3, 190, 66, 195, 225, 63, 46, 3, 118, 4, 208, 15, 1, 40, 254, 235, 151, 123, 70, 180, 170, 44, 172, 90, 4, 254, 53, 239, 116, 246, 67, 56, 129, 61, 22, 169, 213, 65, 27, 216, 116, 162, 239, 214, 207, 126, 177, 20, 100, 25, 48, 143, 84, 215, 70, 197, 53, 65, 70, 86, 172, 61, 62, 9, 212, 167, 169, 133, 41, 126, 213, 196, 33, 192, 238, 0, 63, 246, 215, 58, 128, 110, 101, 92, 3, 170, 214, 130, 149, 52, 81, 125, 118, 233, 3, 118, 193, 104, 207, 120, 115, 77, 253, 191, 122, 0, 107, 164, 207, 113, 81, 169, 36, 201, 228, 74, 134, 131, 218, 178, 35, 30, 216, 101, 2, 103, 174, 87, 95, 50, 50, 215, 157, 5, 210, 188, 54, 211, 78, 45, 199, 96, 121, 241, 241, 176, 226, 194, 134, 130, 89, 217, 210, 186, 32, 140, 39, 91, 103, 212, 26, 87, 32, 72, 144, 228, 230, 117, 99, 188, 50, 15, 69, 79, 179, 50, 12, 106, 86, 218, 101, 73, 142, 243, 29, 250, 122, 228, 233, 29, 255, 22, 121, 114, 125, 103, 41, 250, 241, 179, 126, 158, 198, 116, 209, 65, 94, 98, 228, 175, 169, 96, 3, 9, 233, 133, 214, 55, 161, 164, 103, 80, 85, 24, 186, 64, 167, 92, 131, 53, 101, 202, 47, 25, 104, 118, 155, 14, 12, 12, 25, 116, 45, 221, 249, 28, 246, 212, 200, 157, 167, 169, 56, 197, 181, 4, 245, 146, 1, 140, 234, 191, 212, 228, 125, 87, 81, 86, 119, 30, 63, 129, 143, 32, 96 + 29, 81, 165, 84, 243, 114, 101, 37, 242, 146, 127, 99, 69, 145, 39, 72, 213, 39, 253, + 179, 218, 37, 217, 201, 172, 93, 198, 50, 249, 70, 15, 30, 162, 112, 187, 40, 140, 9, + 236, 53, 32, 44, 38, 163, 113, 254, 192, 197, 44, 89, 71, 130, 169, 242, 17, 211, 214, + 72, 19, 178, 186, 168, 147, 127, 99, 101, 252, 227, 8, 147, 150, 85, 97, 158, 17, 107, + 218, 244, 82, 113, 247, 91, 208, 214, 60, 244, 87, 137, 173, 201, 130, 18, 66, 56, 198, + 149, 207, 189, 175, 120, 123, 224, 177, 167, 251, 159, 143, 110, 68, 183, 189, 70, 126, + 32, 35, 164, 44, 30, 44, 12, 65, 18, 62, 239, 242, 2, 248, 104, 2, 178, 64, 28, 126, 36, + 137, 24, 14, 116, 91, 98, 90, 159, 218, 102, 45, 11, 110, 223, 245, 184, 52, 99, 59, + 245, 136, 175, 3, 72, 164, 146, 145, 116, 22, 66, 24, 49, 193, 121, 3, 60, 37, 41, 97, + 3, 190, 66, 195, 225, 63, 46, 3, 118, 4, 208, 15, 1, 40, 254, 235, 151, 123, 70, 180, + 170, 44, 172, 90, 4, 254, 53, 239, 116, 246, 67, 56, 129, 61, 22, 169, 213, 65, 27, 216, + 116, 162, 239, 214, 207, 126, 177, 20, 100, 25, 48, 143, 84, 215, 70, 197, 53, 65, 70, + 86, 172, 61, 62, 9, 212, 167, 169, 133, 41, 126, 213, 196, 33, 192, 238, 0, 63, 246, + 215, 58, 128, 110, 101, 92, 3, 170, 214, 130, 149, 52, 81, 125, 118, 233, 3, 118, 193, + 104, 207, 120, 115, 77, 253, 191, 122, 0, 107, 164, 207, 113, 81, 169, 36, 201, 228, 74, + 134, 131, 218, 178, 35, 30, 216, 101, 2, 103, 174, 87, 95, 50, 50, 215, 157, 5, 210, + 188, 54, 211, 78, 45, 199, 96, 121, 241, 241, 176, 226, 194, 134, 130, 89, 217, 210, + 186, 32, 140, 39, 91, 103, 212, 26, 87, 32, 72, 144, 228, 230, 117, 99, 188, 50, 15, 69, + 79, 179, 50, 12, 106, 86, 218, 101, 73, 142, 243, 29, 250, 122, 228, 233, 29, 255, 22, + 121, 114, 125, 103, 41, 250, 241, 179, 126, 158, 198, 116, 209, 65, 94, 98, 228, 175, + 169, 96, 3, 9, 233, 133, 214, 55, 161, 164, 103, 80, 85, 24, 186, 64, 167, 92, 131, 53, + 101, 202, 47, 25, 104, 118, 155, 14, 12, 12, 25, 116, 45, 221, 249, 28, 246, 212, 200, + 157, 167, 169, 56, 197, 181, 4, 245, 146, 1, 140, 234, 191, 212, 228, 125, 87, 81, 86, + 119, 30, 63, 129, 143, 32, 96, ]; // Prepare inputs of different lengths diff --git a/noir/noir-repo/noir_stdlib/src/hash/sha512.nr b/noir/noir-repo/noir_stdlib/src/hash/sha512.nr index 09de174103f..5630139c1f1 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/sha512.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/sha512.nr @@ -35,7 +35,7 @@ fn sha_sigma1(x: u64) -> u64 { fn sha_w(msg: [u64; 16]) -> [u64; 80] // Expanded message blocks { - let mut w: [u64;80] = [0; 80]; + let mut w: [u64; 80] = [0; 80]; for j in 0..16 { w[j] = msg[j]; @@ -43,8 +43,8 @@ fn sha_w(msg: [u64; 16]) -> [u64; 80] // Expanded message blocks for j in 16..80 { w[j] = crate::wrapping_add( - crate::wrapping_add(sha_sigma1(w[j-2]), w[j-7]), - crate::wrapping_add(sha_sigma0(w[j-15]), w[j-16]), + crate::wrapping_add(sha_sigma1(w[j - 2]), w[j - 7]), + crate::wrapping_add(sha_sigma0(w[j - 15]), w[j - 16]), ); } w @@ -65,7 +65,7 @@ fn sha_c(msg: [u64; 16], hash: [u64; 8]) -> [u64; 8] { out_h[7] = out_h[6]; out_h[6] = out_h[5]; out_h[5] = out_h[4]; - out_h[4] = crate::wrapping_add(out_h[3] , t1); + out_h[4] = crate::wrapping_add(out_h[3], t1); out_h[3] = out_h[2]; out_h[2] = out_h[1]; out_h[1] = out_h[0]; @@ -81,7 +81,7 @@ fn msg_u8_to_u64(msg: [u8; 128]) -> [u64; 16] { for i in 0..16 { let mut msg_field: Field = 0; for j in 0..8 { - msg_field = msg_field * 256 + msg[128 - 8*(i + 1) + j] as Field; + msg_field = msg_field * 256 + msg[128 - 8 * (i + 1) + j] as Field; } msg64[15 - i] = msg_field as u64; } @@ -157,7 +157,7 @@ pub fn digest(msg: [u8; N]) -> [u8; 64] { for j in 0..8 { let h_bytes: [u8; 8] = (h[7 - j] as Field).to_le_bytes(); for k in 0..8 { - out_h[63 - 8*j - k] = h_bytes[k]; + out_h[63 - 8 * j - k] = h_bytes[k]; } } diff --git a/noir/noir-repo/noir_stdlib/src/lib.nr b/noir/noir-repo/noir_stdlib/src/lib.nr index f1ef6aca83c..91a1980fe70 100644 --- a/noir/noir-repo/noir_stdlib/src/lib.nr +++ b/noir/noir-repo/noir_stdlib/src/lib.nr @@ -55,7 +55,7 @@ pub fn verify_proof( verification_key: [Field; N], proof: [Field; M], public_inputs: [Field; K], - key_hash: Field + key_hash: Field, ) { verify_proof_internal(verification_key, proof, public_inputs, key_hash, 0); } @@ -65,7 +65,7 @@ pub fn verify_proof_with_type( proof: [Field; M], public_inputs: [Field; K], key_hash: Field, - proof_type: u32 + proof_type: u32, ) { if !crate::runtime::is_unconstrained() { crate::assert_constant(proof_type); @@ -79,7 +79,7 @@ fn verify_proof_internal( proof: [Field; M], public_inputs: [Field; K], key_hash: Field, - proof_type: u32 + proof_type: u32, ) {} // Asserts that the given value is known at compile-time. @@ -106,7 +106,9 @@ pub fn wrapping_add(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)) + crate::from_field( + crate::as_field(x) + 340282366920938463463374607431768211456 - crate::as_field(y), + ) } pub fn wrapping_mul(x: T, y: T) -> T { diff --git a/noir/noir-repo/noir_stdlib/src/meta/ctstring.nr b/noir/noir-repo/noir_stdlib/src/meta/ctstring.nr index 4b4854682db..b414b3418d9 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/ctstring.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/ctstring.nr @@ -65,7 +65,10 @@ impl crate::cmp::Eq for CtString { } impl crate::hash::Hash for CtString { - comptime fn hash(self, state: &mut H) where H: crate::hash::Hasher { + comptime fn hash(self, state: &mut H) + where + H: crate::hash::Hasher, + { state.write(ctstring_hash(self)); } } @@ -85,8 +88,7 @@ comptime fn ctstring_hash(_string: CtString) -> Field {} mod test { #[test] fn as_quoted_str_example() { - comptime - { + comptime { // docs:start:as_quoted_str_example let my_ctstring = "foo bar".as_ctstring(); let my_str = my_ctstring.as_quoted_str!(); diff --git a/noir/noir-repo/noir_stdlib/src/meta/expr.nr b/noir/noir-repo/noir_stdlib/src/meta/expr.nr index 83a165fc533..1b04a97ab15 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/expr.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/expr.nr @@ -118,7 +118,9 @@ impl Expr { /// If this expression is a lambda, returns the parameters, return type and body. #[builtin(expr_as_lambda)] // docs:start:as_lambda - pub comptime fn as_lambda(self) -> Option<([(Expr, Option)], Option, Expr)> {} + pub comptime fn as_lambda( + self, + ) -> Option<([(Expr, Option)], Option, Expr)> {} // docs:end:as_lambda /// If this expression is a let statement, returns the let pattern as an `Expr`, @@ -187,7 +189,7 @@ impl Expr { /// Returns `true` if this expression is trailed by a semicolon. /// /// Example: - /// + /// /// ```noir /// comptime { /// let expr1 = quote { 1 + 2 }.as_expr().unwrap(); @@ -195,7 +197,7 @@ impl Expr { /// /// assert(expr1.as_binary_op().is_some()); /// assert(expr2.as_binary_op().is_some()); - /// + /// /// assert(!expr1.has_semicolon()); /// assert(expr2.has_semicolon()); /// } @@ -219,9 +221,9 @@ impl Expr { /// Applies a mapping function to this expression and to all of its sub-expressions. /// `f` will be applied to each sub-expression first, then applied to the expression itself. - /// + /// /// This happens recursively for every expression within `self`. - /// + /// /// For example, calling `modify` on `(&[1], &[2, 3])` with an `f` that returns `Option::some` /// for expressions that are integers, doubling them, would return `(&[2], &[4, 6])`. // docs:start:modify @@ -267,14 +269,14 @@ impl Expr { quote { $self } } - /// Resolves and type-checks this expression and returns the result as a `TypedExpr`. - /// + /// Resolves and type-checks this expression and returns the result as a `TypedExpr`. + /// /// The `in_function` argument specifies where the expression is resolved: /// - If it's `none`, the expression is resolved in the function where `resolve` was called /// - If it's `some`, the expression is resolved in the given function - /// - /// If any names used by this expression are not in scope or if there are any type errors, - /// this will give compiler errors as if the expression was written directly into + /// + /// If any names used by this expression are not in scope or if there are any type errors, + /// this will give compiler errors as if the expression was written directly into /// the current `comptime` function. #[builtin(expr_resolve)] // docs:start:resolve @@ -283,257 +285,222 @@ impl Expr { } comptime fn modify_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_array().map( - |exprs: [Expr]| { + expr.as_array().map(|exprs: [Expr]| { let exprs = modify_expressions(exprs, f); new_array(exprs) - } - ) + }) } comptime fn modify_assert(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_assert().map( - |expr: (Expr, Option)| { + expr.as_assert().map(|expr: (Expr, Option)| { let (predicate, msg) = expr; let predicate = predicate.modify(f); let msg = msg.map(|msg: Expr| msg.modify(f)); new_assert(predicate, msg) - } - ) + }) } comptime fn modify_assert_eq(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_assert_eq().map( - |expr: (Expr, Expr, Option)| { + expr.as_assert_eq().map(|expr: (Expr, Expr, Option)| { let (lhs, rhs, msg) = expr; let lhs = lhs.modify(f); let rhs = rhs.modify(f); let msg = msg.map(|msg: Expr| msg.modify(f)); new_assert_eq(lhs, rhs, msg) - } - ) + }) } comptime fn modify_assign(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_assign().map( - |expr: (Expr, Expr)| { + expr.as_assign().map(|expr: (Expr, Expr)| { let (lhs, rhs) = expr; let lhs = lhs.modify(f); let rhs = rhs.modify(f); new_assign(lhs, rhs) - } - ) + }) } comptime fn modify_binary_op(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_binary_op().map( - |expr: (Expr, BinaryOp, Expr)| { + expr.as_binary_op().map(|expr: (Expr, BinaryOp, Expr)| { let (lhs, op, rhs) = expr; let lhs = lhs.modify(f); let rhs = rhs.modify(f); new_binary_op(lhs, op, rhs) - } - ) + }) } comptime fn modify_block(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_block().map( - |exprs: [Expr]| { + expr.as_block().map(|exprs: [Expr]| { let exprs = modify_expressions(exprs, f); new_block(exprs) - } - ) + }) } comptime fn modify_cast(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_cast().map( - |expr: (Expr, UnresolvedType)| { + expr.as_cast().map(|expr: (Expr, UnresolvedType)| { let (expr, typ) = expr; let expr = expr.modify(f); new_cast(expr, typ) - } - ) + }) } comptime fn modify_comptime(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_comptime().map( - |exprs: [Expr]| { + expr.as_comptime().map(|exprs: [Expr]| { let exprs = exprs.map(|expr: Expr| expr.modify(f)); new_comptime(exprs) - } - ) + }) } comptime fn modify_constructor(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_constructor().map( - |expr: (UnresolvedType, [(Quoted, Expr)])| { + expr.as_constructor().map(|expr: (UnresolvedType, [(Quoted, Expr)])| { let (typ, fields) = expr; let fields = fields.map(|field: (Quoted, Expr)| { let (name, value) = field; (name, value.modify(f)) }); new_constructor(typ, fields) - } - ) + }) } -comptime fn modify_function_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_function_call().map( - |expr: (Expr, [Expr])| { +comptime fn modify_function_call( + expr: Expr, + f: fn[Env](Expr) -> Option, +) -> Option { + expr.as_function_call().map(|expr: (Expr, [Expr])| { let (function, arguments) = expr; let function = function.modify(f); let arguments = arguments.map(|arg: Expr| arg.modify(f)); new_function_call(function, arguments) - } - ) + }) } comptime fn modify_if(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_if().map( - |expr: (Expr, Expr, Option)| { + expr.as_if().map(|expr: (Expr, Expr, Option)| { let (condition, consequence, alternative) = expr; let condition = condition.modify(f); let consequence = consequence.modify(f); let alternative = alternative.map(|alternative: Expr| alternative.modify(f)); new_if(condition, consequence, alternative) - } - ) + }) } comptime fn modify_index(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_index().map( - |expr: (Expr, Expr)| { + expr.as_index().map(|expr: (Expr, Expr)| { let (object, index) = expr; let object = object.modify(f); let index = index.modify(f); new_index(object, index) - } - ) + }) } comptime fn modify_for(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_for().map( - |expr: (Quoted, Expr, Expr)| { + expr.as_for().map(|expr: (Quoted, Expr, Expr)| { let (identifier, array, body) = expr; let array = array.modify(f); let body = body.modify(f); new_for(identifier, array, body) - } - ) + }) } comptime fn modify_for_range(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_for_range().map( - |expr: (Quoted, Expr, Expr, Expr)| { + expr.as_for_range().map(|expr: (Quoted, Expr, Expr, Expr)| { let (identifier, from, to, body) = expr; let from = from.modify(f); let to = to.modify(f); let body = body.modify(f); new_for_range(identifier, from, to, body) - } - ) + }) } comptime fn modify_lambda(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_lambda().map( - |expr: ([(Expr, Option)], Option, Expr)| { - let (params, return_type, body) = expr; - let params = params.map(|param: (Expr, Option)| (param.0.modify(f), param.1)); - let body = body.modify(f); - new_lambda(params, return_type, body) - } - ) + expr.as_lambda().map(|expr: ([(Expr, Option)], Option, Expr)| { + let (params, return_type, body) = expr; + let params = + params.map(|param: (Expr, Option)| (param.0.modify(f), param.1)); + let body = body.modify(f); + new_lambda(params, return_type, body) + }) } comptime fn modify_let(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_let().map( - |expr: (Expr, Option, Expr)| { + expr.as_let().map(|expr: (Expr, Option, Expr)| { let (pattern, typ, expr) = expr; let pattern = pattern.modify(f); let expr = expr.modify(f); new_let(pattern, typ, expr) - } - ) + }) } -comptime fn modify_member_access(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_member_access().map( - |expr: (Expr, Quoted)| { +comptime fn modify_member_access( + expr: Expr, + f: fn[Env](Expr) -> Option, +) -> Option { + expr.as_member_access().map(|expr: (Expr, Quoted)| { let (object, name) = expr; let object = object.modify(f); new_member_access(object, name) - } - ) + }) } comptime fn modify_method_call(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_method_call().map( - |expr: (Expr, Quoted, [UnresolvedType], [Expr])| { + expr.as_method_call().map(|expr: (Expr, Quoted, [UnresolvedType], [Expr])| { let (object, name, generics, arguments) = expr; let object = object.modify(f); let arguments = arguments.map(|arg: Expr| arg.modify(f)); new_method_call(object, name, generics, arguments) - } - ) + }) } -comptime fn modify_repeated_element_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_repeated_element_array().map( - |expr: (Expr, Expr)| { +comptime fn modify_repeated_element_array( + expr: Expr, + f: fn[Env](Expr) -> Option, +) -> Option { + expr.as_repeated_element_array().map(|expr: (Expr, Expr)| { let (expr, length) = expr; let expr = expr.modify(f); let length = length.modify(f); new_repeated_element_array(expr, length) - } - ) + }) } -comptime fn modify_repeated_element_slice(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_repeated_element_slice().map( - |expr: (Expr, Expr)| { +comptime fn modify_repeated_element_slice( + expr: Expr, + f: fn[Env](Expr) -> Option, +) -> Option { + expr.as_repeated_element_slice().map(|expr: (Expr, Expr)| { let (expr, length) = expr; let expr = expr.modify(f); let length = length.modify(f); new_repeated_element_slice(expr, length) - } - ) + }) } comptime fn modify_slice(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_slice().map( - |exprs: [Expr]| { + expr.as_slice().map(|exprs: [Expr]| { let exprs = modify_expressions(exprs, f); new_slice(exprs) - } - ) + }) } comptime fn modify_tuple(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_tuple().map( - |exprs: [Expr]| { + expr.as_tuple().map(|exprs: [Expr]| { let exprs = modify_expressions(exprs, f); new_tuple(exprs) - } - ) + }) } comptime fn modify_unary_op(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_unary_op().map( - |expr: (UnaryOp, Expr)| { + expr.as_unary_op().map(|expr: (UnaryOp, Expr)| { let (op, rhs) = expr; let rhs = rhs.modify(f); new_unary_op(op, rhs) - } - ) + }) } comptime fn modify_unsafe(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { - expr.as_unsafe().map( - |exprs: [Expr]| { + expr.as_unsafe().map(|exprs: [Expr]| { let exprs = exprs.map(|expr: Expr| expr.modify(f)); new_unsafe(exprs) - } - ) + }) } comptime fn modify_expressions(exprs: [Expr], f: fn[Env](Expr) -> Option) -> [Expr] { @@ -587,12 +554,12 @@ comptime fn new_comptime(exprs: [Expr]) -> Expr { } comptime fn new_constructor(typ: UnresolvedType, fields: [(Quoted, Expr)]) -> Expr { - let fields = fields.map( - |field: (Quoted, Expr)| { - let (name, value) = field; - quote { $name: $value } - } - ).join(quote { , }); + let fields = fields + .map(|field: (Quoted, Expr)| { + let (name, value) = field; + quote { $name: $value } + }) + .join(quote { , }); quote { $typ { $fields }}.as_expr().unwrap() } @@ -620,19 +587,19 @@ comptime fn new_index(object: Expr, index: Expr) -> Expr { comptime fn new_lambda( params: [(Expr, Option)], return_type: Option, - body: Expr + body: Expr, ) -> Expr { - let params = params.map( - |param: (Expr, Option)| { - let (name, typ) = param; - if typ.is_some() { - let typ = typ.unwrap(); - quote { $name: $typ } - } else { - quote { $name } - } - } - ).join(quote { , }); + let params = params + .map(|param: (Expr, Option)| { + let (name, typ) = param; + if typ.is_some() { + let typ = typ.unwrap(); + quote { $name: $typ } + } else { + quote { $name } + } + }) + .join(quote { , }); if return_type.is_some() { let return_type = return_type.unwrap(); @@ -661,7 +628,12 @@ comptime fn new_function_call(function: Expr, arguments: [Expr]) -> Expr { quote { $function($arguments) }.as_expr().unwrap() } -comptime fn new_method_call(object: Expr, name: Quoted, generics: [UnresolvedType], arguments: [Expr]) -> Expr { +comptime fn new_method_call( + object: Expr, + name: Quoted, + generics: [UnresolvedType], + arguments: [Expr], +) -> Expr { let arguments = join_expressions(arguments, quote { , }); if generics.len() == 0 { diff --git a/noir/noir-repo/noir_stdlib/src/meta/format_string.nr b/noir/noir-repo/noir_stdlib/src/meta/format_string.nr index f3c18212599..5e639dc278e 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/format_string.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/format_string.nr @@ -1,4 +1,4 @@ -impl fmtstr { +impl fmtstr { #[builtin(fmtstr_quoted_contents)] // docs:start:quoted_contents pub comptime fn quoted_contents(self) -> Quoted {} diff --git a/noir/noir-repo/noir_stdlib/src/meta/function_def.nr b/noir/noir-repo/noir_stdlib/src/meta/function_def.nr index 11dc169b188..010110d678e 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/function_def.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/function_def.nr @@ -69,7 +69,10 @@ impl FunctionDefinition { } impl crate::hash::Hash for FunctionDefinition { - comptime fn hash(self, state: &mut H) where H: crate::hash::Hasher { + comptime fn hash(self, state: &mut H) + where + H: crate::hash::Hasher, + { state.write(function_def_hash(self)) } } diff --git a/noir/noir-repo/noir_stdlib/src/meta/mod.nr b/noir/noir-repo/noir_stdlib/src/meta/mod.nr index f756be364b1..ff662b878ec 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/mod.nr @@ -39,7 +39,8 @@ use crate::hash::poseidon2::Poseidon2Hasher; pub type DeriveFunction = fn(StructDefinition) -> Quoted; // We'll keep a global HANDLERS map to keep track of the derive handler for each trait -comptime mut global HANDLERS: UHashMap> = UHashMap::default(); +comptime mut global HANDLERS: UHashMap> = + UHashMap::default(); // Given a struct and a slice of traits to derive, create trait impls for each. // This function is as simple as iterating over the slice, checking if we have a trait @@ -51,9 +52,7 @@ pub comptime fn derive(s: StructDefinition, traits: [TraitDefinition]) -> Quoted let mut result = quote {}; for trait_to_derive in traits { - let handler = unsafe { - HANDLERS.get(trait_to_derive) - }; + let handler = unsafe { HANDLERS.get(trait_to_derive) }; assert(handler.is_some(), f"No derive function registered for `{trait_to_derive}`"); let trait_impl = handler.unwrap()(s); @@ -92,7 +91,7 @@ pub comptime fn make_trait_impl( function_signature: Quoted, for_each_field: fn[Env1](Quoted) -> Quoted, join_fields_with: Quoted, - body: fn[Env2](Quoted) -> Quoted + body: fn[Env2](Quoted) -> Quoted, ) -> Quoted { // docs:end:make_trait_impl let typ = s.as_type(); @@ -100,12 +99,10 @@ pub comptime fn make_trait_impl( let where_clause = s.generics().map(|name| quote { $name: $trait_name }).join(quote {,}); // `for_each_field(field1) $join_fields_with for_each_field(field2) $join_fields_with ...` - let fields = s.fields().map( - |f: (Quoted, Type)| { + let fields = s.fields().map(|f: (Quoted, Type)| { let name = f.0; for_each_field(name) - } - ); + }); let body = body(fields.join(join_fields_with)); quote { @@ -127,8 +124,7 @@ mod tests { #[test] fn returning_versus_macro_insertion() { - comptime - { + comptime { // let _a: Quoted = quote { 1 }; let _a: Quoted = quote_one(); @@ -149,7 +145,10 @@ mod tests { } #[derive_field_count] - struct Bar { x: Field, y: [Field; 2] } + struct Bar { + x: Field, + y: [Field; 2], + } comptime fn derive_field_count(s: StructDefinition) -> Quoted { let typ = s.as_type(); @@ -166,7 +165,9 @@ mod tests { // docs:start:annotation-arguments-example #[assert_field_is_type(quote { i32 }.as_type())] - struct MyStruct { my_field: i32 } + struct MyStruct { + my_field: i32, + } comptime fn assert_field_is_type(s: StructDefinition, typ: Type) { // Assert the first field in `s` has type `typ` @@ -177,7 +178,9 @@ mod tests { // docs:start:annotation-varargs-example #[assert_three_args(1, 2, 3)] - struct MyOtherStruct { my_other_field: u32 } + struct MyOtherStruct { + my_other_field: u32, + } #[varargs] comptime fn assert_three_args(_s: StructDefinition, args: [Field]) { @@ -240,7 +243,7 @@ mod tests { method_signature, for_each_field, join_fields_with, - body + body, ) } // docs:end:big-derive-usage-example diff --git a/noir/noir-repo/noir_stdlib/src/meta/module.nr b/noir/noir-repo/noir_stdlib/src/meta/module.nr index e9fac5ded0a..0298282761a 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/module.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/module.nr @@ -31,7 +31,10 @@ impl Module { } impl crate::hash::Hash for Module { - comptime fn hash(self, state: &mut H) where H: crate::hash::Hasher { + comptime fn hash(self, state: &mut H) + where + H: crate::hash::Hasher, + { state.write(module_hash(self)) } } diff --git a/noir/noir-repo/noir_stdlib/src/meta/op.nr b/noir/noir-repo/noir_stdlib/src/meta/op.nr index 39ec918fe39..afe230429f8 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/op.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/op.nr @@ -1,5 +1,5 @@ pub struct UnaryOp { - op: Field + op: Field, } // Cannot derive Eq or Hash since they internally use paths @@ -12,7 +12,10 @@ impl crate::cmp::Eq for UnaryOp { } impl crate::hash::Hash for UnaryOp { - fn hash(self, h: &mut H) where H: crate::hash::Hasher { + fn hash(self, h: &mut H) + where + H: crate::hash::Hasher, + { self.op.hash(h); } } @@ -61,7 +64,7 @@ impl UnaryOp { } pub struct BinaryOp { - op: Field + op: Field, } impl crate::cmp::Eq for BinaryOp { @@ -71,7 +74,10 @@ impl crate::cmp::Eq for BinaryOp { } impl crate::hash::Hash for BinaryOp { - fn hash(self, h: &mut H) where H: crate::hash::Hasher { + fn hash(self, h: &mut H) + where + H: crate::hash::Hasher, + { self.op.hash(h); } } diff --git a/noir/noir-repo/noir_stdlib/src/meta/quoted.nr b/noir/noir-repo/noir_stdlib/src/meta/quoted.nr index cf97107ed68..d67174d7829 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/quoted.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/quoted.nr @@ -35,7 +35,10 @@ impl Eq for Quoted { } impl crate::hash::Hash for Quoted { - comptime fn hash(self, state: &mut H) where H: crate::hash::Hasher { + comptime fn hash(self, state: &mut H) + where + H: crate::hash::Hasher, + { state.write(quoted_hash(self)) } } diff --git a/noir/noir-repo/noir_stdlib/src/meta/struct_def.nr b/noir/noir-repo/noir_stdlib/src/meta/struct_def.nr index fe7eabc7007..ba5d0289e73 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/struct_def.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/struct_def.nr @@ -55,7 +55,10 @@ impl StructDefinition { } impl crate::hash::Hash for StructDefinition { - comptime fn hash(self, state: &mut H) where H: crate::hash::Hasher { + comptime fn hash(self, state: &mut H) + where + H: crate::hash::Hasher, + { state.write(struct_def_hash(self)) } } diff --git a/noir/noir-repo/noir_stdlib/src/meta/trait_constraint.nr b/noir/noir-repo/noir_stdlib/src/meta/trait_constraint.nr index b90f0b590d5..bf22f454448 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/trait_constraint.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/trait_constraint.nr @@ -8,7 +8,10 @@ impl Eq for TraitConstraint { } impl Hash for TraitConstraint { - comptime fn hash(self, state: &mut H) where H: Hasher { + comptime fn hash(self, state: &mut H) + where + H: Hasher, + { state.write(constraint_hash(self)); } } diff --git a/noir/noir-repo/noir_stdlib/src/meta/trait_def.nr b/noir/noir-repo/noir_stdlib/src/meta/trait_def.nr index 9bf0132f79e..cc448b2eae5 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/trait_def.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/trait_def.nr @@ -15,7 +15,10 @@ impl Eq for TraitDefinition { } impl Hash for TraitDefinition { - comptime fn hash(self, state: &mut H) where H: Hasher { + comptime fn hash(self, state: &mut H) + where + H: Hasher, + { state.write(trait_def_hash(self)); } } diff --git a/noir/noir-repo/noir_stdlib/src/meta/typ.nr b/noir/noir-repo/noir_stdlib/src/meta/typ.nr index 31fdbb49b53..8076c692ca5 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/typ.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/typ.nr @@ -8,47 +8,47 @@ use crate::option::Option; /// against another type it will also be set to that type. For example, if `a` is a type /// variable and we have the type equality `(a, i32) = (u8, i32)`, the compiler will set /// `a` equal to `u8`. -/// +/// /// Unbound type variables will often be rendered as `_` while printing them. Bound type /// variables will appear as the type they are bound to. -/// +/// /// This can be used in conjunction with functions which internally perform type checks /// such as `Type::implements` or `Type::get_trait_impl` to potentially grab some of the types used. -/// +/// /// Note that calling `Type::implements` or `Type::get_trait_impl` on a type variable will always /// fail. -/// +/// /// Example: -/// +/// /// ```noir /// trait Serialize {} -/// +/// /// impl Serialize<1> for Field {} -/// +/// /// impl Serialize for [T; N] /// where T: Serialize {} -/// +/// /// impl Serialize for (T, U) /// where T: Serialize, U: Serialize {} -/// +/// /// fn fresh_variable_example() { /// let typevar1 = std::meta::typ::fresh_type_variable(); /// let constraint = quote { Serialize<$typevar1> }.as_trait_constraint(); /// let field_type = quote { Field }.as_type(); -/// +/// /// // Search for a trait impl (binding typevar1 to 1 when the impl is found): /// assert(field_type.implements(constraint)); -/// +/// /// // typevar1 should be bound to the "1" generic now: /// assert_eq(typevar1.as_constant().unwrap(), 1); -/// +/// /// // If we want to do the same with a different type, we need to /// // create a new type variable now that `typevar1` is bound /// let typevar2 = std::meta::typ::fresh_type_variable(); /// let constraint = quote { Serialize<$typevar2> }.as_trait_constraint(); /// let array_type = quote { [(Field, Field); 5] }.as_type(); /// assert(array_type.implements(constraint)); -/// +/// /// // Now typevar2 should be bound to the serialized pair size 2 times the array length 5 /// assert_eq(typevar2.as_constant().unwrap(), 10); /// } @@ -60,14 +60,14 @@ pub comptime fn fresh_type_variable() -> Type {} impl Type { /// If this type is an array, return a pair of (element type, size type). - /// + /// /// Example: - /// + /// /// ```noir /// comptime { /// let array_type = quote { [Field; 3] }.as_type(); /// let (field_type, three_type) = array_type.as_array().unwrap(); - /// + /// /// assert(field_type.is_field()); /// assert_eq(three_type.as_constant().unwrap(), 3); /// } @@ -127,14 +127,14 @@ impl Type { /// for a trait constraint specified from a `where` clause is unknown, /// this function will return `None` in these cases. If you only want to know /// whether a type implements a trait, use `implements` instead. - /// + /// /// Example: - /// + /// /// ```rust /// comptime { /// let field_type = quote { Field }.as_type(); /// let default = quote { Default }.as_trait_constraint(); - /// + /// /// let the_impl: TraitImpl = field_type.get_trait_impl(default).unwrap(); /// assert(the_impl.methods().len(), 1); /// } @@ -147,16 +147,16 @@ impl Type { /// Returns `true` if this type implements the given trait. Note that unlike /// `get_trait_impl` this will also return true for any `where` constraints /// in scope. - /// + /// /// Example: - /// + /// /// ```rust /// fn foo() where T: Default { /// comptime { /// let field_type = quote { Field }.as_type(); /// let default = quote { Default }.as_trait_constraint(); /// assert(field_type.implements(default)); - /// + /// /// let t = quote { T }.as_type(); /// assert(t.implements(default)); /// } @@ -196,7 +196,10 @@ impl Eq for Type { } impl crate::hash::Hash for Type { - comptime fn hash(self, state: &mut H) where H: crate::hash::Hasher { + comptime fn hash(self, state: &mut H) + where + H: crate::hash::Hasher, + { state.write(type_hash(self)) } } diff --git a/noir/noir-repo/noir_stdlib/src/option.nr b/noir/noir-repo/noir_stdlib/src/option.nr index 0c120a71568..5db2ce84efd 100644 --- a/noir/noir-repo/noir_stdlib/src/option.nr +++ b/noir/noir-repo/noir_stdlib/src/option.nr @@ -43,7 +43,11 @@ impl Option { /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value. pub fn unwrap_or(self, default: T) -> T { - if self._is_some { self._value } else { default } + if self._is_some { + self._value + } else { + default + } } /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return @@ -112,19 +116,31 @@ impl Option { /// If self is Some, return self. Otherwise, return `other`. pub fn or(self, other: Self) -> Self { - if self._is_some { self } else { other } + if self._is_some { + self + } else { + other + } } /// If self is Some, return self. Otherwise, return `default()`. pub fn or_else(self, default: fn[Env]() -> Self) -> Self { - if self._is_some { self } else { default() } + if self._is_some { + self + } else { + default() + } } // 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. pub fn xor(self, other: Self) -> Self { if self._is_some { - if other._is_some { Option::none() } else { self } + if other._is_some { + Option::none() + } else { + self + } } else if other._is_some { other } else { @@ -163,7 +179,10 @@ impl Default for Option { } } -impl Eq for Option where T: Eq { +impl Eq for Option +where + T: Eq, +{ fn eq(self, other: Self) -> bool { if self._is_some == other._is_some { if self._is_some { @@ -177,8 +196,14 @@ impl Eq for Option where T: Eq { } } -impl Hash for Option where T: Hash { - fn hash(self, state: &mut H) where H: Hasher { +impl Hash for Option +where + T: Hash, +{ + fn hash(self, state: &mut H) + where + H: Hasher, + { self._is_some.hash(state); if self._is_some { self._value.hash(state); @@ -187,7 +212,10 @@ impl Hash for Option where T: Hash { } // For this impl we're declaring Option::none < Option::some -impl Ord for Option where T: Ord { +impl Ord for Option +where + T: Ord, +{ fn cmp(self, other: Self) -> Ordering { if self._is_some { if other._is_some { diff --git a/noir/noir-repo/noir_stdlib/src/schnorr.nr b/noir/noir-repo/noir_stdlib/src/schnorr.nr index 76db04400e2..a43e75537ee 100644 --- a/noir/noir-repo/noir_stdlib/src/schnorr.nr +++ b/noir/noir-repo/noir_stdlib/src/schnorr.nr @@ -6,7 +6,7 @@ pub fn verify_signature( public_key_x: Field, public_key_y: Field, signature: [u8; 64], - message: [u8; N] + message: [u8; N], ) -> bool // docs:end:schnorr_verify {} @@ -17,7 +17,7 @@ pub fn verify_signature_slice( public_key_x: Field, public_key_y: Field, signature: [u8; 64], - message: [u8] + message: [u8], ) -> bool // docs:end:schnorr_verify_slice {} @@ -25,7 +25,7 @@ pub fn verify_signature_slice( pub fn verify_signature_noir( public_key: EmbeddedCurvePoint, signature: [u8; 64], - message: [u8; N] + message: [u8; N], ) -> bool { //scalar lo/hi from bytes let sig_s = EmbeddedCurveScalar::from_bytes(signature, 0); @@ -35,7 +35,8 @@ pub fn verify_signature_noir( & (!public_key.is_infinite); if ((sig_s.lo != 0) | (sig_s.hi != 0)) & ((sig_e.lo != 0) | (sig_e.hi != 0)) { - let (r_is_infinite, result) = calculate_signature_challenge(public_key, sig_s, sig_e, message); + let (r_is_infinite, result) = + calculate_signature_challenge(public_key, sig_s, sig_e, message); is_ok &= !r_is_infinite; for i in 0..32 { @@ -50,7 +51,7 @@ pub fn verify_signature_noir( pub fn assert_valid_signature( public_key: EmbeddedCurvePoint, signature: [u8; 64], - message: [u8; N] + message: [u8; N], ) { //scalar lo/hi from bytes let sig_s = EmbeddedCurveScalar::from_bytes(signature, 0); @@ -75,9 +76,13 @@ fn calculate_signature_challenge( public_key: EmbeddedCurvePoint, sig_s: EmbeddedCurveScalar, sig_e: EmbeddedCurveScalar, - message: [u8; N] + message: [u8; N], ) -> (bool, [u8; 32]) { - let g1 = EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let g1 = EmbeddedCurvePoint { + x: 1, + y: 17631683881184975370165255887551781615748388533673675138860, + is_infinite: false, + }; let r = crate::embedded_curve_ops::multi_scalar_mul([g1, public_key], [sig_s, sig_e]); // compare the _hashes_ rather than field elements modulo r let pedersen_hash = crate::hash::pedersen_hash([r.x, public_key.x, public_key.y]); @@ -88,7 +93,7 @@ fn calculate_signature_challenge( hash_input[i] = pde[i]; } for i in 0..N { - hash_input[32+i] = message[i]; + hash_input[32 + i] = message[i]; } let result = crate::hash::blake2s(hash_input); @@ -97,7 +102,11 @@ fn calculate_signature_challenge( #[test] fn test_zero_signature() { - let public_key: EmbeddedCurvePoint = EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let public_key: EmbeddedCurvePoint = EmbeddedCurvePoint { + x: 1, + y: 17631683881184975370165255887551781615748388533673675138860, + is_infinite: false, + }; let signature: [u8; 64] = [0; 64]; let message: [u8; _] = [2; 64]; // every message let verified = verify_signature_noir(public_key, signature, message); diff --git a/noir/noir-repo/noir_stdlib/src/sha256.nr b/noir/noir-repo/noir_stdlib/src/sha256.nr index 39e72cfbeb8..9e07b690c4c 100644 --- a/noir/noir-repo/noir_stdlib/src/sha256.nr +++ b/noir/noir-repo/noir_stdlib/src/sha256.nr @@ -1,5 +1,4 @@ // This file is kept for backwards compatibility. - #[deprecated] pub fn digest(msg: [u8; N]) -> [u8; 32] { crate::hash::sha256::digest(msg) diff --git a/noir/noir-repo/noir_stdlib/src/sha512.nr b/noir/noir-repo/noir_stdlib/src/sha512.nr index c66d898b0cf..27b53f4395f 100644 --- a/noir/noir-repo/noir_stdlib/src/sha512.nr +++ b/noir/noir-repo/noir_stdlib/src/sha512.nr @@ -1,5 +1,4 @@ // This file is kept for backwards compatibility. - #[deprecated] pub fn digest(msg: [u8; N]) -> [u8; 64] { crate::hash::sha512::digest(msg) diff --git a/noir/noir-repo/noir_stdlib/src/slice.nr b/noir/noir-repo/noir_stdlib/src/slice.nr index 66c69db65f0..a8815681d6d 100644 --- a/noir/noir-repo/noir_stdlib/src/slice.nr +++ b/noir/noir-repo/noir_stdlib/src/slice.nr @@ -12,8 +12,8 @@ impl [T] { pub fn push_back(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. + /// new slice with a length one greater than the + /// original unmodified slice. #[builtin(slice_push_front)] pub fn push_front(self, elem: T) -> Self {} @@ -27,13 +27,13 @@ impl [T] { #[builtin(slice_pop_front)] pub fn pop_front(self) -> (T, Self) {} - /// Insert an element at a specified index, shifting all elements + /// Insert an element at a specified index, shifting all elements /// after it to the right #[builtin(slice_insert)] pub fn insert(self, index: u32, elem: T) -> Self {} /// Remove an element at a specified index, shifting all elements - /// after it to the left, returning the altered slice and + /// after it to the left, returning the altered slice and /// the removed element #[builtin(slice_remove)] pub fn remove(self, index: u32) -> (Self, T) {} @@ -101,7 +101,10 @@ impl [T] { } // Flatten each element in the slice into one value, separated by `separator`. - pub fn join(self, separator: T) -> T where T: Append { + pub fn join(self, separator: T) -> T + where + T: Append, + { let mut ret = T::empty(); if self.len() != 0 { diff --git a/noir/noir-repo/noir_stdlib/src/uint128.nr b/noir/noir-repo/noir_stdlib/src/uint128.nr index e4a4342c3d1..a4e20859604 100644 --- a/noir/noir-repo/noir_stdlib/src/uint128.nr +++ b/noir/noir-repo/noir_stdlib/src/uint128.nr @@ -1,8 +1,8 @@ use crate::ops::{Add, Sub, Mul, Div, Rem, Not, BitOr, BitAnd, BitXor, Shl, Shr}; use crate::cmp::{Eq, Ord, Ordering}; -global pow64 : Field = 18446744073709551616; //2^64; -global pow63 : Field = 9223372036854775808; // 2^63; +global pow64: Field = 18446744073709551616; //2^64; +global pow63: Field = 9223372036854775808; // 2^63; pub struct U128 { pub(crate) lo: Field, pub(crate) hi: Field, @@ -31,13 +31,13 @@ impl U128 { let mut lo = 0; let mut base = 1; for i in 0..8 { - lo += (bytes[i] as Field)*base; + lo += (bytes[i] as Field) * base; base *= 256; } let mut hi = 0; base = 1; for i in 8..16 { - hi += (bytes[i] as Field)*base; + hi += (bytes[i] as Field) * base; base *= 256; } U128 { lo, hi } @@ -49,7 +49,7 @@ impl U128 { let mut bytes = [0; 16]; for i in 0..8 { bytes[i] = hi[i]; - bytes[i+8] = lo[i]; + bytes[i + 8] = lo[i]; } bytes } @@ -60,7 +60,7 @@ impl U128 { let mut bytes = [0; 16]; for i in 0..8 { bytes[i] = lo[i]; - bytes[i+8] = hi[i]; + bytes[i + 8] = hi[i]; } bytes } @@ -77,18 +77,18 @@ impl U128 { let mut base = 1; if N <= 18 { for i in 0..N - 2 { - lo += U128::decode_ascii(bytes[N-i-1])*base; - base = base*16; + lo += U128::decode_ascii(bytes[N - i - 1]) * base; + base = base * 16; } } else { for i in 0..16 { - lo += U128::decode_ascii(bytes[N-i-1])*base; - base = base*16; + lo += U128::decode_ascii(bytes[N - i - 1]) * base; + base = base * 16; } base = 1; for i in 17..N - 1 { - hi += U128::decode_ascii(bytes[N-i])*base; - base = base*16; + hi += U128::decode_ascii(bytes[N - i]) * base; + base = base * 16; } } U128 { lo: lo as Field, hi: hi as Field } @@ -99,16 +99,17 @@ impl U128 { } pub(crate) fn decode_ascii(ascii: u8) -> Field { - (if ascii < 58 { - ascii - 48 - } else { - let ascii = ascii + 32 * (unsafe { - U128::uconstrained_check_is_upper_ascii(ascii) as u8 - }); - assert(ascii >= 97); // enforce >= 'a' - assert(ascii <= 102); // enforce <= 'f' - ascii - 87 - }) as Field + ( + if ascii < 58 { + ascii - 48 + } else { + let ascii = + ascii + 32 * (unsafe { U128::uconstrained_check_is_upper_ascii(ascii) as u8 }); + assert(ascii >= 97); // enforce >= 'a' + assert(ascii <= 102); // enforce <= 'f' + ascii - 87 + } + ) as Field } // TODO: Replace with a faster version. @@ -123,7 +124,7 @@ impl U128 { } else if self == b { (U128::one(), U128::zero()) } else { - let (q,r) = if b.hi as u64 >= pow63 as u64 { + let (q, r) = if b.hi as u64 >= pow63 as u64 { // The result of multiplication by 2 would overflow (U128::zero(), self) } else { @@ -205,7 +206,7 @@ impl Mul for U128 { impl Div for U128 { fn div(self: Self, b: U128) -> U128 { unsafe { - let (q,r) = self.unconstrained_div(b); + let (q, r) = self.unconstrained_div(b); let a = b * q + r; assert_eq(self, a); assert(r < b); @@ -217,7 +218,7 @@ impl Div for U128 { impl Rem for U128 { fn rem(self: Self, b: U128) -> U128 { unsafe { - let (q,r) = self.unconstrained_div(b); + let (q, r) = self.unconstrained_div(b); let a = b * q + r; assert_eq(self, a); assert(r < b); @@ -256,7 +257,7 @@ impl BitOr for U128 { fn bitor(self, other: U128) -> U128 { U128 { lo: ((self.lo as u64) | (other.lo as u64)) as Field, - hi: ((self.hi as u64) | (other.hi as u64)) as Field + hi: ((self.hi as u64) | (other.hi as u64)) as Field, } } } @@ -265,7 +266,7 @@ impl BitAnd for U128 { fn bitand(self, other: U128) -> U128 { U128 { lo: ((self.lo as u64) & (other.lo as u64)) as Field, - hi: ((self.hi as u64) & (other.hi as u64)) as Field + hi: ((self.hi as u64) & (other.hi as u64)) as Field, } } } @@ -274,7 +275,7 @@ impl BitXor for U128 { fn bitxor(self, other: U128) -> U128 { U128 { lo: ((self.lo as u64) ^ (other.lo as u64)) as Field, - hi: ((self.hi as u64) ^ (other.hi as u64)) as Field + hi: ((self.hi as u64) ^ (other.hi as u64)) as Field, } } } @@ -340,15 +341,15 @@ mod tests { fn test_byte_decomposition() { let a = U128::from_u64s_le(0x0706050403020100, 0x0f0e0d0c0b0a0908); // Get big-endian and little-endian byte decompostions - let le_bytes_a= a.to_le_bytes(); - let be_bytes_a= a.to_be_bytes(); + let le_bytes_a = a.to_le_bytes(); + let be_bytes_a = a.to_be_bytes(); // Check equivalence for i in 0..16 { assert_eq(le_bytes_a[i], be_bytes_a[15 - i]); } // Reconstruct U128 from byte decomposition - let b= U128::from_le_bytes(le_bytes_a); + let b = U128::from_le_bytes(le_bytes_a); // Check that it's the same element assert_eq(a, b); } @@ -358,12 +359,12 @@ mod tests { let b = U128::from_hex("0x20000000000000001"); assert_eq(a, b); - let c= U128::from_hex("0xffffffffffffffffffffffffffffffff"); - let d= U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff); + let c = U128::from_hex("0xffffffffffffffffffffffffffffffff"); + let d = U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff); assert_eq(c, d); - let e= U128::from_hex("0x00000000000000000000000000000000"); - let f= U128::from_u64s_le(0, 0); + let e = U128::from_hex("0x00000000000000000000000000000000"); + let f = U128::from_u64s_le(0, 0); assert_eq(e, f); } @@ -373,7 +374,7 @@ mod tests { fn test_ascii_decode_correct_range() { // '0'..'9' range for i in 0..10 { - let decoded= U128::decode_ascii(48 + i); + let decoded = U128::decode_ascii(48 + i); assert_eq(decoded, i as Field); } // 'A'..'F' range @@ -423,20 +424,20 @@ mod tests { // This code will actually fail because of ascii_decode, // but in the past it was possible to create a value > (1<<128) let a = U128::from_hex("0x~fffffffffffffffffffffffffffffff"); - let b:Field= a.to_integer(); - let c: [u8; 17]= b.to_le_bytes(); + let b: Field = a.to_integer(); + let c: [u8; 17] = b.to_le_bytes(); assert(c[16] != 0); } #[test] fn test_unconstrained_div() { // Test the potential overflow case - let a= U128::from_u64s_le(0x0, 0xffffffffffffffff); - let b= U128::from_u64s_le(0x0, 0xfffffffffffffffe); - let c= U128::one(); - let d= U128::from_u64s_le(0x0, 0x1); + let a = U128::from_u64s_le(0x0, 0xffffffffffffffff); + let b = U128::from_u64s_le(0x0, 0xfffffffffffffffe); + let c = U128::one(); + let d = U128::from_u64s_le(0x0, 0x1); unsafe { - let (q,r) = a.unconstrained_div(b); + let (q, r) = a.unconstrained_div(b); assert_eq(q, c); assert_eq(r, d); } @@ -451,7 +452,7 @@ mod tests { // Check where b is a multiple of a unsafe { - let (c,d) = b.unconstrained_div(a); + let (c, d) = b.unconstrained_div(a); assert_eq((c, d), (U128::zero(), b)); } @@ -459,7 +460,7 @@ mod tests { let a = U128::from_u64s_le(0x1, 0x0); let b = U128::zero(); unsafe { - let (c, d)= a.unconstrained_div(b); + let (c, d) = a.unconstrained_div(b); assert_eq((c, d), (U128::zero(), U128::zero())); } // Dividing 1<<127 by 1<<127 (special case) @@ -474,25 +475,25 @@ mod tests { #[test] fn integer_conversions() { // Maximum - let start:Field = 0xffffffffffffffffffffffffffffffff; + let start: Field = 0xffffffffffffffffffffffffffffffff; let a = U128::from_integer(start); let end = a.to_integer(); assert_eq(start, end); // Minimum - let start:Field = 0x0; + let start: Field = 0x0; let a = U128::from_integer(start); let end = a.to_integer(); assert_eq(start, end); // Low limb - let start:Field = 0xffffffffffffffff; + let start: Field = 0xffffffffffffffff; let a = U128::from_integer(start); let end = a.to_integer(); assert_eq(start, end); // High limb - let start:Field = 0xffffffffffffffff0000000000000000; + let start: Field = 0xffffffffffffffff0000000000000000; let a = U128::from_integer(start); let end = a.to_integer(); assert_eq(start, end); @@ -533,7 +534,10 @@ mod tests { assert_eq(U128::zero(), U128::from_u64s_le(0, 1).wrapping_mul(U128::from_u64s_le(0, 1))); // -1 * -1 == 1 assert_eq( - U128::one(), U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff).wrapping_mul(U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff)) + U128::one(), + U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff).wrapping_mul( + U128::from_u64s_le(0xffffffffffffffff, 0xffffffffffffffff), + ), ); } } diff --git a/noir/noir-repo/scripts/install_bb.sh b/noir/noir-repo/scripts/install_bb.sh index c94a1b7dff0..596f0a54ba4 100755 --- a/noir/noir-repo/scripts/install_bb.sh +++ b/noir/noir-repo/scripts/install_bb.sh @@ -1,6 +1,6 @@ #!/bin/bash -VERSION="0.56.0" +VERSION="0.58.0" BBUP_PATH=~/.bb/bbup diff --git a/noir/noir-repo/test_programs/benchmarks/bench_sha256_long/Prover.toml b/noir/noir-repo/test_programs/benchmarks/bench_sha256_long/Prover.toml new file mode 100644 index 00000000000..ba4bbc1540d --- /dev/null +++ b/noir/noir-repo/test_programs/benchmarks/bench_sha256_long/Prover.toml @@ -0,0 +1,191 @@ +# 2*64+60=188 bytes +input = [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, +] diff --git a/noir/noir-repo/test_programs/benchmarks/bench_sha256_long/src/main.nr b/noir/noir-repo/test_programs/benchmarks/bench_sha256_long/src/main.nr new file mode 100644 index 00000000000..17129275371 --- /dev/null +++ b/noir/noir-repo/test_programs/benchmarks/bench_sha256_long/src/main.nr @@ -0,0 +1,7 @@ +// Input size long enough that we have to compress a few times +// and then pad the last block out. +global INPUT_SIZE = 2 * 64 + 60; + +fn main(input: [u8; INPUT_SIZE]) -> pub [u8; 32] { + std::hash::sha256(input) +} diff --git a/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr index 4a057a75e43..f599d2879ee 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics/src/main.nr @@ -52,9 +52,9 @@ fn push_multiple(array: [Field; N]) -> [Field; N + 2] { // The rest of this file is setup for demo_proof // ********************************************* -struct W { } +pub struct W {} -struct Equiv { +pub struct Equiv { // TODO(https://github.com/noir-lang/noir/issues/5644): // Bug with struct_obj.field_thats_a_fn(x) @@ -75,8 +75,8 @@ impl Equiv { fn equiv_trans( x: Equiv, - y: Equiv -) -> Equiv, Equiv), V, (Equiv, Equiv)> { + y: Equiv, + ) -> Equiv, Equiv), V, (Equiv, Equiv)> { Equiv { to_: |z| { y.to(x.to(z)) }, fro_: |z| { x.fro(y.fro(z)) } } } @@ -84,7 +84,9 @@ fn mul_one_r() -> Equiv, (), W, ()> { Equiv { to_: |_x| { W {} }, fro_: |_x| { W {} } } } -fn add_equiv_r(_: Equiv, EN, W, EM>) -> Equiv, (), W, ()> { +fn add_equiv_r( + _: Equiv, EN, W, EM>, +) -> Equiv, (), W, ()> { Equiv { to_: |_x| { W {} }, fro_: |_x| { W {} } } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics_move_constant_terms/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics_move_constant_terms/src/main.nr index e27d4baf1f4..4a9b1489d35 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics_move_constant_terms/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/arithmetic_generics_move_constant_terms/src/main.nr @@ -2,9 +2,12 @@ trait FromCallData { fn from_calldata(calldata: [Field; N]) -> (Self, [Field; M]); } -struct Point { x: Field, y: Field } +struct Point { + x: Field, + y: Field, +} -impl FromCallData for Field { +impl FromCallData for Field { fn from_calldata(calldata: [Field; N]) -> (Self, [Field; N - 1]) { let slice = calldata.as_slice(); let (value, slice) = slice.pop_front(); @@ -12,7 +15,7 @@ impl FromCallData for Field { } } -impl FromCallData for Point { +impl FromCallData for Point { fn from_calldata(calldata: [Field; N]) -> (Self, [Field; N - 2]) { let (x, calldata) = FromCallData::from_calldata(calldata); let (y, calldata) = FromCallData::from_calldata(calldata); diff --git a/noir/noir-repo/test_programs/compile_success_empty/assert_constant/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/assert_constant/src/main.nr index 6910a2d17b2..978f668f611 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/assert_constant/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/assert_constant/src/main.nr @@ -17,7 +17,7 @@ struct Foo { fn main( dynamic_one: Field, // == 1 - dynamic_two: Field // == 2 + dynamic_two: Field, // == 2 ) { // contents unknown at compile time // length known at compile time diff --git a/noir/noir-repo/test_programs/compile_success_empty/attributes_struct/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/attributes_struct/src/main.nr index f02e7973878..713e6321f4b 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/attributes_struct/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/attributes_struct/src/main.nr @@ -2,7 +2,7 @@ #['another_attribute] pub struct SomeStruct { a: Field, - b: Field + b: Field, } fn main() {} @@ -11,9 +11,7 @@ fn main() {} #[abi(something)] #[add_attribute] -pub struct Foo { - -} +pub struct Foo {} comptime fn add_attribute(s: StructDefinition) { assert(!s.has_named_attribute("foo")); diff --git a/noir/noir-repo/test_programs/compile_success_empty/brillig_cast/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/brillig_cast/src/main.nr index f2bede99d4c..f1a6814f4e7 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/brillig_cast/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/brillig_cast/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple Brillig function. -// +// // The features being tested are cast operations on brillig fn main() { unsafe { diff --git a/noir/noir-repo/test_programs/compile_success_empty/brillig_modulo/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/brillig_modulo/src/main.nr index dff5eadcb55..2ad43bdb7eb 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/brillig_modulo/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/brillig_modulo/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is modulo operations on brillig fn main() { unsafe { diff --git a/noir/noir-repo/test_programs/compile_success_empty/brillig_slice_input/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/brillig_slice_input/src/main.nr index 596f364b49f..436a939767e 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/brillig_slice_input/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/brillig_slice_input/src/main.nr @@ -15,31 +15,13 @@ unconstrained fn sum_slice(slice: [[Point; 2]]) -> Field { fn main() { let mut slice = &[]; - slice = slice.push_back([ - Point { - x: 13, - y: 14, - }, - Point { - x: 20, - y: 8, - } - ]); + slice = slice.push_back([Point { x: 13, y: 14 }, Point { x: 20, y: 8 }]); unsafe { let brillig_sum = sum_slice(slice); assert_eq(brillig_sum, 55); } - slice = slice.push_back([ - Point { - x: 15, - y: 5, - }, - Point { - x: 12, - y: 13, - } - ]); + slice = slice.push_back([Point { x: 15, y: 5 }, Point { x: 12, y: 13 }]); unsafe { let brillig_sum = sum_slice(slice); assert_eq(brillig_sum, 100); diff --git a/noir/noir-repo/test_programs/compile_success_empty/checked_transmute/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/checked_transmute/src/main.nr index fa6240fb43a..1acf07e98a8 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/checked_transmute/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/checked_transmute/src/main.nr @@ -5,7 +5,9 @@ fn main() { let _: [Field; 5] = distribute::<1, 2, 3>([1, 2, 3, 4, 5]); } -pub fn distribute(x: [Field; N * (A + B)]) -> [Field; N * A + N * B] { +pub fn distribute( + x: [Field; N * (A + B)], +) -> [Field; N * A + N * B] { // asserts: [Field; N * (A + B)] = [Field; N * A + N * B] // -> N * A + B = N * A + N * B // diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_array_len/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_array_len/src/main.nr index c98a3de01dd..283f3ea8d3e 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_array_len/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_array_len/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { assert_eq([1, 2, 3].len(), 3); } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_as_slice/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_as_slice/src/main.nr index 07c5e344cc2..bc3f649e52a 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_as_slice/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_as_slice/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { let ws: [Field; 3] = [1; 3]; let ws_as_slice: [Field] = ws.as_slice(); diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_change_type_each_iteration/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_change_type_each_iteration/src/main.nr index 7b34c112d4f..976987fec9e 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_change_type_each_iteration/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_change_type_each_iteration/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { for i in 9..11 { // Lengths are different on each iteration: // foo9, foo10 diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr index 95f602e04bf..132c6df6c91 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_closures/src/main.nr @@ -1,22 +1,15 @@ fn main() { - comptime - { + comptime { closure_test(0); } } fn closure_test(mut x: Field) { let one = 1; - let add1 = |z| { - (|| { - *z += one; - })() - }; + let add1 = |z| { (|| { *z += one; })() }; let two = 2; - let add2 = |z| { - *z = *z + two; - }; + let add2 = |z| { *z = *z + two; }; add1(&mut x); assert(x == 1); diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/Nargo.toml b/noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/Nargo.toml new file mode 100644 index 00000000000..0bf7ca9d0f2 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "comptime_derive_generators" +type = "bin" +authors = [""] +compiler_version = ">=0.35.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/src/main.nr new file mode 100644 index 00000000000..b79ce9956c1 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_derive_generators/src/main.nr @@ -0,0 +1,67 @@ +use std::embedded_curve_ops::EmbeddedCurvePoint; + +fn main() { + comptime { + // Result computed from executing `derive_generators` with non-comptime Noir + let result = [ + EmbeddedCurvePoint { + x: 0x0224a8abc6c8b8d50373d64cd2a1ab1567bf372b3b1f7b861d7f01257052d383, + y: 0x2358629b90eafb299d6650a311e79914b0215eb0a790810b26da5a826726d711, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x0f106f6d46bc904a5290542490b2f238775ff3c445b2f8f704c466655f460a2a, + y: 0x29ab84d472f1d33f42fe09c47b8f7710f01920d6155250126731e486877bcf27, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x0298f2e42249f0519c8a8abd91567ebe016e480f219b8c19461d6a595cc33696, + y: 0x035bec4b8520a4ece27bd5aafabee3dfe1390d7439c419a8c55aceb207aac83b, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x2c9628479de4181ea77e7b0913ccf41d2a74155b1d9c82eaa220c218781f6f3b, + y: 0x278f86b8fd95520b5da23bee1a5e354dc5dcb0cb43d6b76e628ddbffb101d776, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x0be1916f382e3532aa53a766fe74b1a983784caab90290aea7bf616bc371fb41, + y: 0x0f65545005e896f14249956344faf9addd762b7573a487b58f805a361d920a20, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x29ff8437ae5bec89981441b23036a22b7fd5bee9eff0e83c0dd5b87bfb5bd60e, + y: 0x1fd247352b77e2676b22db23cf7cd482474f543e3480b5a39c42f839a306be10, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x2f3bd4e98f8c8458cd58888749f0f5e582a43565767398e08e50e94b9b19a4d9, + y: 0x1f534906d1aa8b4ba74ad9e3f85ae3f8295e51eaafd15b5d116801b96360205b, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x27759098f425b76447c2c52728576803a1ac5de37bba875ac47cdcff539ab931, + y: 0x0aa47ee64d12d856cfb81b595c1d60ceecb693f0fdae644746ff333e39f61db7, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x015ca8d68616fde86c9108e3db04f588e0f308e60d367e963b7d460fe9a65e6c, + y: 0x2cf918009dda942ac9d59903cd2d0294d8738f938b1394170d892a027d0f347b, + is_infinite: false, + }, + EmbeddedCurvePoint { + x: 0x0d1783d5b256765515f3c9988df9f1ba7e6f5fb0248c8971fbc503ffd5187714, + y: 0x2ebb434ff4857fc3621f3bc3c6b8002b17d02d9c204e75f19b8f0b99ea68402c, + is_infinite: false, + }, + ]; + + let generators: [EmbeddedCurvePoint; 10] = + std::hash::derive_generators("DEFAULT_DOMAIN_SEPARATOR".as_bytes(), 5); + + for i in 0..10 { + assert(generators[i].x == result[i].x); + assert(generators[i].y == result[i].y); + } + } +} diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_function_definition/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_function_definition/src/main.nr index 4266d3734f9..105c1e8d577 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_function_definition/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_function_definition/src/main.nr @@ -1,9 +1,18 @@ use std::meta::type_of; -struct Foo { x: Field, field: Field } +pub struct Foo { + x: Field, + field: Field, +} #[function_attr] -pub fn foo(w: i32, y: Field, Foo { x, field: some_field }: Foo, mut a: bool, (b, c): (i32, i32)) -> i32 { +pub fn foo( + w: i32, + y: Field, + Foo { x, field: some_field }: Foo, + mut a: bool, + (b, c): (i32, i32), +) -> i32 { let _ = (w, y, x, some_field, a, b, c); 1 } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_globals_regression/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_globals_regression/src/main.nr index 54dbc0413f0..86b85fbc00a 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_globals_regression/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_globals_regression/src/main.nr @@ -1,14 +1,8 @@ comptime mut global COUNTER = 0; fn main() { - comptime - { - increment() - }; - comptime - { - increment() - }; + comptime { increment() }; + comptime { increment() }; assert_eq(get_counter(), 2); } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_keccak/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_keccak/src/main.nr index 3cde32b6ba9..dc4e88b7ab2 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_keccak/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_keccak/src/main.nr @@ -1,12 +1,13 @@ // Tests a very simple program. -// +// // The features being tested is keccak256 in brillig fn main() { - comptime - { + comptime { let x = 0xbd; let result = [ - 0x5a, 0x50, 0x2f, 0x9f, 0xca, 0x46, 0x7b, 0x26, 0x6d, 0x5b, 0x78, 0x33, 0x65, 0x19, 0x37, 0xe8, 0x05, 0x27, 0x0c, 0xa3, 0xf3, 0xaf, 0x1c, 0x0d, 0xd2, 0x46, 0x2d, 0xca, 0x4b, 0x3b, 0x1a, 0xbf + 0x5a, 0x50, 0x2f, 0x9f, 0xca, 0x46, 0x7b, 0x26, 0x6d, 0x5b, 0x78, 0x33, 0x65, 0x19, + 0x37, 0xe8, 0x05, 0x27, 0x0c, 0xa3, 0xf3, 0xaf, 0x1c, 0x0d, 0xd2, 0x46, 0x2d, 0xca, + 0x4b, 0x3b, 0x1a, 0xbf, ]; // We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field // The padding is taken care of by the program diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr index 09b1e98744d..8114fa34555 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr @@ -47,7 +47,7 @@ comptime fn outer_attribute_separate_module(m: Module) { increment_counter(); } -struct Foo {} +pub struct Foo {} #[add_function] mod add_to_me { @@ -59,15 +59,14 @@ comptime fn add_function(m: Module) { quote { pub fn added_function() -> super::Foo { add_to_me_function(); super::Foo {} - } } + } }, ); } fn main() { let _ = foo::Struct1 {}; - comptime - { + comptime { // Check Module::is_contract let foo = quote { foo }.as_module().unwrap(); assert(!foo.is_contract()); @@ -120,8 +119,7 @@ mod baz { #[test] fn as_module_test() { - comptime - { + comptime { let my_mod = quote { baz::qux }.as_module().unwrap(); assert_eq(my_mod.name(), quote { qux }); } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_mut_global/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_mut_global/src/main.nr index fa739289d37..111968a8a41 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_mut_global/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_mut_global/src/main.nr @@ -7,15 +7,13 @@ comptime fn get_unique_id() -> Field { } fn id1() -> Field { - comptime - { + comptime { get_unique_id() } } fn id2() -> Field { - comptime - { + comptime { get_unique_id() } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_parse_statement_as_expression/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_parse_statement_as_expression/src/main.nr index 4fa47dbc2f7..50e88382737 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_parse_statement_as_expression/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_parse_statement_as_expression/src/main.nr @@ -1,27 +1,26 @@ fn main() { - comptime - { - let block = quote[{ + comptime { + let block = quote {{ 1; 2; 3 - }]; + }}; let statements = block.as_expr().unwrap().as_block().unwrap(); let last = statements.pop_back().1; // `3` should fit in an expression position even though it is // originally a StatementKind::Expression - let regression1 = quote[{ + let regression1 = quote {{ let _ = $last; - }]; + }}; assert(regression1.as_expr().is_some()); // `1;` should fit in an expression position even though it is // originally a StatementKind::Semi let first = statements.pop_front().0; - let regression2 = quote[{ + let regression2 = quote {{ let _ = $first; - }]; + }}; assert(regression2.as_expr().is_some()); } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_slice_methods/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_slice_methods/src/main.nr index b76e8d70b83..8341669a0a4 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_slice_methods/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_slice_methods/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { // Comptime scopes are counted as unconstrained assert(std::runtime::is_unconstrained()); diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr index eefea67100f..fe69f2205c7 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_str_as_bytes/src/main.nr @@ -1,8 +1,8 @@ fn main() { - comptime - { + comptime { let hello_world_string = "hello world"; - let hello_world_bytes: [u8; 11] = [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]; + let hello_world_bytes: [u8; 11] = + [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]; assert_eq(hello_world_string.as_bytes(), hello_world_bytes); } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_struct_definition/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_struct_definition/src/main.nr index 97d99d0de6b..686ac26025d 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_struct_definition/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_struct_definition/src/main.nr @@ -17,10 +17,7 @@ comptime fn my_comptime_fn(typ: StructDefinition) { } comptime fn mutate_struct_fields(s: StructDefinition) { - let fields = &[ - (quote[x], quote[i32].as_type()), - (quote[y], quote[Field].as_type()) - ]; + let fields = &[(quote {x}, quote {i32}.as_type()), (quote {y}, quote {Field}.as_type())]; s.set_fields(fields); } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_to_radix/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_to_radix/src/main.nr index 959a7c12007..2233436a46c 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_to_radix/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_to_radix/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { let le_bytes: [u8; 3] = 257.to_le_bytes(); assert_eq(le_bytes, [1, 1, 0]); diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_constraint/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_constraint/src/main.nr index 43075058480..2f24675e8c7 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_constraint/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_constraint/src/main.nr @@ -5,8 +5,7 @@ trait TraitWithGenerics { } fn main() { - comptime - { + comptime { let constraint1 = quote { Default }.as_trait_constraint(); let constraint2 = quote { TraitWithGenerics }.as_trait_constraint(); diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_impl/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_impl/src/main.nr index 8498e75d7f4..598f04c5d3d 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_impl/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_trait_impl/src/main.nr @@ -1,17 +1,14 @@ trait SomeTrait { fn foo(); } -pub struct SomeStruct { - -} +pub struct SomeStruct {} impl SomeTrait for SomeStruct { fn foo() {} } fn main() { - comptime - { + comptime { let some_struct = quote { SomeStruct }.as_type(); let some_trait = quote { SomeTrait }.as_trait_constraint(); let trait_impl = some_struct.get_trait_impl(some_trait).unwrap(); diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_traits/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_traits/src/main.nr index 60fe264c57c..11025d45024 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_traits/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_traits/src/main.nr @@ -1,8 +1,7 @@ use std::ops::Neg; fn main() { - comptime - { + comptime { // impl Eq for Field assert(3 == 3); @@ -27,8 +26,7 @@ impl Neg for MyType { } pub fn neg_at_comptime() { - comptime - { + comptime { let value = MyType { value: 1 }; let _result = -value; } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_type/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_type/src/main.nr index 68c3477b027..887690cb6cb 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_type/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_type/src/main.nr @@ -1,21 +1,15 @@ use std::meta::type_of; struct Foo { - x: T + x: T, } -trait SomeTrait { - -} -pub struct StructImplementsSomeTrait { - -} +trait SomeTrait {} +pub struct StructImplementsSomeTrait {} impl SomeTrait for StructImplementsSomeTrait {} -pub struct StructDoesNotImplementSomeTrait { - -} +pub struct StructDoesNotImplementSomeTrait {} // docs:start:serialize-setup trait Serialize {} @@ -23,15 +17,19 @@ trait Serialize {} impl Serialize<1> for Field {} impl Serialize for [T; N] - where T: Serialize {} +where + T: Serialize, +{} impl Serialize for (T, U) - where T: Serialize, U: Serialize {} +where + T: Serialize, + U: Serialize, +{} // docs:end:serialize-setup fn main() { - comptime - { + comptime { // Check type_of works correctly (relies on Eq for Type) let a_field = 0; let another_field = 1; @@ -82,7 +80,7 @@ fn main() { let array = [1, 2, 3]; let array_type = type_of(array); - let (array_type_element_type , array_length) = array_type.as_array().unwrap(); + let (array_type_element_type, array_length) = array_type.as_array().unwrap(); assert_eq(array_type_element_type, field_type_1); // Check Type::as_constant @@ -111,7 +109,8 @@ fn main() { // Check Type::implements let some_trait_i32 = quote { SomeTrait }.as_trait_constraint(); let struct_implements_some_trait = quote { StructImplementsSomeTrait }.as_type(); - let struct_does_not_implement_some_trait = quote { StructDoesNotImplementSomeTrait }.as_type(); + let struct_does_not_implement_some_trait = + quote { StructDoesNotImplementSomeTrait }.as_type(); assert(struct_implements_some_trait.implements(some_trait_i32)); assert(!struct_does_not_implement_some_trait.implements(some_trait_i32)); @@ -148,7 +147,6 @@ fn main() { // Now typevar2 should be bound to the serialized pair size 2 times the array length 5 assert_eq(typevar2.as_constant().unwrap(), 10); // docs:end:fresh-type-variable-example - // Check Type::is_unit let unit = quote { () }.as_type(); assert(unit.is_unit()); @@ -160,9 +158,11 @@ fn main() { } // docs:start:implements_example -pub fn function_with_where(_x: T) where T: SomeTrait { - comptime - { +pub fn function_with_where(_x: T) +where + T: SomeTrait, +{ + comptime { let t = quote { T }.as_type(); let some_trait_i32 = quote { SomeTrait }.as_trait_constraint(); assert(t.implements(some_trait_i32)); diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_typed_expr/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_typed_expr/src/main.nr index ba2594f1da9..361f6e8a1c8 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_typed_expr/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_typed_expr/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { let expr = quote { [1, 3] }.as_expr().unwrap().resolve(Option::none()); assert_eq(expr.get_type().unwrap(), quote { [Field; 2] }.as_type()); } diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_unresolved_type/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_unresolved_type/src/main.nr index aba4461d4af..e3a5f7ad4ca 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_unresolved_type/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_unresolved_type/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { // Check UnresolvedType::is_bool let typ = quote { x as bool }.as_expr().unwrap().as_cast().unwrap().1; assert(typ.is_bool()); diff --git a/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_579/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_579/src/main.nr index a517f4fdb70..758c6fefc28 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_579/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_579/src/main.nr @@ -7,7 +7,7 @@ fn main() { } struct MyStruct579 { - array_param: [u32; 2] + array_param: [u32; 2], } impl MyStruct579 { @@ -20,7 +20,7 @@ fn test(flag: bool) -> MyStruct579 { let mut my_struct = MyStruct579::new([0; 2]); if flag == true { - my_struct= MyStruct579::new([1; 2]); + my_struct = MyStruct579::new([1; 2]); } my_struct } diff --git a/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_to_bits/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_to_bits/src/main.nr index 5205e2bff73..dd80d2c576f 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_to_bits/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_to_bits/src/main.nr @@ -1,5 +1,5 @@ fn main() { - //Regression for to_le_bits() constant evaluation + //Regression for to_le_bits() constant evaluation // binary array representation of u8 1 let arr: [u8; 2] = [1, 2]; let as_bits_hardcode_1 = [1, 0]; diff --git a/noir/noir-repo/test_programs/compile_success_empty/ctstring/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/ctstring/src/main.nr index b2329cb1997..61cd848a436 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/ctstring/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/ctstring/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { let msg1 = "msg1"; let msg2 = f" (msg2 contains {msg1}) "; diff --git a/noir/noir-repo/test_programs/compile_success_empty/derive_impl/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/derive_impl/src/main.nr index 69cb641e7c7..db3f78a35c6 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/derive_impl/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/derive_impl/src/main.nr @@ -1,7 +1,9 @@ comptime fn derive_default(typ: StructDefinition) -> Quoted { let generics = typ.generics(); assert_eq( - generics.len(), 0, "derive_default: Deriving Default on generic types is currently unimplemented" + generics.len(), + 0, + "derive_default: Deriving Default on generic types is currently unimplemented", ); let type_name = typ.as_type(); diff --git a/noir/noir-repo/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr index 207869e5291..935b1c613ad 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/ec_baby_jubjub/src/main.nr @@ -19,38 +19,30 @@ fn main() { 168696, Gaffine::new( 995203441582195749578291179787384436505546430278305826713579947235728471134, - 5472060717959818805561601436314318772137091100104008585924551046643952123905 - ) + 5472060717959818805561601436314318772137091100104008585924551046643952123905, + ), ); // Test addition let p1_affine = Gaffine::new( 17777552123799933955779906779655732241715742912184938656739573121738514868268, - 2626589144620713026669568689430873010625803728049924121243784502389097019475 + 2626589144620713026669568689430873010625803728049924121243784502389097019475, ); let p2_affine = Gaffine::new( 16540640123574156134436876038791482806971768689494387082833631921987005038935, - 20819045374670962167435360035096875258406992893633759881276124905556507972311 + 20819045374670962167435360035096875258406992893633759881276124905556507972311, ); let p3_affine = bjj_affine.add(p1_affine, p2_affine); - assert( - p3_affine.eq( - Gaffine::new( - 7916061937171219682591368294088513039687205273691143098332585753343424131937, - 14035240266687799601661095864649209771790948434046947201833777492504781204499 - ) - ) - ); + assert(p3_affine.eq(Gaffine::new( + 7916061937171219682591368294088513039687205273691143098332585753343424131937, + 14035240266687799601661095864649209771790948434046947201833777492504781204499, + ))); // Test scalar multiplication let p4_affine = bjj_affine.mul(2, p1_affine); - assert( - p4_affine.eq( - Gaffine::new( - 6890855772600357754907169075114257697580319025794532037257385534741338397365, - 4338620300185947561074059802482547481416142213883829469920100239455078257889 - ) - ) - ); + assert(p4_affine.eq(Gaffine::new( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889, + ))); assert(p4_affine.eq(bjj_affine.bit_mul([0, 1], p1_affine))); // Test subtraction let p5_affine = bjj_affine.subtract(p3_affine, p3_affine); @@ -58,11 +50,11 @@ fn main() { // Check that these points are on the curve assert( bjj_affine.contains(bjj_affine.gen) - & bjj_affine.contains(p1_affine) - & bjj_affine.contains(p2_affine) - & bjj_affine.contains(p3_affine) - & bjj_affine.contains(p4_affine) - & bjj_affine.contains(p5_affine) + & bjj_affine.contains(p1_affine) + & bjj_affine.contains(p2_affine) + & bjj_affine.contains(p3_affine) + & bjj_affine.contains(p4_affine) + & bjj_affine.contains(p5_affine), ); // Test CurveGroup equivalents let bjj = bjj_affine.into_group(); // Baby Jubjub @@ -82,11 +74,11 @@ fn main() { // Check that these points are on the curve assert( bjj.contains(bjj.gen) - & bjj.contains(p1) - & bjj.contains(p2) - & bjj.contains(p3) - & bjj.contains(p4) - & bjj.contains(p5) + & bjj.contains(p1) + & bjj.contains(p2) + & bjj.contains(p3) + & bjj.contains(p4) + & bjj.contains(p5), ); // Test SWCurve equivalents of the above // First the affine representation @@ -103,16 +95,19 @@ fn main() { assert(p4_swcurve_affine.eq(bjj_swcurve_affine.mul(2, p1_swcurve_affine))); assert(p4_swcurve_affine.eq(bjj_swcurve_affine.bit_mul([0, 1], p1_swcurve_affine))); // Subtraction - assert(SWGaffine::zero().eq(bjj_swcurve_affine.subtract(p3_swcurve_affine, p3_swcurve_affine))); + assert(SWGaffine::zero().eq(bjj_swcurve_affine.subtract( + p3_swcurve_affine, + p3_swcurve_affine, + ))); assert(p5_swcurve_affine.eq(SWGaffine::zero())); // Check that these points are on the curve assert( bjj_swcurve_affine.contains(bjj_swcurve_affine.gen) - & bjj_swcurve_affine.contains(p1_swcurve_affine) - & bjj_swcurve_affine.contains(p2_swcurve_affine) - & bjj_swcurve_affine.contains(p3_swcurve_affine) - & bjj_swcurve_affine.contains(p4_swcurve_affine) - & bjj_swcurve_affine.contains(p5_swcurve_affine) + & bjj_swcurve_affine.contains(p1_swcurve_affine) + & bjj_swcurve_affine.contains(p2_swcurve_affine) + & bjj_swcurve_affine.contains(p3_swcurve_affine) + & bjj_swcurve_affine.contains(p4_swcurve_affine) + & bjj_swcurve_affine.contains(p5_swcurve_affine), ); // Then the CurveGroup representation let bjj_swcurve = bjj.into_swcurve(); @@ -133,11 +128,11 @@ fn main() { // Check that these points are on the curve assert( bjj_swcurve.contains(bjj_swcurve.gen) - & bjj_swcurve.contains(p1_swcurve) - & bjj_swcurve.contains(p2_swcurve) - & bjj_swcurve.contains(p3_swcurve) - & bjj_swcurve.contains(p4_swcurve) - & bjj_swcurve.contains(p5_swcurve) + & bjj_swcurve.contains(p1_swcurve) + & bjj_swcurve.contains(p2_swcurve) + & bjj_swcurve.contains(p3_swcurve) + & bjj_swcurve.contains(p4_swcurve) + & bjj_swcurve.contains(p5_swcurve), ); // Test MontCurve conversions // First the affine representation @@ -149,21 +144,27 @@ fn main() { let p4_montcurve_affine = p4_affine.into_montcurve(); let p5_montcurve_affine = p5_affine.into_montcurve(); // Addition - assert(p3_montcurve_affine.eq(bjj_montcurve_affine.add(p1_montcurve_affine, p2_montcurve_affine))); + assert(p3_montcurve_affine.eq(bjj_montcurve_affine.add( + p1_montcurve_affine, + p2_montcurve_affine, + ))); // Doubling assert(p4_montcurve_affine.eq(bjj_montcurve_affine.mul(2, p1_montcurve_affine))); assert(p4_montcurve_affine.eq(bjj_montcurve_affine.bit_mul([0, 1], p1_montcurve_affine))); // Subtraction - assert(MGaffine::zero().eq(bjj_montcurve_affine.subtract(p3_montcurve_affine, p3_montcurve_affine))); + assert(MGaffine::zero().eq(bjj_montcurve_affine.subtract( + p3_montcurve_affine, + p3_montcurve_affine, + ))); assert(p5_montcurve_affine.eq(MGaffine::zero())); // Check that these points are on the curve assert( bjj_montcurve_affine.contains(bjj_montcurve_affine.gen) - & bjj_montcurve_affine.contains(p1_montcurve_affine) - & bjj_montcurve_affine.contains(p2_montcurve_affine) - & bjj_montcurve_affine.contains(p3_montcurve_affine) - & bjj_montcurve_affine.contains(p4_montcurve_affine) - & bjj_montcurve_affine.contains(p5_montcurve_affine) + & bjj_montcurve_affine.contains(p1_montcurve_affine) + & bjj_montcurve_affine.contains(p2_montcurve_affine) + & bjj_montcurve_affine.contains(p3_montcurve_affine) + & bjj_montcurve_affine.contains(p4_montcurve_affine) + & bjj_montcurve_affine.contains(p5_montcurve_affine), ); // Then the CurveGroup representation let bjj_montcurve = bjj.into_montcurve(); @@ -184,35 +185,26 @@ fn main() { // Check that these points are on the curve assert( bjj_montcurve.contains(bjj_montcurve.gen) - & bjj_montcurve.contains(p1_montcurve) - & bjj_montcurve.contains(p2_montcurve) - & bjj_montcurve.contains(p3_montcurve) - & bjj_montcurve.contains(p4_montcurve) - & bjj_montcurve.contains(p5_montcurve) + & bjj_montcurve.contains(p1_montcurve) + & bjj_montcurve.contains(p2_montcurve) + & bjj_montcurve.contains(p3_montcurve) + & bjj_montcurve.contains(p4_montcurve) + & bjj_montcurve.contains(p5_montcurve), ); // Elligator 2 map-to-curve let ell2_pt_map = bjj_affine.elligator2_map(27); - assert( - ell2_pt_map.eq( - MGaffine::new( - 7972459279704486422145701269802978968072470631857513331988813812334797879121, - 8142420778878030219043334189293412482212146646099536952861607542822144507872 - ).into_tecurve() - ) - ); + assert(ell2_pt_map.eq(MGaffine::new( + 7972459279704486422145701269802978968072470631857513331988813812334797879121, + 8142420778878030219043334189293412482212146646099536952861607542822144507872, + ) + .into_tecurve())); // SWU map-to-curve let swu_pt_map = bjj_affine.swu_map(5, 27); - assert( - swu_pt_map.eq( - bjj_affine.map_from_swcurve( - SWGaffine::new( - 2162719247815120009132293839392097468339661471129795280520343931405114293888, - 5341392251743377373758788728206293080122949448990104760111875914082289313973 - ) - ) - ) - ); + assert(swu_pt_map.eq(bjj_affine.map_from_swcurve(SWGaffine::new( + 2162719247815120009132293839392097468339661471129795280520343931405114293888, + 5341392251743377373758788728206293080122949448990104760111875914082289313973, + )))); } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/embedded_curve_add_simplification/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/embedded_curve_add_simplification/src/main.nr index 5a619906775..8984bd54979 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/embedded_curve_add_simplification/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/embedded_curve_add_simplification/src/main.nr @@ -2,7 +2,11 @@ use std::embedded_curve_ops::EmbeddedCurvePoint; fn main() { let zero = EmbeddedCurvePoint::point_at_infinity(); - let g1 = EmbeddedCurvePoint { x: 1, y: 17631683881184975370165255887551781615748388533673675138860, is_infinite: false }; + let g1 = EmbeddedCurvePoint { + x: 1, + y: 17631683881184975370165255887551781615748388533673675138860, + is_infinite: false, + }; assert(g1 + zero == g1); assert(g1 - g1 == zero); diff --git a/noir/noir-repo/test_programs/compile_success_empty/generators/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/generators/src/main.nr index 20bdedee50f..58aebc92b72 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/generators/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/generators/src/main.nr @@ -21,7 +21,7 @@ fn fibonacci_generator() -> fn[(&mut Field, &mut Field)]() -> Field { *y = *x + *y; *x = old_y; - + old_x } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/src/main.nr index 3cec46bdfcd..8ce6ce3314d 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/src/main.nr @@ -6,7 +6,10 @@ trait Bar { } } -impl Bar for (T, T) where T: Bar { +impl Bar for (T, T) +where + T: Bar, +{ fn ok(self) -> Self { self } diff --git a/noir/noir-repo/test_programs/compile_success_empty/impl_where_clause/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/impl_where_clause/src/main.nr index 2f3223efaae..9cf0d26132c 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/impl_where_clause/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/impl_where_clause/src/main.nr @@ -18,7 +18,10 @@ impl MyEq for InnerStruct { } } -impl MyStruct where T: MyEq { +impl MyStruct +where + T: MyEq, +{ fn my_eq(self, other: Self) -> bool { (self.a == other.a) & self.b.my_eq(other.b) } diff --git a/noir/noir-repo/test_programs/compile_success_empty/inject_context_attribute/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/inject_context_attribute/src/main.nr index 156579ce0b2..963d4cea969 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/inject_context_attribute/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/inject_context_attribute/src/main.nr @@ -40,21 +40,20 @@ comptime fn inject_context(f: FunctionDefinition) { } comptime fn mapping_function(expr: Expr, f: FunctionDefinition) -> Option { - expr.as_function_call().and_then( - |func_call: (Expr, [Expr])| { + expr.as_function_call().and_then(|func_call: (Expr, [Expr])| { let (name, arguments) = func_call; name.resolve(Option::some(f)).as_function_definition().and_then( |function_definition: FunctionDefinition| { - if function_definition.has_named_attribute("inject_context") { - let arguments = arguments.push_front(quote { _context }.as_expr().unwrap()); - let arguments = arguments.map(|arg: Expr| arg.quoted()).join(quote { , }); - Option::some(quote { $name($arguments) }.as_expr().unwrap()) - } else { - Option::none() - } - } - )} - ) + if function_definition.has_named_attribute("inject_context") { + let arguments = arguments.push_front(quote { _context }.as_expr().unwrap()); + let arguments = arguments.map(|arg: Expr| arg.quoted()).join(quote { , }); + Option::some(quote { $name($arguments) }.as_expr().unwrap()) + } else { + Option::none() + } + }, + ) + }) } fn main() { diff --git a/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr index ce847b56b93..57890cd6b67 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/inner_outer_cl/src/main.nr @@ -2,9 +2,7 @@ fn main() { let z1 = 0; let z2 = 1; let cl_outer = |x| { - let cl_inner = |y| { - x + y + z2 - }; + let cl_inner = |y| { x + y + z2 }; cl_inner(1) + z1 }; let result = cl_outer(1); diff --git a/noir/noir-repo/test_programs/compile_success_empty/macros_in_comptime/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/macros_in_comptime/src/main.nr index 197f4e87f0b..799091fca09 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/macros_in_comptime/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/macros_in_comptime/src/main.nr @@ -5,11 +5,8 @@ use std::meta::unquote; global three_field: Field = 3; fn main() { - comptime - { - unsafe { - foo::(5) - }; + comptime { + unsafe { foo::(5) }; submodule::bar(); } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/method_call_regression/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/method_call_regression/src/main.nr index 26493c4836b..f5b28978ef7 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/method_call_regression/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/method_call_regression/src/main.nr @@ -5,7 +5,10 @@ fn main() { s.foo(); } -struct Struct { a: A, b: B } +struct Struct { + a: A, + b: B, +} // Before the fix, this candidate is searched first, binding ? to `u8` permanently. impl Struct { diff --git a/noir/noir-repo/test_programs/compile_success_empty/no_duplicate_methods/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/no_duplicate_methods/src/main.nr index 8b809715529..7e25a61d2ff 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/no_duplicate_methods/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/no_duplicate_methods/src/main.nr @@ -7,7 +7,9 @@ trait ToField2 { fn to_field(self) -> Field; } -pub struct Foo { x: Field } +pub struct Foo { + x: Field, +} impl ToField for Foo { fn to_field(self) -> Field { diff --git a/noir/noir-repo/test_programs/compile_success_empty/numeric_generics/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/numeric_generics/src/main.nr index 04f170aef58..1bdde60bcd5 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/numeric_generics/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/numeric_generics/src/main.nr @@ -32,7 +32,7 @@ impl MyStruct { } } -fn foo(mut s: MyStruct<2+1>) -> MyStruct<10/2-2> { +fn foo(mut s: MyStruct<2 + 1>) -> MyStruct<10 / 2 - 2> { s.data[0] = s.data[0] + 1; s } diff --git a/noir/noir-repo/test_programs/compile_success_empty/numeric_generics_explicit/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/numeric_generics_explicit/src/main.nr index c940e28dac2..c2eeeb37395 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/numeric_generics_explicit/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/numeric_generics_explicit/src/main.nr @@ -48,7 +48,7 @@ impl MyStruct { } } -fn foo(mut s: MyStruct<2+1>) -> MyStruct<10/2-2> { +fn foo(mut s: MyStruct<2 + 1>) -> MyStruct<10 / 2 - 2> { s.data[0] = s.data[0] + 1; s } @@ -88,7 +88,10 @@ trait Deserialize { pub struct PublicStorage {} impl PublicStorage { - fn read() -> T where T: Deserialize { + fn read() -> T + where + T: Deserialize, + { // Used as a type within a function body let mut fields: [Field; N] = [0; N]; // Used a loop bound @@ -104,7 +107,7 @@ impl PublicStorage { // which are declared after the parent struct pub struct NestedNumeric { a: Field, - b: InnerNumeric + b: InnerNumeric, } pub struct InnerNumeric { inner: [u32; N], diff --git a/noir/noir-repo/test_programs/compile_success_empty/regression_2099/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/regression_2099/src/main.nr index b390daec8c8..3fe3cdaf39a 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/regression_2099/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/regression_2099/src/main.nr @@ -8,17 +8,17 @@ fn main() { 168696, Gaffine::new( 995203441582195749578291179787384436505546430278305826713579947235728471134, - 5472060717959818805561601436314318772137091100104008585924551046643952123905 - ) + 5472060717959818805561601436314318772137091100104008585924551046643952123905, + ), ); // Test addition let p1_affine = Gaffine::new( 17777552123799933955779906779655732241715742912184938656739573121738514868268, - 2626589144620713026669568689430873010625803728049924121243784502389097019475 + 2626589144620713026669568689430873010625803728049924121243784502389097019475, ); let p2_affine = Gaffine::new( 16540640123574156134436876038791482806971768689494387082833631921987005038935, - 20819045374670962167435360035096875258406992893633759881276124905556507972311 + 20819045374670962167435360035096875258406992893633759881276124905556507972311, ); let _p3_affine = bjj_affine.add(p1_affine, p2_affine); // Test SWCurve equivalents of the above diff --git a/noir/noir-repo/test_programs/compile_success_empty/regression_4635/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/regression_4635/src/main.nr index 6bccdf9e30f..f33effb6bdb 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/regression_4635/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/regression_4635/src/main.nr @@ -15,7 +15,7 @@ trait Deserialize { global AZTEC_ADDRESS_LENGTH: u32 = 1; struct AztecAddress { - inner : Field + inner: Field, } impl FromField for AztecAddress { @@ -39,10 +39,13 @@ impl Eq for AztecAddress { // Custom code struct MyStruct { - a: T + a: T, } -impl Deserialize<1> for MyStruct where T: FromField { +impl Deserialize<1> for MyStruct +where + T: FromField, +{ fn deserialize(fields: [Field; 1]) -> Self { Self { a: FromField::from_field(fields[0]) } } @@ -51,7 +54,6 @@ impl Deserialize<1> for MyStruct where T: FromField { fn main() { let fields = [5; 1]; let foo = MyStruct::deserialize(fields); // Note I don't specify T here (the type of `foo.a`) - let bar = AztecAddress { inner: 5 }; // Here `T` is apparently inferred to be `AztecAddress`, presumably because of the comparison. diff --git a/noir/noir-repo/test_programs/compile_success_empty/regression_5065/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/regression_5065/src/main.nr index 36b0570165f..6ffb6e4e237 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/regression_5065/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/regression_5065/src/main.nr @@ -24,7 +24,10 @@ impl MyTrait for MyType { } } -fn foo() -> T where T: MyTrait { +fn foo() -> T +where + T: MyTrait, +{ MyTrait::new() } diff --git a/noir/noir-repo/test_programs/compile_success_empty/regression_6077/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/regression_6077/src/main.nr index fe067177e77..971d487316f 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/regression_6077/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/regression_6077/src/main.nr @@ -1,4 +1,4 @@ -struct WeirdStruct { +pub struct WeirdStruct { a: T, b: U, } @@ -19,7 +19,9 @@ comptime fn mangle_fn(f: FunctionDefinition) { { WeirdStruct { a: 1, b: [0;3] } } - }.as_expr().unwrap(); + } + .as_expr() + .unwrap(); f.set_return_type(new_return_type); f.set_body(new_body); diff --git a/noir/noir-repo/test_programs/compile_success_empty/ret_fn_ret_cl/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/ret_fn_ret_cl/src/main.nr index 89083b076b6..0e99a92585b 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/ret_fn_ret_cl/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/ret_fn_ret_cl/src/main.nr @@ -17,9 +17,7 @@ fn ret_fn() -> fn(Field) -> Field { // inner_closure // } fn ret_lambda() -> fn(Field) -> Field { - let cl = |z: Field| -> Field { - z + 1 - }; + let cl = |z: Field| -> Field { z + 1 }; cl } diff --git a/noir/noir-repo/test_programs/compile_success_empty/schnorr_simplification/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/schnorr_simplification/src/main.nr index 1a9023e2d7a..cdfa8337094 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/schnorr_simplification/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/schnorr_simplification/src/main.nr @@ -5,70 +5,10 @@ fn main() { let pub_key_x = 0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a; let pub_key_y = 0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197; let signature = [ - 1, - 13, - 119, - 112, - 212, - 39, - 233, - 41, - 84, - 235, - 255, - 93, - 245, - 172, - 186, - 83, - 157, - 253, - 76, - 77, - 33, - 128, - 178, - 15, - 214, - 67, - 105, - 107, - 177, - 234, - 77, - 48, - 27, - 237, - 155, - 84, - 39, - 84, - 247, - 27, - 22, - 8, - 176, - 230, - 24, - 115, - 145, - 220, - 254, - 122, - 135, - 179, - 171, - 4, - 214, - 202, - 64, - 199, - 19, - 84, - 239, - 138, - 124, - 12 + 1, 13, 119, 112, 212, 39, 233, 41, 84, 235, 255, 93, 245, 172, 186, 83, 157, 253, 76, 77, + 33, 128, 178, 15, 214, 67, 105, 107, 177, 234, 77, 48, 27, 237, 155, 84, 39, 84, 247, 27, + 22, 8, 176, 230, 24, 115, 145, 220, 254, 122, 135, 179, 171, 4, 214, 202, 64, 199, 19, 84, + 239, 138, 124, 12, ]; let valid_signature = std::schnorr::verify_signature(pub_key_x, pub_key_y, signature, message); diff --git a/noir/noir-repo/test_programs/compile_success_empty/serialize/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/serialize/src/main.nr index 19f3f0319b8..66c79f9fc9d 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/serialize/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/serialize/src/main.nr @@ -5,7 +5,11 @@ trait Serialize { fn serialize(self) -> [Field; Self::Size]; } -impl Serialize for (A, B) where A: Serialize, B: Serialize { +impl Serialize for (A, B) +where + A: Serialize, + B: Serialize, +{ // let Size = ::Size + ::Size; let Size: u32 = AS + BS; @@ -24,7 +28,10 @@ impl Serialize for (A, B) where A: Serialize Serialize for [T; N] where T: Serialize { +impl Serialize for [T; N] +where + T: Serialize, +{ // let Size = ::Size * N; let Size: u32 = TS * N; diff --git a/noir/noir-repo/test_programs/compile_success_empty/simple_program_no_body/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/simple_program_no_body/src/main.nr index 21719018f3f..8605ff1a9cc 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/simple_program_no_body/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/simple_program_no_body/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested are: // - Abi generation of private and public // main parameters. diff --git a/noir/noir-repo/test_programs/compile_success_empty/simple_range/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/simple_range/src/main.nr index 3f595cfd817..b7c319cfed4 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/simple_range/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/simple_range/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is casting to an integer fn main(x: Field) { let _z = x as u32; diff --git a/noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr index 217000694b0..d65f8a4f040 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr @@ -10,7 +10,10 @@ fn main() { assert_eq(odds_and_evens, &[1, 3, 5, 100, 2, 4]); } -fn append_three(one: T, two: T, three: T) -> T where T: Append { +fn append_three(one: T, two: T, three: T) -> T +where + T: Append, +{ // The `T::empty()`s here should do nothing T::empty().append(one).append(two).append(three).append(T::empty()) } diff --git a/noir/noir-repo/test_programs/compile_success_empty/static_assert/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/static_assert/src/main.nr index 11d30e4e069..873efe734e1 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/static_assert/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/static_assert/src/main.nr @@ -17,7 +17,7 @@ pub struct Foo { fn main( dynamic_one: Field, // == 1 - dynamic_two: Field // == 2 + dynamic_two: Field, // == 2 ) { // contents unknown at compile time // length known at compile time diff --git a/noir/noir-repo/test_programs/compile_success_empty/to_bits/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/to_bits/src/main.nr index 918a2fad036..dc2ff4be394 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/to_bits/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/to_bits/src/main.nr @@ -1,7 +1,7 @@ fn main() { let field = 1000; - let be_bits:[u1; 16] = field.to_be_bits(); - let le_bits:[u1; 16] = field.to_le_bits(); + let be_bits: [u1; 16] = field.to_be_bits(); + let le_bits: [u1; 16] = field.to_le_bits(); for i in 0..16 { let x = be_bits[i]; diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_allowed_item_name_matches/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_allowed_item_name_matches/src/main.nr index 4104ca71037..f32445202b7 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_allowed_item_name_matches/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_allowed_item_name_matches/src/main.nr @@ -1,25 +1,25 @@ pub trait Trait1 { - // types and consts with the same name are allowed - type Tralala; - let Tralala: u32; + // types and consts with the same name are allowed + type Tralala; + let Tralala: u32; } pub trait Trait2 { - // consts and types with the same name are allowed - let Tralala: u32; - type Tralala; + // consts and types with the same name are allowed + let Tralala: u32; + type Tralala; } pub trait Trait3 { - // types and functions with the same name are allowed - type Tralala; - fn Tralala(); + // types and functions with the same name are allowed + type Tralala; + fn Tralala(); } pub trait Trait4 { - // functions and types with the same name are allowed - fn Tralala(); - type Tralala; + // functions and types with the same name are allowed + fn Tralala(); + type Tralala; } fn main() {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_associated_member_names_clashes/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_associated_member_names_clashes/src/main.nr index 06bf311aa3c..953ee321b47 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_associated_member_names_clashes/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_associated_member_names_clashes/src/main.nr @@ -6,8 +6,7 @@ trait Trait2 { fn tralala() -> Field; } -pub struct Struct1 { -} +pub struct Struct1 {} impl Struct1 { fn tralala() -> Field { diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_default_implementation/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_default_implementation/src/main.nr index 361d82ff3df..ecfa6da0818 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_default_implementation/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_default_implementation/src/main.nr @@ -2,7 +2,7 @@ trait MyDefault { fn my_default(x: Field, y: Field) -> Self; fn method2(x: Field) -> Field { - x + x } } diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_function_calls/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_function_calls/src/main.nr index 352f18a74c0..f9a338bfa47 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_function_calls/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_function_calls/src/main.nr @@ -30,7 +30,9 @@ trait Trait1a { 43278 } } -struct Struct1a { vl: Field } +struct Struct1a { + vl: Field, +} impl Trait1a for Struct1a {} // 1b) trait default method -> trait overriden method trait Trait1b { @@ -41,7 +43,9 @@ trait Trait1b { 9323 } } -struct Struct1b { vl: Field } +struct Struct1b { + vl: Field, +} impl Trait1b for Struct1b { fn trait_method2(self) -> Field { let _ = self; @@ -55,7 +59,9 @@ trait Trait1c { } fn trait_method2(self) -> Field; } -struct Struct1c { vl: Field } +struct Struct1c { + vl: Field, +} impl Trait1c for Struct1c { fn trait_method2(self) -> Field { let _ = self; @@ -72,7 +78,9 @@ trait Trait1d { 29341 } } -struct Struct1d { vl: Field } +struct Struct1d { + vl: Field, +} impl Trait1d for Struct1d { fn trait_method1(self) -> Field { self.trait_method2() * 9342 - self.vl @@ -87,7 +95,9 @@ trait Trait1e { 2381 } } -struct Struct1e { vl: Field } +struct Struct1e { + vl: Field, +} impl Trait1e for Struct1e { fn trait_method1(self) -> Field { self.trait_method2() * 47324 - self.vl @@ -104,7 +114,9 @@ trait Trait1f { } fn trait_method2(self) -> Field; } -struct Struct1f { vl: Field } +struct Struct1f { + vl: Field, +} impl Trait1f for Struct1f { fn trait_method1(self) -> Field { self.trait_method2() * 34875 - self.vl @@ -122,7 +134,9 @@ trait Trait1g { 37845 } } -struct Struct1g { vl: Field } +struct Struct1g { + vl: Field, +} impl Trait1g for Struct1g { fn trait_method1(self) -> Field { self.trait_method2() * 7854 - self.vl @@ -135,7 +149,9 @@ trait Trait1h { 7823 } } -struct Struct1h { vl: Field } +struct Struct1h { + vl: Field, +} impl Trait1h for Struct1h { fn trait_method1(self) -> Field { self.trait_method2() * 3482 - self.vl @@ -150,7 +166,9 @@ trait Trait1i { fn trait_method1(self) -> Field; fn trait_method2(self) -> Field; } -struct Struct1i { vl: Field } +struct Struct1i { + vl: Field, +} impl Trait1i for Struct1i { fn trait_method1(self) -> Field { self.trait_method2() * 23478 - self.vl @@ -170,7 +188,9 @@ trait Trait2a { 7843 } } -struct Struct2a { vl: Field } +struct Struct2a { + vl: Field, +} impl Trait2a for Struct2a {} // 2b) trait default method -> trait overriden function trait Trait2b { @@ -181,7 +201,9 @@ trait Trait2b { 3752 } } -struct Struct2b { vl: Field } +struct Struct2b { + vl: Field, +} impl Trait2b for Struct2b { fn trait_function2() -> Field { 8477 @@ -194,7 +216,9 @@ trait Trait2c { } fn trait_function2() -> Field; } -struct Struct2c { vl: Field } +struct Struct2c { + vl: Field, +} impl Trait2c for Struct2c { fn trait_function2() -> Field { 8342 @@ -209,7 +233,9 @@ trait Trait2d { 384 } } -struct Struct2d { vl: Field } +struct Struct2d { + vl: Field, +} impl Trait2d for Struct2d { fn trait_method1(self) -> Field { Self::trait_function2() * 3984 - self.vl @@ -224,7 +250,9 @@ trait Trait2e { 97342 } } -struct Struct2e { vl: Field } +struct Struct2e { + vl: Field, +} impl Trait2e for Struct2e { fn trait_method1(self) -> Field { Self::trait_function2() * 7363 - self.vl @@ -240,7 +268,9 @@ trait Trait2f { } fn trait_function2() -> Field; } -struct Struct2f { vl: Field } +struct Struct2f { + vl: Field, +} impl Trait2f for Struct2f { fn trait_method1(self) -> Field { Self::trait_function2() * 6362 - self.vl @@ -256,7 +286,9 @@ trait Trait2g { 19273 } } -struct Struct2g { vl: Field } +struct Struct2g { + vl: Field, +} impl Trait2g for Struct2g { fn trait_method1(self) -> Field { Self::trait_function2() * 9123 - self.vl @@ -269,7 +301,9 @@ trait Trait2h { 1281 } } -struct Struct2h { vl: Field } +struct Struct2h { + vl: Field, +} impl Trait2h for Struct2h { fn trait_method1(self) -> Field { Self::trait_function2() * 4833 - self.vl @@ -283,7 +317,9 @@ trait Trait2i { fn trait_method1(self) -> Field; fn trait_function2() -> Field; } -struct Struct2i { vl: Field } +struct Struct2i { + vl: Field, +} impl Trait2i for Struct2i { fn trait_method1(self) -> Field { Self::trait_function2() * 2291 - self.vl @@ -303,7 +339,9 @@ trait Trait3a { 19212 } } -struct Struct3a { vl: Field } +struct Struct3a { + vl: Field, +} impl Trait3a for Struct3a {} // 3b) trait default function -> trait overriden method trait Trait3b { @@ -314,7 +352,9 @@ trait Trait3b { 9111 } } -struct Struct3b { vl: Field } +struct Struct3b { + vl: Field, +} impl Trait3b for Struct3b { fn trait_method2(self) -> Field { let _ = self; @@ -328,7 +368,9 @@ trait Trait3c { } fn trait_method2(self) -> Field; } -struct Struct3c { vl: Field } +struct Struct3c { + vl: Field, +} impl Trait3c for Struct3c { fn trait_method2(self) -> Field { let _ = self; @@ -345,7 +387,9 @@ trait Trait3d { 3328 } } -struct Struct3d { vl: Field } +struct Struct3d { + vl: Field, +} impl Trait3d for Struct3d { fn trait_function1(a: Field, b: Self) -> Field { b.trait_method2() * 4933 - b.vl + a @@ -360,7 +404,9 @@ trait Trait3e { 373 } } -struct Struct3e { vl: Field } +struct Struct3e { + vl: Field, +} impl Trait3e for Struct3e { fn trait_function1(a: Field, b: Self) -> Field { b.trait_method2() * 81232 - b.vl + a @@ -377,7 +423,9 @@ trait Trait3f { } fn trait_method2(self) -> Field; } -struct Struct3f { vl: Field } +struct Struct3f { + vl: Field, +} impl Trait3f for Struct3f { fn trait_function1(a: Field, b: Self) -> Field { b.trait_method2() * 29223 - b.vl + a @@ -395,7 +443,9 @@ trait Trait3g { 8887 } } -struct Struct3g { vl: Field } +struct Struct3g { + vl: Field, +} impl Trait3g for Struct3g { fn trait_function1(a: Field, b: Self) -> Field { b.trait_method2() * 31337 - b.vl + a @@ -408,7 +458,9 @@ trait Trait3h { 293 } } -struct Struct3h { vl: Field } +struct Struct3h { + vl: Field, +} impl Trait3h for Struct3h { fn trait_function1(a: Field, b: Self) -> Field { b.trait_method2() * 74747 - b.vl + a @@ -423,7 +475,9 @@ trait Trait3i { fn trait_function1(a: Field, b: Self) -> Field; fn trait_method2(self) -> Field; } -struct Struct3i { vl: Field } +struct Struct3i { + vl: Field, +} impl Trait3i for Struct3i { fn trait_function1(a: Field, b: Self) -> Field { b.trait_method2() * 1237 - b.vl + a @@ -443,7 +497,9 @@ trait Trait4a { 2932 } } -pub struct Struct4a { vl: Field } +pub struct Struct4a { + vl: Field, +} impl Trait4a for Struct4a {} // 4b) trait default function -> trait overriden function trait Trait4b { @@ -454,7 +510,9 @@ trait Trait4b { 2932 } } -pub struct Struct4b { vl: Field } +pub struct Struct4b { + vl: Field, +} impl Trait4b for Struct4b { fn trait_function2() -> Field { 9353 @@ -467,7 +525,9 @@ trait Trait4c { } fn trait_function2() -> Field; } -pub struct Struct4c { vl: Field } +pub struct Struct4c { + vl: Field, +} impl Trait4c for Struct4c { fn trait_function2() -> Field { 2928 @@ -482,7 +542,9 @@ trait Trait4d { 9332 } } -pub struct Struct4d { vl: Field } +pub struct Struct4d { + vl: Field, +} impl Trait4d for Struct4d { fn trait_function1() -> Field { Self::trait_function2() * 8374 @@ -497,7 +559,9 @@ trait Trait4e { 28328 } } -pub struct Struct4e { vl: Field } +pub struct Struct4e { + vl: Field, +} impl Trait4e for Struct4e { fn trait_function1() -> Field { Self::trait_function2() * 12323 @@ -513,7 +577,9 @@ trait Trait4f { } fn trait_function2() -> Field; } -pub struct Struct4f { vl: Field } +pub struct Struct4f { + vl: Field, +} impl Trait4f for Struct4f { fn trait_function1() -> Field { Self::trait_function2() * 21392 @@ -529,7 +595,9 @@ trait Trait4g { 2932 } } -pub struct Struct4g { vl: Field } +pub struct Struct4g { + vl: Field, +} impl Trait4g for Struct4g { fn trait_function1() -> Field { Self::trait_function2() * 3345 @@ -542,7 +610,9 @@ trait Trait4h { 5756 } } -pub struct Struct4h { vl: Field } +pub struct Struct4h { + vl: Field, +} impl Trait4h for Struct4h { fn trait_function1() -> Field { Self::trait_function2() * 6478 @@ -556,7 +626,9 @@ trait Trait4i { fn trait_function1() -> Field; fn trait_function2() -> Field; } -pub struct Struct4i { vl: Field } +pub struct Struct4i { + vl: Field, +} impl Trait4i for Struct4i { fn trait_function1() -> Field { Self::trait_function2() * 8239 diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_generics/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_generics/src/main.nr index 77309ca4bee..08302ded68c 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_generics/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_generics/src/main.nr @@ -7,7 +7,11 @@ fn main() { assert_eq(15, sum_static(Data { a: 5, b: 10 })); } -fn foo(x: T, u: U) where T: MyInto, U: Eq { +fn foo(x: T, u: U) +where + T: MyInto, + U: Eq, +{ assert(x.into() == u); } @@ -15,7 +19,10 @@ trait MyInto { fn into(self) -> T; } -impl MyInto<[U; N]> for [T; N] where T: MyInto { +impl MyInto<[U; N]> for [T; N] +where + T: MyInto, +{ fn into(self) -> [U; N] { self.map(|x: T| x.into()) } @@ -44,13 +51,19 @@ impl Serializable<2> for Data { } } -fn sum(data: T) -> Field where T: Serializable { +fn sum(data: T) -> Field +where + T: Serializable, +{ let serialized = data.serialize(); serialized.fold(0, |acc, elem| acc + elem) } // Test static trait method syntax -fn sum_static(data: T) -> Field where T: Serializable { +fn sum_static(data: T) -> Field +where + T: Serializable, +{ let serialized = Serializable::serialize(data); serialized.fold(0, |acc, elem| acc + elem) } diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_impl_generics/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_impl_generics/src/main.nr index bae4d62f9e4..33a086912d6 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_impl_generics/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_impl_generics/src/main.nr @@ -23,7 +23,7 @@ fn main() { assert(x.foo() == 32); assert(y.foo() == 64); - // Types matching multiple impls will currently choose + // Types matching multiple impls will currently choose // the first matching one instead of erroring assert(z.foo() == 32); @@ -44,7 +44,9 @@ trait T2 { fn t2(self) -> Self; } -struct S2 { x: T } +struct S2 { + x: T, +} impl T2 for S2 { fn t2(self) -> Self { diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_impl_with_where_clause/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_impl_with_where_clause/src/main.nr index 6da2c86fa2f..6fa194f2520 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_impl_with_where_clause/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_impl_with_where_clause/src/main.nr @@ -10,7 +10,10 @@ trait MyEq { fn my_eq(self, other: Self) -> bool; } -impl MyEq for [T; 3] where T: MyEq { +impl MyEq for [T; 3] +where + T: MyEq, +{ fn my_eq(self, other: Self) -> bool { let mut ret = true; for i in 0..self.len() { diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr index 9cc8375b140..aa0baab7f89 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_method_mut_self/src/main.nr @@ -17,7 +17,7 @@ fn main(x: Field, y: pub Field) { hasher.write(x); hasher.write(y); let expected_hash = hasher.finish(); - // Check that we get the same result when using the hasher in a + // Check that we get the same result when using the hasher in a // method that purely uses trait methods without a supplied implementation. assert(hash_simple_array::([x, y]) == expected_hash); } @@ -29,7 +29,7 @@ trait SomeTrait { } struct AType { - x: Field + x: Field, } impl SomeTrait for AType { @@ -48,18 +48,27 @@ fn pass_trait_by_value_impl_param(mut a_mut_ref: impl SomeTrait, value: Field) { assert(a_mut_ref.get_value() == value); } -fn pass_trait_by_value(mut a_mut_ref: T, value: Field) where T: SomeTrait { +fn pass_trait_by_value(mut a_mut_ref: T, value: Field) +where + T: SomeTrait, +{ // We auto add a mutable reference to the object type if the method call expects a mutable self a_mut_ref.set_value(value); assert(a_mut_ref.get_value() == value); } -fn pass_trait_by_mut_ref(a_mut_ref: &mut T, value: Field) where T: SomeTrait { +fn pass_trait_by_mut_ref(a_mut_ref: &mut T, value: Field) +where + T: SomeTrait, +{ // We auto add a mutable reference to the object type if the method call expects a mutable self a_mut_ref.set_value(value); } -fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { +fn hash_simple_array(input: [Field; 2]) -> Field +where + H: Hasher + Default, +{ // Check that we can call a trait method instead of a trait implementation // TODO: Need to remove the need for this type annotation // TODO: Curently, without the annotation we will get `Expression type is ambiguous` when trying to use the `hasher` diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module1.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module1.nr index b5c05d69378..8eaeafa5207 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module1.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module1.nr @@ -1,2 +1 @@ -pub trait MyTrait { -} +pub trait MyTrait {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module2.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module2.nr index c1335fe95e4..3db88f40ef7 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module2.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module2.nr @@ -1,2 +1 @@ -pub struct MyStruct { -} +pub struct MyStruct {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module4.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module4.nr index f1e3c407531..487cc404726 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module4.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module4.nr @@ -1,2 +1 @@ -pub trait MyTrait4 { -} +pub trait MyTrait4 {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module5.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module5.nr index 8c1c41ea25e..9c58cf799db 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module5.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_multi_module_test/src/module5.nr @@ -1,2 +1 @@ -pub struct MyStruct5 { -} +pub struct MyStruct5 {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_override_implementation/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_override_implementation/src/main.nr index 68a928c0c52..12a625b0843 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_override_implementation/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_override_implementation/src/main.nr @@ -23,10 +23,18 @@ impl MyDefault for Foo { trait F { fn f1(self) -> Field; - fn f2(_self: Self) -> Field { 2 } - fn f3(_self: Self) -> Field { 3 } - fn f4(_self: Self) -> Field { 4 } - fn f5(_self: Self) -> Field { 5 } + fn f2(_self: Self) -> Field { + 2 + } + fn f3(_self: Self) -> Field { + 3 + } + fn f4(_self: Self) -> Field { + 4 + } + fn f5(_self: Self) -> Field { + 5 + } } struct Bar {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_static_methods/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_static_methods/src/main.nr index 976d0ab762c..571f917ab89 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_static_methods/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_static_methods/src/main.nr @@ -11,7 +11,7 @@ trait ATrait { } struct Foo { - x: Field + x: Field, } impl ATrait for Foo { fn asd() -> Self { @@ -21,7 +21,7 @@ impl ATrait for Foo { } struct Bar { - x: Field + x: Field, } impl ATrait for Bar { // The trait method is declared as returning `Self` diff --git a/noir/noir-repo/test_programs/compile_success_empty/trait_where_clause/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/trait_where_clause/src/main.nr index 86e7f70a3a3..8dc00be622d 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/trait_where_clause/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/trait_where_clause/src/main.nr @@ -7,10 +7,19 @@ mod the_trait; use crate::the_trait::Asd; use crate::the_trait::StaticTrait; -struct Add10 { x: Field, } -struct Add20 { x: Field, } -struct Add30 { x: Field, } -struct AddXY { x: Field, y: Field, } +struct Add10 { + x: Field, +} +struct Add20 { + x: Field, +} +struct Add30 { + x: Field, +} +struct AddXY { + x: Field, + y: Field, +} impl Asd for Add10 { fn asd(self) -> Field { @@ -47,18 +56,24 @@ impl StaticTrait for Static200 { } } -fn assert_asd_eq_100(t: T) where T: crate::the_trait::Asd { +fn assert_asd_eq_100(t: T) +where + T: crate::the_trait::Asd, +{ assert(t.asd() == 100); } -fn add_one_to_static_function(t: T) -> Field where T: StaticTrait { +fn add_one_to_static_function(t: T) -> Field +where + T: StaticTrait, +{ T::static_function(t) + 1 } fn main() { - let x = Add10 { x: 90 }; - let z = Add20 { x: 80 }; - let a = Add30 { x: 70 }; + let x = Add10 { x: 90 }; + let z = Add20 { x: 80 }; + let a = Add30 { x: 70 }; let xy = AddXY { x: 30, y: 70 }; assert_asd_eq_100(x); diff --git a/noir/noir-repo/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr index 36c7d2926c1..535d7b18137 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/turbofish_call_func_diff_types/src/main.nr @@ -7,7 +7,7 @@ fn main(x: Field, y: pub Field) { hasher.write(x); hasher.write(y); let poseidon_expected_hash = hasher.finish(); - // Check that we get the same result when using the hasher in a + // Check that we get the same result when using the hasher in a // method that purely uses trait methods without a supplied implementation. assert(hash_simple_array::([x, y]) == poseidon_expected_hash); @@ -21,7 +21,10 @@ fn main(x: Field, y: pub Field) { assert(hash_simple_array::([x, y]) == poseidon2_expected_hash); } -fn hash_simple_array(input: [Field; 2]) -> Field where H: Hasher + Default { +fn hash_simple_array(input: [Field; 2]) -> Field +where + H: Hasher + Default, +{ // Check that we can call a trait method instead of a trait implementation let mut hasher = H::default(); // Regression that the object is converted to a mutable reference type `&mut _`. diff --git a/noir/noir-repo/test_programs/compile_success_empty/type_path/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/type_path/src/main.nr index 968812801c6..92f04104868 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/type_path/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/type_path/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { let foo = quote { Foo }.as_type(); quote { $foo::static() diff --git a/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/src/main.nr index 603440b5c76..d4ab275858c 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/src/main.nr @@ -10,18 +10,18 @@ fn foo(x: Field, y: u32) -> u32 { // Given a function, wrap its parameters in a struct definition comptime fn output_struct(f: FunctionDefinition) -> Quoted { - let fields = f.parameters().map( - |param: (Quoted, Type)| { - let name = param.0; - let typ = param.1; - quote { $name: $typ, } - } - ).join(quote {}); + let fields = f + .parameters() + .map(|param: (Quoted, Type)| { + let name = param.0; + let typ = param.1; + quote { $name: $typ, } + }) + .join(quote {}); quote { struct Foo { $fields } - - impl Foo { + impl Foo { fn assert_equal(self) { assert_eq(self.x as u32, self.y); } diff --git a/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr index 30db6c48f7c..bc93bc5187e 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/use_callers_scope/src/main.nr @@ -19,11 +19,7 @@ mod bar { // Ensure closures can still access Bar even // though `map` separates them from `fn_attr`. - let _ = &[1, 2, 3].map( - |_| { - quote { Bar }.as_type() - } - ); + let _ = &[1, 2, 3].map(|_| { quote { Bar }.as_type() }); } // use_callers_scope should also work nested diff --git a/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/Nargo.toml b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/Nargo.toml new file mode 100644 index 00000000000..c4efe5b4bb4 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "invalid_comptime_bits_decomposition" +type = "bin" +authors = [""] +compiler_version = ">=0.30.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/src/main.nr b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/src/main.nr new file mode 100644 index 00000000000..a9ac06c42c6 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bits_decomposition/src/main.nr @@ -0,0 +1,5 @@ +fn main() -> pub [u1; 1] { + let large_number: Field = 2; + + large_number.to_be_bits() +} diff --git a/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/Nargo.toml b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/Nargo.toml new file mode 100644 index 00000000000..7ec63576af3 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "invalid_comptime_bytes_decomposition" +type = "bin" +authors = [""] +compiler_version = ">=0.30.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/src/main.nr b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/src/main.nr new file mode 100644 index 00000000000..29be8508575 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_failure/invalid_comptime_bytes_decomposition/src/main.nr @@ -0,0 +1,4 @@ +fn main() -> pub [u8; 1] { + let large_number: Field = 256; + large_number.to_be_bytes() +} diff --git a/noir/noir-repo/test_programs/execution_success/1327_concrete_in_generic/src/main.nr b/noir/noir-repo/test_programs/execution_success/1327_concrete_in_generic/src/main.nr index 3e476107c29..1d37eca57a2 100644 --- a/noir/noir-repo/test_programs/execution_success/1327_concrete_in_generic/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/1327_concrete_in_generic/src/main.nr @@ -6,8 +6,8 @@ fn new_concrete_c_over_d() -> C { // --- // Map struct B { - new_concrete_t_c_constructor: fn()->T_C, - } + new_concrete_t_c_constructor: fn() -> T_C, +} impl B { fn new(new_concrete_t_c_constructor: fn() -> T_C) -> B { @@ -22,8 +22,8 @@ impl B { // --- // PrivateSet struct C { - t_d_interface: MethodInterface, - } + t_d_interface: MethodInterface, +} impl C { fn new(t_d_interface: MethodInterface) -> Self { @@ -37,13 +37,13 @@ impl C { } // --- struct MethodInterface { - some_method_on_t_d: fn(T_D)->Field, - } + some_method_on_t_d: fn(T_D) -> Field, +} // --- // Note struct D { - d: Field, - } + d: Field, +} fn d_method(input: D) -> Field { input.d * input.d diff --git a/noir/noir-repo/test_programs/execution_success/4_sub/src/main.nr b/noir/noir-repo/test_programs/execution_success/4_sub/src/main.nr index 2b4fc395705..4170c2cbaf2 100644 --- a/noir/noir-repo/test_programs/execution_success/4_sub/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/4_sub/src/main.nr @@ -1,5 +1,5 @@ // Test unsafe integer subtraction with underflow: 12 - 2418266113 = 1876701195 modulo 2^32 fn main(mut x: u32, y: u32, z: u32) { - x = std::wrapping_sub(x,y); + x = std::wrapping_sub(x, y); assert(x == z); } diff --git a/noir/noir-repo/test_programs/execution_success/5_over/src/main.nr b/noir/noir-repo/test_programs/execution_success/5_over/src/main.nr index 6c4153e4b49..ad0a60d0a7f 100644 --- a/noir/noir-repo/test_programs/execution_success/5_over/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/5_over/src/main.nr @@ -1,7 +1,7 @@ // Test unsafe integer arithmetic // Test odd bits integer fn main(mut x: u32, y: u32) { - x = std::wrapping_mul(x,x); + x = std::wrapping_mul(x, x); assert(y == x); let c: u1 = 0; diff --git a/noir/noir-repo/test_programs/execution_success/6/src/main.nr b/noir/noir-repo/test_programs/execution_success/6/src/main.nr index 8657199bd7f..8ddbbd546d2 100644 --- a/noir/noir-repo/test_programs/execution_success/6/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/6/src/main.nr @@ -5,7 +5,6 @@ // If you do not cast, it will take all the bytes from the field element! // Mimc input is an array of field elements // The function is called mimc_bn254 to emphasize its parameters are chosen for bn254 curve, it should be used only with a proving system using the same curve (e.g Plonk from Aztec) - fn main(x: [u8; 5], result: pub [u8; 32]) { let mut digest = std::hash::sha256(x); digest[0] = 5 as u8; diff --git a/noir/noir-repo/test_programs/execution_success/6_array/src/main.nr b/noir/noir-repo/test_programs/execution_success/6_array/src/main.nr index d7180c260ff..37f6e447487 100644 --- a/noir/noir-repo/test_programs/execution_success/6_array/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/6_array/src/main.nr @@ -2,28 +2,28 @@ fn main(x: [u32; 5], y: [u32; 5], mut z: u32, t: u32) { let mut c = 2301; z = y[4]; - //Test 1: + //Test 1: for i in 0..5 { - c = z*z*y[i]; + c = z * z * y[i]; z -= c; } assert(z == 0); //y[4]=0, so c and z are always 0 //Test 2: c = 2301 as u32; for i in 0..5 { - c = t+2 as u32; - c = std::wrapping_mul(std::wrapping_mul(z,z),x[i]); - z =std::wrapping_add(z, std::wrapping_sub(x[i]*y[i] , c)); + c = t + 2 as u32; + c = std::wrapping_mul(std::wrapping_mul(z, z), x[i]); + z = std::wrapping_add(z, std::wrapping_sub(x[i] * y[i], c)); } assert(z == 3814912846); //Test 3: c = 2300001 as u32; z = y[4]; for i in 0..5 { - z = z + x[i]*y[i]; + z = z + x[i] * y[i]; for _i in 0..3 { - c = std::wrapping_sub(i as u32,2 as u32); - z = std::wrapping_mul(z,c); + c = std::wrapping_sub(i as u32, 2 as u32); + z = std::wrapping_mul(z, c); } } assert(z == 41472); @@ -32,7 +32,7 @@ fn main(x: [u32; 5], y: [u32; 5], mut z: u32, t: u32) { for i in 0..3 { z += x[i] * y[i]; for j in 0..2 { - z += x[i+j] - y[i+j]; + z += x[i + j] - y[i + j]; } } assert(z == 11539); diff --git a/noir/noir-repo/test_programs/execution_success/7/src/main.nr b/noir/noir-repo/test_programs/execution_success/7/src/main.nr index ad3fe1aadc8..32880aa8e41 100644 --- a/noir/noir-repo/test_programs/execution_success/7/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/7/src/main.nr @@ -2,7 +2,6 @@ // // Pre-alpha dependencies must now be prefixed with the word "dep". // The line below indicates that we would like to pull in the standard library dependency. - fn main(x: [u8; 5], result: [u8; 32]) { let digest = std::hash::blake2s(x); assert(digest == result); diff --git a/noir/noir-repo/test_programs/execution_success/7_function/src/main.nr b/noir/noir-repo/test_programs/execution_success/7_function/src/main.nr index 32227b841bd..ad065a5cae5 100644 --- a/noir/noir-repo/test_programs/execution_success/7_function/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/7_function/src/main.nr @@ -31,8 +31,8 @@ fn pow(base: Field, exponent: Field) -> Field { let mut r = 1 as Field; let b: [u1; 32] = exponent.to_le_bits(); for i in 1..33 { - r = r*r; - r = (b[32-i] as Field) * (r * base) + (1 - b[32-i] as Field) * r; + r = r * r; + r = (b[32 - i] as Field) * (r * base) + (1 - b[32 - i] as Field) * r; } r } diff --git a/noir/noir-repo/test_programs/execution_success/aes128_encrypt/src/main.nr b/noir/noir-repo/test_programs/execution_success/aes128_encrypt/src/main.nr index 31d907fea10..3d3992971f7 100644 --- a/noir/noir-repo/test_programs/execution_success/aes128_encrypt/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/aes128_encrypt/src/main.nr @@ -15,7 +15,7 @@ unconstrained fn decode_hex(s: str) -> [u8; M] { if i % 2 != 0 { continue; } - result[i/2] = decode_ascii(as_bytes[i]) * 16 + decode_ascii(as_bytes[i + 1]); + result[i / 2] = decode_ascii(as_bytes[i]) * 16 + decode_ascii(as_bytes[i + 1]); } result } @@ -26,15 +26,12 @@ unconstrained fn cipher(plaintext: [u8; 12], iv: [u8; 16], key: [u8; 16]) -> [u8 } fn main(inputs: str<12>, iv: str<16>, key: str<16>, output: str<32>) { - let result: [u8; 16] = std::aes128::aes128_encrypt(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()).as_array(); + let result: [u8; 16] = + std::aes128::aes128_encrypt(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()).as_array(); - let output_bytes: [u8; 16] = unsafe { - decode_hex(output) - }; + let output_bytes: [u8; 16] = unsafe { decode_hex(output) }; assert(result == output_bytes); - let unconstrained_result = unsafe { - cipher(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()) - }; + let unconstrained_result = unsafe { cipher(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()) }; assert(unconstrained_result == output_bytes); } diff --git a/noir/noir-repo/test_programs/execution_success/arithmetic_binary_operations/src/main.nr b/noir/noir-repo/test_programs/execution_success/arithmetic_binary_operations/src/main.nr index 69554f413a4..3a6b0149ec1 100644 --- a/noir/noir-repo/test_programs/execution_success/arithmetic_binary_operations/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/arithmetic_binary_operations/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested are: // Binary addition, multiplication, division, constant modulo // x = 3, y = 4, z = 5 diff --git a/noir/noir-repo/test_programs/execution_success/array_dynamic/src/main.nr b/noir/noir-repo/test_programs/execution_success/array_dynamic/src/main.nr index 6b51095bd8c..fc29c4364c9 100644 --- a/noir/noir-repo/test_programs/execution_success/array_dynamic/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/array_dynamic/src/main.nr @@ -5,7 +5,7 @@ fn main( index: [Field; 5], index2: [Field; 5], offset: Field, - sublen: Field + sublen: Field, ) { let idx = (z - 5 * t - 5) as Field; //dynamic array test diff --git a/noir/noir-repo/test_programs/execution_success/array_to_slice_constant_length/src/main.nr b/noir/noir-repo/test_programs/execution_success/array_to_slice_constant_length/src/main.nr index 5668a9ff388..09f99622939 100644 --- a/noir/noir-repo/test_programs/execution_success/array_to_slice_constant_length/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/array_to_slice_constant_length/src/main.nr @@ -1,5 +1,4 @@ // Regression test for https://github.com/noir-lang/noir/issues/4722 - unconstrained fn return_array(val: Field) -> [Field; 1] { [val; 1] } diff --git a/noir/noir-repo/test_programs/execution_success/assert_statement/src/main.nr b/noir/noir-repo/test_programs/execution_success/assert_statement/src/main.nr index 2646a0b85c2..c076f047dd8 100644 --- a/noir/noir-repo/test_programs/execution_success/assert_statement/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/assert_statement/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is assertion fn main(x: Field, y: pub Field) { assert(x == y, "x and y are not equal"); diff --git a/noir/noir-repo/test_programs/execution_success/assert_statement_recursive/src/main.nr b/noir/noir-repo/test_programs/execution_success/assert_statement_recursive/src/main.nr index d89ea3d35bb..7f28fe3821d 100644 --- a/noir/noir-repo/test_programs/execution_success/assert_statement_recursive/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/assert_statement_recursive/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is assertion // This is the same as the `assert_statement` test except we specify // that the backend should use a prover which will construct proofs diff --git a/noir/noir-repo/test_programs/execution_success/bench_ecdsa_secp256k1/src/main.nr b/noir/noir-repo/test_programs/execution_success/bench_ecdsa_secp256k1/src/main.nr index 60f182c7836..18d57d7886c 100644 --- a/noir/noir-repo/test_programs/execution_success/bench_ecdsa_secp256k1/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/bench_ecdsa_secp256k1/src/main.nr @@ -1,6 +1,7 @@ use dep::std; fn main(hashed_message: [u8; 32], pub_key_x: [u8; 32], pub_key_y: [u8; 32], signature: [u8; 64]) { - let valid_signature = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + let valid_signature = + std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); assert(valid_signature); } diff --git a/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr b/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr index 8592e6fb230..5a8b9fb67ef 100644 --- a/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/bigint/src/main.nr @@ -7,8 +7,8 @@ fn main(mut x: [u8; 5], y: [u8; 5]) { let mut a_be_bytes = [0; 32]; let mut b_be_bytes = [0; 32]; for i in 0..5 { - a_be_bytes[31-i] = x[i]; - b_be_bytes[31-i] = y[i]; + a_be_bytes[31 - i] = x[i]; + b_be_bytes[31 - i] = y[i]; } let a_field = std::field::bytes32_to_field(a_be_bytes); let b_field = std::field::bytes32_to_field(b_be_bytes); @@ -44,15 +44,17 @@ fn main(mut x: [u8; 5], y: [u8; 5]) { big_int_example(x[0], x[1]); // Regression for issue #4882 - let num_b:[u8;32] = [ - 0, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48 + let num_b: [u8; 32] = [ + 0, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, + 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48, ]; - let num2_b:[u8;7] = [126, 193, 45, 39, 188, 84, 11]; + let num2_b: [u8; 7] = [126, 193, 45, 39, 188, 84, 11]; let num = bigint::Bn254Fr::from_le_bytes(num_b.as_slice()); let num2 = bigint::Bn254Fr::from_le_bytes(num2_b.as_slice()); - let ret_b:[u8;32] = [ - 131, 62, 210, 200, 215, 160, 214, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48 + let ret_b: [u8; 32] = [ + 131, 62, 210, 200, 215, 160, 214, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, + 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48, ]; let ret = bigint::Bn254Fr::from_le_bytes(ret_b.as_slice()); assert(ret == num.mul(num2)); diff --git a/noir/noir-repo/test_programs/execution_success/binary_operator_overloading/src/main.nr b/noir/noir-repo/test_programs/execution_success/binary_operator_overloading/src/main.nr index c2c831d0c1e..a5e12fd5da9 100644 --- a/noir/noir-repo/test_programs/execution_success/binary_operator_overloading/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/binary_operator_overloading/src/main.nr @@ -30,7 +30,7 @@ fn main(x: u32, y: u32) { assert((wx >= wy) == (ex >= ey)); assert(wx.cmp(wy) == ex.cmp(ey)); - // Ensure operator overloading still works with more complex types + // Ensure operator overloading still works with more complex types let pair_ascending = Pair { x: wx, y: wy }; let pair_descending = Pair { x: wy, y: wx }; @@ -45,7 +45,7 @@ fn main(x: u32, y: u32) { } struct Wrapper { - inner: u32 + inner: u32, } impl Wrapper { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_arrays/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_arrays/src/main.nr index c7f0757f31e..00d43e2b10d 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_arrays/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_arrays/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested are array reads and writes fn main(x: [Field; 3]) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_assert/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_assert/src/main.nr index c6c39b61bc9..dc0138d3f05 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_assert/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_assert/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is using assert on brillig fn main(x: Field) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_blake2s/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_blake2s/src/main.nr index 122142a9c80..c4412bd2bba 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_blake2s/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_blake2s/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is blake2s in brillig fn main(x: [u8; 5], result: [u8; 32]) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr index 6ddfc03622a..7f04dcd4d04 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_block_parameter_liveness/src/main.nr @@ -1,5 +1,4 @@ // Tests that we run liveness in block parameters by trying to create too many block parameters to fit in the stack - // Uses up 10 stack items struct Inner { a: u64, diff --git a/noir/noir-repo/test_programs/execution_success/brillig_calls/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_calls/src/main.nr index 3e23da53b18..c76d7651b0a 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_calls/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_calls/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is brillig calls fn main(x: u32) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_calls_array/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_calls_array/src/main.nr index 8b27a9bb202..90f588ab988 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_calls_array/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_calls_array/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is brillig calls passing arrays around fn main(x: [u32; 3]) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_calls_conditionals/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_calls_conditionals/src/main.nr index 318da4caf72..0fbfd84968f 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_calls_conditionals/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_calls_conditionals/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is brillig calls with conditionals fn main(x: [u32; 3]) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_conditional/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_conditional/src/main.nr index 8ababf82319..17484f6e8c5 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_conditional/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_conditional/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is basic conditonal on brillig fn main(x: Field) { unsafe { @@ -8,5 +8,9 @@ fn main(x: Field) { } unconstrained fn conditional(x: bool) -> Field { - if x { 4 } else { 5 } + if x { + 4 + } else { + 5 + } } diff --git a/noir/noir-repo/test_programs/execution_success/brillig_constant_reference_regression/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_constant_reference_regression/src/main.nr index c975d20a3b6..67bde87c712 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_constant_reference_regression/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_constant_reference_regression/src/main.nr @@ -1,11 +1,7 @@ unconstrained fn main(sorted_index: [u32; 2]) { - let original = [ - 55, - 11 - ]; + let original = [55, 11]; let mut sorted = original; // Stores the constant "original" into the sorted reference - for i in 0..2 { let index = sorted_index[i]; let value = original[index]; diff --git a/noir/noir-repo/test_programs/execution_success/brillig_cow/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_cow/src/main.nr index 52ce8b8be3c..1d4c7f3172e 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_cow/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_cow/src/main.nr @@ -1,5 +1,4 @@ // Tests the copy on write optimization for arrays. We look for cases where we are modifying an array in place when we shouldn't. - global ARRAY_SIZE = 5; struct ExecutionResult { @@ -23,14 +22,14 @@ fn modify_in_inlined_constrained(original: [Field; ARRAY_SIZE], index: u64) -> E let modified_once = modified; - modified[index+1] = 27; + modified[index + 1] = 27; ExecutionResult { original, modified_once, modified_twice: modified } } unconstrained fn modify_in_unconstrained( original: [Field; ARRAY_SIZE], - index: u64 + index: u64, ) -> ExecutionResult { let mut modified = original; @@ -38,7 +37,7 @@ unconstrained fn modify_in_unconstrained( let modified_once = modified; - modified[index+1] = 27; + modified[index + 1] = 27; ExecutionResult { original, modified_once, modified_twice: modified } } diff --git a/noir/noir-repo/test_programs/execution_success/brillig_cow_assign/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_cow_assign/src/main.nr index e5c3e2bd2f5..73b91e24bea 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_cow_assign/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_cow_assign/src/main.nr @@ -14,7 +14,6 @@ unconstrained fn main() { // Expect: // arr = [27, 27, 27, 27, 27, 27, 27, 27, 27, 27] // mid_change = [27, 27, 27, 27, 27, 0, 0, 0, 0, 0] - let modified_i = N / 2 + 1; assert_eq(arr[modified_i], 27); diff --git a/noir/noir-repo/test_programs/execution_success/brillig_cow_regression/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_cow_regression/src/main.nr index 3fce7fb2c7d..ad2a291f87d 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_cow_regression/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_cow_regression/src/main.nr @@ -1,5 +1,4 @@ // Tests a performance regression found in aztec-packages with brillig cow optimization - global MAX_NOTE_HASHES_PER_TX: u32 = 64; global MAX_NULLIFIERS_PER_TX: u32 = 64; global MAX_L2_TO_L1_MSGS_PER_TX: u32 = 2; @@ -13,9 +12,9 @@ global TX_EFFECT_HASH_LOG_FIELDS: u32 = 4; global TX_EFFECT_HASH_FULL_FIELDS: u32 = 165; struct PublicDataUpdateRequest { - leaf_slot : Field, - old_value : Field, - new_value : Field + leaf_slot: Field, + old_value: Field, + new_value: Field, } struct NewContractData { @@ -43,7 +42,7 @@ struct U256 { // This is in big-endian order, typically because // sha256 is usually in big endian order. // Note: this means that inner[0] has the most significant 64 bits. - inner : [u64; 4] + inner: [u64; 4], } impl U256 { @@ -92,7 +91,7 @@ impl U256 { let two_pow_64 = 2.pow_32(64); let high = (self.inner[0] as Field) * two_pow_64 + self.inner[1] as Field; - let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field; + let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field; [high, low] } @@ -113,18 +112,16 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA for j in 0..MAX_NOTE_HASHES_PER_TX { tx_effects_hash_inputs[offset + j] = new_note_hashes[j]; } - offset += MAX_NOTE_HASHES_PER_TX ; + offset += MAX_NOTE_HASHES_PER_TX; for j in 0..MAX_NULLIFIERS_PER_TX { tx_effects_hash_inputs[offset + j] = new_nullifiers[j]; } - offset += MAX_NULLIFIERS_PER_TX ; + offset += MAX_NULLIFIERS_PER_TX; for j in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { - tx_effects_hash_inputs[offset + j * 2] = - public_data_update_requests[j].leaf_slot; - tx_effects_hash_inputs[offset + j * 2 + 1] = - public_data_update_requests[j].new_value; + tx_effects_hash_inputs[offset + j * 2] = public_data_update_requests[j].leaf_slot; + tx_effects_hash_inputs[offset + j * 2 + 1] = public_data_update_requests[j].new_value; } offset += MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2; @@ -157,8 +154,8 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA offset += NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256; assert_eq(offset, TX_EFFECT_HASH_INPUT_SIZE); // Sanity check - - let mut hash_input_flattened = [0; TX_EFFECT_HASH_FULL_FIELDS * 32 + TX_EFFECT_HASH_LOG_FIELDS * 16]; + let mut hash_input_flattened = + [0; TX_EFFECT_HASH_FULL_FIELDS * 32 + TX_EFFECT_HASH_LOG_FIELDS * 16]; for offset in 0..TX_EFFECT_HASH_FULL_FIELDS { let input_as_bytes: [u8; 32] = tx_effects_hash_inputs[offset].to_be_bytes(); for byte_index in 0..32 { @@ -167,9 +164,11 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA } for log_field_index in 0..TX_EFFECT_HASH_LOG_FIELDS { - let input_as_bytes: [u8; 16] = tx_effects_hash_inputs[TX_EFFECT_HASH_FULL_FIELDS + log_field_index].to_be_bytes(); + let input_as_bytes: [u8; 16] = + tx_effects_hash_inputs[TX_EFFECT_HASH_FULL_FIELDS + log_field_index].to_be_bytes(); for byte_index in 0..16 { - hash_input_flattened[TX_EFFECT_HASH_FULL_FIELDS * 32 + log_field_index * 16 + byte_index] = input_as_bytes[byte_index]; + hash_input_flattened[TX_EFFECT_HASH_FULL_FIELDS * 32 + log_field_index * 16 + byte_index] = + input_as_bytes[byte_index]; } } diff --git a/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256k1/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256k1/src/main.nr index 45f13c79637..6bde8ac4ac7 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256k1/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256k1/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is ecdsa in brillig fn main(hashed_message: [u8; 32], pub_key_x: [u8; 32], pub_key_y: [u8; 32], signature: [u8; 64]) { unsafe { @@ -11,7 +11,7 @@ unconstrained fn ecdsa( hashed_message: [u8; 32], pub_key_x: [u8; 32], pub_key_y: [u8; 32], - signature: [u8; 64] + signature: [u8; 64], ) -> bool { std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message) } diff --git a/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256r1/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256r1/src/main.nr index 32b562ec50c..091905a3d01 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256r1/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_ecdsa_secp256r1/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is ecdsa in brillig fn main(hashed_message: [u8; 32], pub_key_x: [u8; 32], pub_key_y: [u8; 32], signature: [u8; 64]) { unsafe { @@ -11,7 +11,7 @@ unconstrained fn ecdsa( hashed_message: [u8; 32], pub_key_x: [u8; 32], pub_key_y: [u8; 32], - signature: [u8; 64] + signature: [u8; 64], ) -> bool { std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message) } diff --git a/noir/noir-repo/test_programs/execution_success/brillig_fns_as_values/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_fns_as_values/src/main.nr index 55b9d307905..03a92b4b10d 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_fns_as_values/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_fns_as_values/src/main.nr @@ -1,5 +1,5 @@ struct MyStruct { - operation: unconstrained fn (u32) -> u32, + operation: unconstrained fn(u32) -> u32, } fn main(x: u32) { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_hash_to_field/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_hash_to_field/src/main.nr index d1ea635d49a..48c628020b6 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_hash_to_field/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_hash_to_field/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is hash_to_field in brillig fn main(input: Field) -> pub Field { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_identity_function/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_identity_function/src/main.nr index c2759fe054f..f3b45d0de4e 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_identity_function/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_identity_function/src/main.nr @@ -3,7 +3,7 @@ struct myStruct { foo_arr: [Field; 2], } // Tests a very simple program. -// +// // The features being tested is the identity function in Brillig fn main(x: Field) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_keccak/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_keccak/src/main.nr index 9674ed92942..e5c8e5f493e 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_keccak/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_keccak/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is keccak256 in brillig fn main(x: Field, result: [u8; 32]) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_loop/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_loop/src/main.nr index 9de8c66b051..2d073afb482 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_loop/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_loop/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is basic looping on brillig fn main(sum: u32) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_loop_size_regression/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_loop_size_regression/src/main.nr index 488304114b9..88c6544dcaa 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_loop_size_regression/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_loop_size_regression/src/main.nr @@ -5,7 +5,8 @@ struct EnumEmulation { } unconstrained fn main() -> pub Field { - let mut emulated_enum = EnumEmulation { a: Option::some(1), b: Option::none(), c: Option::none() }; + let mut emulated_enum = + EnumEmulation { a: Option::some(1), b: Option::none(), c: Option::none() }; for _ in 0..1 { assert_eq(emulated_enum.a.unwrap(), 1); diff --git a/noir/noir-repo/test_programs/execution_success/brillig_not/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_not/src/main.nr index 557d1e2e31f..4e61b6a54ea 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_not/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_not/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple Brillig function. -// +// // The features being tested is not instruction on brillig fn main(x: Field, y: Field) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_oracle/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_oracle/src/main.nr index 93465b87389..8f5b2fa7566 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_oracle/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_oracle/src/main.nr @@ -15,8 +15,12 @@ fn main(_x: Field) { } // TODO: this method of returning a slice feels hacky. - let _ = OracleMock::mock("get_number_sequence").with_params(size).returns((20, mock_oracle_response)); - let _ = OracleMock::mock("get_reverse_number_sequence").with_params(size).returns((20, reversed_mock_oracle_response)); + let _ = OracleMock::mock("get_number_sequence").with_params(size).returns(( + 20, mock_oracle_response, + )); + let _ = OracleMock::mock("get_reverse_number_sequence").with_params(size).returns(( + 20, reversed_mock_oracle_response, + )); get_number_sequence_wrapper(size as Field); } diff --git a/noir/noir-repo/test_programs/execution_success/brillig_pedersen/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_pedersen/src/main.nr index 17c79f9d0ae..55f81882bd4 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_pedersen/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_pedersen/src/main.nr @@ -1,4 +1,11 @@ -unconstrained fn main(x: Field, y: Field, salt: Field, out_x: Field, out_y: Field, out_hash: Field) { +unconstrained fn main( + x: Field, + y: Field, + salt: Field, + out_x: Field, + out_y: Field, + out_hash: Field, +) { let res = std::hash::pedersen_commitment_with_separator([x, y], 0); assert(res.x == out_x); assert(res.y == out_y); diff --git a/noir/noir-repo/test_programs/execution_success/brillig_recursion/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_recursion/src/main.nr index c69468013b1..5354777a1de 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_recursion/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_recursion/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The feature being tested is brillig recursion fn main(x: u32) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_references/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_references/src/main.nr index e1f906beb0a..47f263cf557 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_references/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_references/src/main.nr @@ -25,9 +25,13 @@ unconstrained fn add1(x: &mut Field) { *x += 1; } -struct S { y: Field } +struct S { + y: Field, +} -struct Nested { y: &mut &mut Field } +struct Nested { + y: &mut &mut Field, +} struct C { foo: Field, @@ -35,7 +39,7 @@ struct C { } struct C2 { - array: &mut [Field; 2] + array: &mut [Field; 2], } impl S { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_sha256/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_sha256/src/main.nr index 5519fb2da64..e574676965d 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_sha256/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_sha256/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is sha256 in brillig fn main(x: Field, result: [u8; 32]) { unsafe { diff --git a/noir/noir-repo/test_programs/execution_success/brillig_slices/src/main.nr b/noir/noir-repo/test_programs/execution_success/brillig_slices/src/main.nr index 89f838a3a57..f3928cbc026 100644 --- a/noir/noir-repo/test_programs/execution_success/brillig_slices/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/brillig_slices/src/main.nr @@ -110,7 +110,11 @@ unconstrained fn merge_slices_else(x: Field) { unconstrained fn merge_slices_return(x: Field, y: Field) -> [Field] { let slice = &[0; 2]; if x != y { - if x != 20 { slice.push_back(y) } else { slice } + if x != 20 { + slice.push_back(y) + } else { + slice + } } else { slice } diff --git a/noir/noir-repo/test_programs/execution_success/check_large_field_bits/src/main.nr b/noir/noir-repo/test_programs/execution_success/check_large_field_bits/src/main.nr index 542a06ecb6f..8022ea138ed 100644 --- a/noir/noir-repo/test_programs/execution_success/check_large_field_bits/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/check_large_field_bits/src/main.nr @@ -26,20 +26,26 @@ fn main() { C.assert_max_bit_size::<34>(); assert( - C.to_be_bits() == [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 - ] + C.to_be_bits() + == [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + ], ); // leading big-endian bits past 34 are 0's assert( - C.to_be_bits() == [ - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 - ] + C.to_be_bits() + == [ + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, + ], ); assert( - C.to_be_bits() == [ - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 - ] + C.to_be_bits() + == [ + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + ], ); } diff --git a/noir/noir-repo/test_programs/execution_success/closures_mut_ref/src/main.nr b/noir/noir-repo/test_programs/execution_success/closures_mut_ref/src/main.nr index 5a743d1b633..bff2649aead 100644 --- a/noir/noir-repo/test_programs/execution_success/closures_mut_ref/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/closures_mut_ref/src/main.nr @@ -1,13 +1,9 @@ fn main(mut x: Field) { let one = 1; - let add1 = |z| { - *z = *z + one; - }; + let add1 = |z| { *z = *z + one; }; let two = 2; - let add2 = |z| { - *z = *z + two; - }; + let add2 = |z| { *z = *z + two; }; add1(&mut x); assert(x == 1); diff --git a/noir/noir-repo/test_programs/execution_success/comptime_slice_equality/src/main.nr b/noir/noir-repo/test_programs/execution_success/comptime_slice_equality/src/main.nr index 83f82fca06f..e39e1fe0fb8 100644 --- a/noir/noir-repo/test_programs/execution_success/comptime_slice_equality/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/comptime_slice_equality/src/main.nr @@ -1,6 +1,5 @@ fn main() { - comptime - { + comptime { assert_eq(&[1], &[1]); } } diff --git a/noir/noir-repo/test_programs/execution_success/conditional_1/src/main.nr b/noir/noir-repo/test_programs/execution_success/conditional_1/src/main.nr index e7d780263b8..eedb8a697d1 100644 --- a/noir/noir-repo/test_programs/execution_success/conditional_1/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/conditional_1/src/main.nr @@ -25,10 +25,10 @@ fn main(a: u32, mut c: [u32; 4], x: [u8; 5], result: pub [u8; 32]) { for j in 0..4 { data[i + j] = c[4 - 1 - j]; for k in 0..4 { - ba = ba +data[k]; + ba = ba + data[k]; } if ba == 4864 { - c[3]=ba; + c[3] = ba; } } } @@ -84,7 +84,7 @@ fn main(a: u32, mut c: [u32; 4], x: [u8; 5], result: pub [u8; 32]) { x = a - a; for i in 0..4 { if c[i] == 0 { - x = i as u32 +2; + x = i as u32 + 2; } } assert(x == 0); diff --git a/noir/noir-repo/test_programs/execution_success/conditional_regression_547/src/main.nr b/noir/noir-repo/test_programs/execution_success/conditional_regression_547/src/main.nr index e47d23516a5..7c09e6a2e20 100644 --- a/noir/noir-repo/test_programs/execution_success/conditional_regression_547/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/conditional_regression_547/src/main.nr @@ -12,5 +12,9 @@ fn main(x: Field) -> pub Field { } fn safe_inverse(n: Field) -> Field { - if n == 0 { 0 } else { 1 / n } + if n == 0 { + 0 + } else { + 1 / n + } } diff --git a/noir/noir-repo/test_programs/execution_success/conditional_regression_661/src/main.nr b/noir/noir-repo/test_programs/execution_success/conditional_regression_661/src/main.nr index 26521a88358..1036acc6da4 100644 --- a/noir/noir-repo/test_programs/execution_success/conditional_regression_661/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/conditional_regression_661/src/main.nr @@ -22,7 +22,7 @@ fn issue_661_foo(array: [u32; 4], b: u32) -> [u32; 1] { fn issue_661_bar(a: [u32; 4]) -> [u32; 4] { let mut b: [u32; 4] = [0; 4]; - b[0]=a[0]+1; + b[0] = a[0] + 1; b } diff --git a/noir/noir-repo/test_programs/execution_success/databus_composite_calldata/src/main.nr b/noir/noir-repo/test_programs/execution_success/databus_composite_calldata/src/main.nr index e8b88e84d0d..fe6e2ed613a 100644 --- a/noir/noir-repo/test_programs/execution_success/databus_composite_calldata/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/databus_composite_calldata/src/main.nr @@ -7,7 +7,7 @@ fn main( foos: call_data(0) [Foo; 2], values: call_data(0) [[[u32; 2]; 2]; 3], zero: u32, - one: u32 + one: u32, ) -> pub u32 { assert_eq(foos[zero].x + 1, foos[one].x); assert_eq(foos[zero].y[3] + 2, foos[one].y[4]); diff --git a/noir/noir-repo/test_programs/execution_success/databus_two_calldata/src/main.nr b/noir/noir-repo/test_programs/execution_success/databus_two_calldata/src/main.nr index 75df2a0953c..f19852ae8a0 100644 --- a/noir/noir-repo/test_programs/execution_success/databus_two_calldata/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/databus_two_calldata/src/main.nr @@ -1,6 +1,10 @@ -// An simple program demonstrating two calldata array inputs and a single return data array. As an arbitrary example, +// An simple program demonstrating two calldata array inputs and a single return data array. As an arbitrary example, // the return data is computed as a linear combination of the calldata. -fn main(mut x: [u32; 4], y: call_data(0) [u32; 3], z: call_data(1) [u32; 4]) -> return_data [u32; 4] { +fn main( + mut x: [u32; 4], + y: call_data(0) [u32; 3], + z: call_data(1) [u32; 4], +) -> return_data [u32; 4] { let mut result = [0; 4]; for i in 0..3 { let idx = x[i]; diff --git a/noir/noir-repo/test_programs/execution_success/debug_logs/src/main.nr b/noir/noir-repo/test_programs/execution_success/debug_logs/src/main.nr index d1314406068..14344b1700b 100644 --- a/noir/noir-repo/test_programs/execution_success/debug_logs/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/debug_logs/src/main.nr @@ -6,7 +6,6 @@ fn main(x: Field, y: pub Field) { // let fmt_str: fmtstr<14, (Field, Field)> = f"i: {x}, j: {y}"; // let fmt_fmt_str = f"fmtstr: {fmt_str}, i: {x}"; // println(fmt_fmt_str); - // A `fmtstr` lets you easily perform string interpolation. let fmt_str: fmtstr<14, (Field, Field)> = f"i: {x}, j: {y}"; @@ -83,7 +82,9 @@ fn string_with_generics(string: fmtstr) -> fmtstr { string } -fn string_with_partial_generics(string: fmtstr) -> fmtstr { +fn string_with_partial_generics( + string: fmtstr, +) -> fmtstr { string } @@ -98,12 +99,10 @@ struct fooStruct { } fn regression_2903() { - let v : [str<1>; 1] = ["1"; 1]; + let v: [str<1>; 1] = ["1"; 1]; println(v); // will print [1] - let a = v[0]; println(a); // will print `1` - let bytes = ["aaa", "bbb", "ccc"]; println(bytes); } @@ -121,7 +120,9 @@ fn regression_2906() { let label_five_vals = "12345"; println(f"label_five_vals: {label_five_vals}"); - println(f"array_five_vals: {array_five_vals}, label_five_vals: {label_five_vals}"); + println( + f"array_five_vals: {array_five_vals}, label_five_vals: {label_five_vals}", + ); } fn regression_4967() { @@ -132,6 +133,8 @@ fn regression_4967() { println(slice_of_tuples); let slice_of_tuples_coerced: [(i32, u8)] = [(11, 22), (33, 44)]; - println(f"slice_of_tuples: {slice_of_tuples_coerced}, sentinel: {sentinel}"); + println( + f"slice_of_tuples: {slice_of_tuples_coerced}, sentinel: {sentinel}", + ); println(slice_of_tuples_coerced); } diff --git a/noir/noir-repo/test_programs/execution_success/derive/src/main.nr b/noir/noir-repo/test_programs/execution_success/derive/src/main.nr index f2f467eb761..6900aa6aead 100644 --- a/noir/noir-repo/test_programs/execution_success/derive/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/derive/src/main.nr @@ -6,7 +6,9 @@ trait DoNothing { } #[derive(DoNothing)] -struct MyStruct { my_field: u32 } +struct MyStruct { + my_field: u32, +} comptime fn derive_do_nothing(s: StructDefinition) -> Quoted { let typ = s.as_type(); @@ -36,7 +38,7 @@ struct MyOtherOtherStruct { } #[derive(Eq, Default, Hash, Ord)] -struct EmptyStruct { } +struct EmptyStruct {} fn main() { let s = MyStruct { my_field: 1 }; @@ -49,8 +51,16 @@ fn main() { assert_eq(o, o); // Field & str<2> above don't implement Ord - let o1 = MyOtherStruct { field1: 12 as u32, field2: 24 as i8, field3: MyOtherOtherStruct { x: 54 as i8 } }; - let o2 = MyOtherStruct { field1: 12 as u32, field2: 24 as i8, field3: MyOtherOtherStruct { x: 55 as i8 } }; + let o1 = MyOtherStruct { + field1: 12 as u32, + field2: 24 as i8, + field3: MyOtherOtherStruct { x: 54 as i8 }, + }; + let o2 = MyOtherStruct { + field1: 12 as u32, + field2: 24 as i8, + field3: MyOtherOtherStruct { x: 55 as i8 }, + }; assert(o1 < o2); let mut hasher = TestHasher { result: 0 }; diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr index c4be84e727b..aecaa931d43 100644 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof/src/main.nr @@ -1,7 +1,6 @@ - // This circuit aggregates two Honk proof from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 463; -global HONK_IDENTIFIER : u32 = 1; +global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; +global HONK_IDENTIFIER: u32 = 1; fn main( verification_key: [Field; 128], // This is the proof without public inputs attached. @@ -10,20 +9,20 @@ fn main( public_inputs: pub [Field; 1], key_hash: Field, // The second proof, currently set to be identical - proof_b: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28] + proof_b: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], ) { std::verify_proof_with_type( verification_key, proof, public_inputs, key_hash, - HONK_IDENTIFIER + HONK_IDENTIFIER, ); std::verify_proof_with_type( verification_key, proof_b, public_inputs, key_hash, - HONK_IDENTIFIER + HONK_IDENTIFIER, ); } diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr index 315b5e01b50..63902824da1 100644 --- a/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/double_verify_honk_proof_recursive/src/main.nr @@ -1,7 +1,6 @@ - // This circuit aggregates two Honk proofs from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 463; -global HONK_IDENTIFIER : u32 = 1; +global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; +global HONK_IDENTIFIER: u32 = 1; #[recursive] fn main( verification_key: [Field; 128], @@ -11,20 +10,20 @@ fn main( public_inputs: pub [Field; 1], key_hash: Field, // The second proof, currently set to be identical to the first proof - proof_b: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28] + proof_b: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], ) { std::verify_proof_with_type( verification_key, proof, public_inputs, key_hash, - HONK_IDENTIFIER + HONK_IDENTIFIER, ); std::verify_proof_with_type( verification_key, proof_b, public_inputs, key_hash, - HONK_IDENTIFIER + HONK_IDENTIFIER, ); } diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_nested_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_nested_proof/src/main.nr index 75a5fa9ebda..8dde07cae19 100644 --- a/noir/noir-repo/test_programs/execution_success/double_verify_nested_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/double_verify_nested_proof/src/main.nr @@ -1,9 +1,8 @@ - // This circuit aggregates two recursive proofs from `double_verify_proof_recursive`. -// Recursive aggregation is a backend-specific process and it is expected for backends -// to attach any extra data they may need (e.g. aggregation objects) to their proofs. -// Whether the proof we are verifying itself contains a recursive proof is expected to be -// a circuit constant by the barretenberg. Barretenberg hides this circuit constant in the +// Recursive aggregation is a backend-specific process and it is expected for backends +// to attach any extra data they may need (e.g. aggregation objects) to their proofs. +// Whether the proof we are verifying itself contains a recursive proof is expected to be +// a circuit constant by the barretenberg. Barretenberg hides this circuit constant in the // proof serialization. Thus, we must have separate circuits for verifying a normal proof and a recursive proof // with two different proof sizes. fn main( @@ -17,7 +16,7 @@ fn main( // This is currently not public. It is fine given that the vk is a part of the circuit definition. // I believe we want to eventually make it public too though. key_hash: Field, - proof_b: [Field; 109] + proof_b: [Field; 109], ) { std::verify_proof(verification_key, proof, public_inputs, key_hash); diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_proof/src/main.nr index 8d73bb09aa5..ac79e8ecf34 100644 --- a/noir/noir-repo/test_programs/execution_success/double_verify_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/double_verify_proof/src/main.nr @@ -1,16 +1,15 @@ - // This circuit aggregates two proofs from `assert_statement_recursive`. fn main( verification_key: [Field; 114], // This is the proof without public inputs attached. - // + // // This means: the size of this does not change with the number of public inputs. proof: [Field; 93], public_inputs: pub [Field; 1], // This is currently not public. It is fine given that the vk is a part of the circuit definition. // I believe we want to eventually make it public too though. key_hash: Field, - proof_b: [Field; 93] + proof_b: [Field; 93], ) { std::verify_proof(verification_key, proof, public_inputs, key_hash); diff --git a/noir/noir-repo/test_programs/execution_success/double_verify_proof_recursive/src/main.nr b/noir/noir-repo/test_programs/execution_success/double_verify_proof_recursive/src/main.nr index 5137a538e42..47ca84792a0 100644 --- a/noir/noir-repo/test_programs/execution_success/double_verify_proof_recursive/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/double_verify_proof_recursive/src/main.nr @@ -1,17 +1,16 @@ - // This circuit aggregates two proofs from `assert_statement_recursive`. #[recursive] fn main( verification_key: [Field; 114], // This is the proof without public inputs attached. - // + // // This means: the size of this does not change with the number of public inputs. proof: [Field; 93], public_inputs: pub [Field; 1], // This is currently not public. It is fine given that the vk is a part of the circuit definition. // I believe we want to eventually make it public too though. key_hash: Field, - proof_b: [Field; 93] + proof_b: [Field; 93], ) { std::verify_proof(verification_key, proof, public_inputs, key_hash); diff --git a/noir/noir-repo/test_programs/execution_success/ecdsa_secp256k1/src/main.nr b/noir/noir-repo/test_programs/execution_success/ecdsa_secp256k1/src/main.nr index 7f0999fc360..00d420089fc 100644 --- a/noir/noir-repo/test_programs/execution_success/ecdsa_secp256k1/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/ecdsa_secp256k1/src/main.nr @@ -3,12 +3,13 @@ fn main( hashed_message: [u8; 32], pub_key_x: [u8; 32], pub_key_y: [u8; 32], - signature: [u8; 64] + signature: [u8; 64], ) { // Hash the message, since secp256k1 expects a hashed_message let expected = std::hash::sha256(message); assert(hashed_message == expected); - let valid_signature = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + let valid_signature = + std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); assert(valid_signature); } diff --git a/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1/src/main.nr b/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1/src/main.nr index 09f427c37d9..d65e4a371b9 100644 --- a/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1/src/main.nr @@ -1,4 +1,5 @@ fn main(hashed_message: [u8; 32], pub_key_x: [u8; 32], pub_key_y: [u8; 32], signature: [u8; 64]) { - let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + let valid_signature = + std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); assert(valid_signature); } diff --git a/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr b/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr index b5bd633915f..ab9b70e52df 100644 --- a/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/ecdsa_secp256r1_3x/src/main.nr @@ -10,12 +10,23 @@ fn main( hashed_message_3: [u8; 32], pub_key_x_3: [u8; 32], pub_key_y_3: [u8; 32], - signature_3: [u8; 64] + signature_3: [u8; 64], ) { - let valid_signature = std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + let valid_signature = + std::ecdsa_secp256r1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); assert(valid_signature); - let valid_signature_2 = std::ecdsa_secp256r1::verify_signature(pub_key_x_2, pub_key_y_2, signature_2, hashed_message_2); + let valid_signature_2 = std::ecdsa_secp256r1::verify_signature( + pub_key_x_2, + pub_key_y_2, + signature_2, + hashed_message_2, + ); assert(valid_signature_2); - let valid_signature_3 = std::ecdsa_secp256r1::verify_signature(pub_key_x_3, pub_key_y_3, signature_3, hashed_message_3); + let valid_signature_3 = std::ecdsa_secp256r1::verify_signature( + pub_key_x_3, + pub_key_y_3, + signature_3, + hashed_message_3, + ); assert(valid_signature_3); } diff --git a/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr b/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr index 407ca049806..d0ce8e70053 100644 --- a/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr @@ -50,6 +50,8 @@ fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { // User A's signature over the message can't be used with another message assert(!eddsa_poseidon_verify(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg + 1)); // Using a different hash should fail - assert(!eddsa_verify::(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg)); + assert( + !eddsa_verify::(pub_key_a.x, pub_key_a.y, s_a, r8_a.x, r8_a.y, msg), + ); } } diff --git a/noir/noir-repo/test_programs/execution_success/embedded_curve_ops/src/main.nr b/noir/noir-repo/test_programs/execution_success/embedded_curve_ops/src/main.nr index 5372f73df23..e69184b9c96 100644 --- a/noir/noir-repo/test_programs/execution_success/embedded_curve_ops/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/embedded_curve_ops/src/main.nr @@ -8,7 +8,8 @@ fn main(priv_key: Field, pub_x: pub Field, pub_y: pub Field) { assert(res.y == pub_y); // Test that double function calling embedded_curve_add works as expected - let pub_point = std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y, is_infinite: false }; + let pub_point = + std::embedded_curve_ops::EmbeddedCurvePoint { x: pub_x, y: pub_y, is_infinite: false }; let res = pub_point.double(); let double = g1.add(g1); diff --git a/noir/noir-repo/test_programs/execution_success/fold_complex_outputs/src/main.nr b/noir/noir-repo/test_programs/execution_success/fold_complex_outputs/src/main.nr index 309d9747598..b433c8b416c 100644 --- a/noir/noir-repo/test_programs/execution_success/fold_complex_outputs/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/fold_complex_outputs/src/main.nr @@ -2,7 +2,7 @@ struct MyStruct { x: u32, y: u32, z: u32, - nested_struct: InnerStruct + nested_struct: InnerStruct, } struct InnerStruct { diff --git a/noir/noir-repo/test_programs/execution_success/fold_numeric_generic_poseidon/src/main.nr b/noir/noir-repo/test_programs/execution_success/fold_numeric_generic_poseidon/src/main.nr index 8eaea086ec0..c5993cf6523 100644 --- a/noir/noir-repo/test_programs/execution_success/fold_numeric_generic_poseidon/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/fold_numeric_generic_poseidon/src/main.nr @@ -10,7 +10,7 @@ pub fn poseidon_hash(inputs: [Field; N]) -> Field { fn main( to_hash: [[Field; HASH_LENGTH]; NUM_HASHES], - enable: [bool; NUM_HASHES] + enable: [bool; NUM_HASHES], ) -> pub [Field; NUM_HASHES + 1] { let mut result = [0; NUM_HASHES + 1]; for i in 0..NUM_HASHES { diff --git a/noir/noir-repo/test_programs/execution_success/global_consts/src/main.nr b/noir/noir-repo/test_programs/execution_success/global_consts/src/main.nr index 0b382ff6b8b..30c5f7167f3 100644 --- a/noir/noir-repo/test_programs/execution_success/global_consts/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/global_consts/src/main.nr @@ -10,8 +10,8 @@ global T_LEN: u32 = 2; global DERIVED: Field = M as Field + L; struct Dummy { - x: [Field; N], - y: [Field; foo::MAGIC_NUMBER] + x: [Field; N], + y: [Field; foo::MAGIC_NUMBER], } struct Test { @@ -31,7 +31,7 @@ fn main( a: [Field; M + N - N], b: [Field; 30 + N / 2], c: pub [Field; foo::MAGIC_NUMBER], - d: [Field; foo::bar::N] + d: [Field; foo::bar::N], ) { let test_struct = Dummy { x: d, y: c }; @@ -109,7 +109,7 @@ mod my_submodule { } struct Foo { - a: Field, + a: Field, } struct Bar {} @@ -121,6 +121,4 @@ impl Bar { } // Regression for #1440 -global foo = Foo { - a: Bar::get_a(), -}; +global foo = Foo { a: Bar::get_a() }; diff --git a/noir/noir-repo/test_programs/execution_success/hashmap/src/main.nr b/noir/noir-repo/test_programs/execution_success/hashmap/src/main.nr index e8bc486e1e2..964b900dce5 100644 --- a/noir/noir-repo/test_programs/execution_success/hashmap/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/hashmap/src/main.nr @@ -10,9 +10,9 @@ type K = Field; type V = Field; // It is more convenient and readable to use structs as input. -struct Entry{ +struct Entry { key: Field, - value: Field + value: Field, } global HASHMAP_CAP: u32 = 8; @@ -24,8 +24,8 @@ global K_CMP = FIELD_CMP; global V_CMP = FIELD_CMP; global KV_CMP = |a: (K, V), b: (K, V)| a.0.lt(b.0); -global ALLOCATE_HASHMAP = || -> HashMap> - HashMap::default(); +global ALLOCATE_HASHMAP = + || -> HashMap> HashMap::default(); fn main(input: [Entry; HASHMAP_LEN]) { test_sequential(input[0].key, input[0].value); @@ -54,7 +54,10 @@ fn test_sequential(key: K, value: V) { assert(value == got, f"Inserted {value} but got {got} for the same key."); hashmap.remove(key); - assert(hashmap.is_empty(), "HashMap after one insert and corresponding removal should be empty."); + assert( + hashmap.is_empty(), + "HashMap after one insert and corresponding removal should be empty.", + ); let got = hashmap.get(key); assert(got.is_none(), "Value has been removed, but is still available (not none)."); } @@ -123,11 +126,14 @@ fn test_retain() { let (key, value) = (11, 5); hashmap.insert(key, value); - let predicate = |key: K, value: V| -> bool {key * value == 55}; + let predicate = |key: K, value: V| -> bool { key * value == 55 }; hashmap.retain(predicate); assert(hashmap.len() == 2, "HashMap should have retained 2 elements."); - assert(hashmap.get(2).is_none(), "Pair should have been removed, since it does not match predicate."); + assert( + hashmap.get(2).is_none(), + "Pair should have been removed, since it does not match predicate.", + ); } // Equality trait check. @@ -172,10 +178,10 @@ fn test_mut_iterators() { hashmap.insert(5, 7); hashmap.insert(11, 13); - let f = |k: K| -> K{ k * 3}; + let f = |k: K| -> K { k * 3 }; hashmap.iter_keys_mut(f); - let f = |v: V| -> V{ v * 5}; + let f = |v: V| -> V { v * 5 }; hashmap.iter_values_mut(f); let keys: [K; 3] = cut(hashmap.keys()).sort_via(K_CMP); @@ -184,7 +190,7 @@ fn test_mut_iterators() { assert(keys == [6, 15, 33], f"Got incorrect iteration of keys: {keys}"); assert(values == [15, 35, 65], "Got incorrect iteration of values."); - let f = |k: K, v: V| -> (K, V){(k * 2, v * 2)}; + let f = |k: K, v: V| -> (K, V) { (k * 2, v * 2) }; hashmap.iter_mut(f); let entries: [(K, V); 3] = cut(hashmap.entries()).sort_via(KV_CMP); @@ -202,19 +208,17 @@ fn doc_tests() { let hashmap: HashMap> = HashMap::default(); assert(hashmap.is_empty()); // docs:end:default_example - // docs:start:with_hasher_example let my_hasher: BuildHasherDefault = Default::default(); - let hashmap: HashMap> = HashMap::with_hasher(my_hasher); + let hashmap: HashMap> = + HashMap::with_hasher(my_hasher); assert(hashmap.is_empty()); // docs:end:with_hasher_example - // docs:start:insert_example let mut map: HashMap> = HashMap::default(); map.insert(12, 42); assert(map.len() == 1); // docs:end:insert_example - get_example(map); // docs:start:remove_example @@ -225,7 +229,6 @@ fn doc_tests() { map.remove(12); assert(map.is_empty()); // docs:end:remove_example - // docs:start:is_empty_example assert(map.is_empty()); @@ -235,7 +238,6 @@ fn doc_tests() { map.remove(1); assert(map.is_empty()); // docs:end:is_empty_example - // docs:start:len_example // This is equivalent to checking map.is_empty() assert(map.len() == 0); @@ -252,19 +254,17 @@ fn doc_tests() { map.remove(1); assert(map.len() == 2); // docs:end:len_example - // docs:start:capacity_example - let empty_map: HashMap> = HashMap::default(); + let empty_map: HashMap> = + HashMap::default(); assert(empty_map.len() == 0); assert(empty_map.capacity() == 42); // docs:end:capacity_example - // docs:start:clear_example assert(!map.is_empty()); map.clear(); assert(map.is_empty()); // docs:end:clear_example - // docs:start:contains_key_example if map.contains_key(7) { let value = map.get(7); @@ -273,14 +273,12 @@ fn doc_tests() { println("No value for key 7!"); } // docs:end:contains_key_example - entries_examples(map); iter_examples(map); // docs:start:retain_example map.retain(|k, v| (k != 0) & (v != 0)); // docs:end:retain_example - // docs:start:eq_example let mut map1: HashMap> = HashMap::default(); let mut map2: HashMap> = HashMap::default(); @@ -318,7 +316,6 @@ fn entries_examples(map: HashMap pub Field { assert(twice(|x| x * 2, 5) == 20); assert((|x, y| x + y + 1)(2, 3) == 6); // nested lambdas - assert( - (|a, b| { - a + (|c| c + 2)(b) - })(0, 1) - == 3 - ); + assert((|a, b| { a + (|c| c + 2)(b) })(0, 1) == 3); // Closures: let a = 42; let g = || a; @@ -25,7 +20,7 @@ fn main(w: Field) -> pub Field { x = x + 1; assert((|y| y + z)(1) == 4); // When you capture mutable variables, - // again, the captured variable doesn't change: + // again, the captured variable doesn't change: let closure_capturing_mutable = (|y| y + x); assert(closure_capturing_mutable(1) == 5); x += 1; diff --git a/noir/noir-repo/test_programs/execution_success/inline_never_basic/Prover.toml b/noir/noir-repo/test_programs/execution_success/inline_never_basic/Prover.toml index f28f2f8cc48..fbe96700abe 100644 --- a/noir/noir-repo/test_programs/execution_success/inline_never_basic/Prover.toml +++ b/noir/noir-repo/test_programs/execution_success/inline_never_basic/Prover.toml @@ -1,2 +1,2 @@ x = "5" -y = "10" +y = "10" \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/keccak256/src/main.nr b/noir/noir-repo/test_programs/execution_success/keccak256/src/main.nr index ff18cae0c9c..1e13fa028b7 100644 --- a/noir/noir-repo/test_programs/execution_success/keccak256/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/keccak256/src/main.nr @@ -1,5 +1,4 @@ // docs:start:keccak256 - fn main(x: Field, result: [u8; 32]) { // We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field // The padding is taken care of by the program diff --git a/noir/noir-repo/test_programs/execution_success/loop/src/main.nr b/noir/noir-repo/test_programs/execution_success/loop/src/main.nr index 8365cf6f801..4482fdb3443 100644 --- a/noir/noir-repo/test_programs/execution_success/loop/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/loop/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is basic looping. fn main(six_as_u32: u32) { assert_eq(loop(4), six_as_u32); diff --git a/noir/noir-repo/test_programs/execution_success/merkle_insert/src/main.nr b/noir/noir-repo/test_programs/execution_success/merkle_insert/src/main.nr index a08088e847b..decb5b1401a 100644 --- a/noir/noir-repo/test_programs/execution_success/merkle_insert/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/merkle_insert/src/main.nr @@ -7,7 +7,7 @@ fn main( new_root: pub Field, leaf: Field, index: Field, - mimc_input: [Field; 4] + mimc_input: [Field; 4], ) { assert(old_root == std::merkle::compute_merkle_root(old_leaf, index, old_hash_path)); diff --git a/noir/noir-repo/test_programs/execution_success/modulus/src/main.nr b/noir/noir-repo/test_programs/execution_success/modulus/src/main.nr index 1627cc0dba2..36ec722a049 100644 --- a/noir/noir-repo/test_programs/execution_success/modulus/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/modulus/src/main.nr @@ -5,7 +5,7 @@ fn main(bn254_modulus_be_bytes: [u8; 32], bn254_modulus_be_bits: [u1; 254]) { assert_reverse( std::field::modulus_be_bytes(), - std::field::modulus_le_bytes() + std::field::modulus_le_bytes(), ); let modulus_be_byte_array = std::field::modulus_be_bytes(); diff --git a/noir/noir-repo/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr b/noir/noir-repo/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr index 9664b4d1ce6..f8070aa3ef4 100644 --- a/noir/noir-repo/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr @@ -20,9 +20,7 @@ unconstrained fn create_inside_brillig(values: [Field; 6]) -> [MyNote; 2] { } fn main(values: [Field; 6]) { - let notes = unsafe { - create_inside_brillig(values) - }; + let notes = unsafe { create_inside_brillig(values) }; assert(access_nested(notes) == (2 + 4 + 3 + 1)); } diff --git a/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/src/main.nr b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/src/main.nr index d6b463dbe30..aa1106132ff 100644 --- a/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/src/main.nr @@ -10,7 +10,7 @@ pub fn poseidon_hash(inputs: [Field; N]) -> Field { fn main( to_hash: [[Field; HASH_LENGTH]; NUM_HASHES], - enable: [bool; NUM_HASHES] + enable: [bool; NUM_HASHES], ) -> pub [Field; NUM_HASHES + 1] { let mut result = [0; NUM_HASHES + 1]; for i in 0..NUM_HASHES { diff --git a/noir/noir-repo/test_programs/execution_success/pedersen_commitment/src/main.nr b/noir/noir-repo/test_programs/execution_success/pedersen_commitment/src/main.nr index 81c605a64dd..c2225edcdf1 100644 --- a/noir/noir-repo/test_programs/execution_success/pedersen_commitment/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/pedersen_commitment/src/main.nr @@ -1,5 +1,4 @@ // docs:start:pedersen-commitment - fn main(x: Field, y: Field, expected_commitment: std::embedded_curve_ops::EmbeddedCurvePoint) { let commitment = std::hash::pedersen_commitment([x, y]); assert_eq(commitment.x, expected_commitment.x); diff --git a/noir/noir-repo/test_programs/execution_success/pedersen_hash/src/main.nr b/noir/noir-repo/test_programs/execution_success/pedersen_hash/src/main.nr index f8ec56a9d98..de981d44bca 100644 --- a/noir/noir-repo/test_programs/execution_success/pedersen_hash/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/pedersen_hash/src/main.nr @@ -1,5 +1,4 @@ // docs:start:pedersen-hash - fn main(x: Field, y: Field, expected_hash: Field) { let hash = std::hash::pedersen_hash([x, y]); assert_eq(hash, expected_hash); diff --git a/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Nargo.toml b/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Nargo.toml new file mode 100644 index 00000000000..0ccbf63aa8d --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ram_blowup_regression" +type = "bin" +authors = [""] +compiler_version = ">=0.35.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Prover.toml b/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Prover.toml new file mode 100644 index 00000000000..35842ce2431 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/Prover.toml @@ -0,0 +1 @@ +tx_effects_hash_input = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/src/main.nr b/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/src/main.nr new file mode 100644 index 00000000000..59843c368ec --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/ram_blowup_regression/src/main.nr @@ -0,0 +1,41 @@ +global TX_EFFECTS_HASH_INPUT_FIELDS = 256; + +// Convert a 32 byte array to a field element by truncating the final byte +pub fn field_from_bytes_32_trunc(bytes32: [u8; 32]) -> Field { + // Convert it to a field element + let mut v = 1; + let mut high = 0 as Field; + let mut low = 0 as Field; + + for i in 0..15 { + // covers bytes 16..30 (31 is truncated and ignored) + low = low + (bytes32[15 + 15 - i] as Field) * v; + v = v * 256; + // covers bytes 0..14 + high = high + (bytes32[14 - i] as Field) * v; + } + // covers byte 15 + low = low + (bytes32[15] as Field) * v; + + low + high * v +} + +pub fn sha256_to_field(bytes_to_hash: [u8; N]) -> Field { + let sha256_hashed = std::hash::sha256(bytes_to_hash); + let hash_in_a_field = field_from_bytes_32_trunc(sha256_hashed); + + hash_in_a_field +} + +fn main(tx_effects_hash_input: [Field; TX_EFFECTS_HASH_INPUT_FIELDS]) -> pub Field { + let mut hash_input_flattened = [0; TX_EFFECTS_HASH_INPUT_FIELDS * 32]; + for offset in 0..TX_EFFECTS_HASH_INPUT_FIELDS { + let input_as_bytes: [u8; 32] = tx_effects_hash_input[offset].to_be_bytes(); + for byte_index in 0..32 { + hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index]; + } + } + + let sha_digest = sha256_to_field(hash_input_flattened); + sha_digest +} diff --git a/noir/noir-repo/test_programs/execution_success/reference_only_used_as_alias/src/main.nr b/noir/noir-repo/test_programs/execution_success/reference_only_used_as_alias/src/main.nr index c04d68d1748..8b5b804cf94 100644 --- a/noir/noir-repo/test_programs/execution_success/reference_only_used_as_alias/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/reference_only_used_as_alias/src/main.nr @@ -13,11 +13,6 @@ impl EventInterface for ExampleEvent0 { } } -struct ExampleEvent1 { - value2: u8, - value3: u8, -} - struct Context { a: u32, b: [u32; 3], @@ -38,7 +33,10 @@ impl Context { } } -fn compute(_event: Event) -> ([u8; 5], Field) where Event: EventInterface { +fn compute(_event: Event) -> ([u8; 5], Field) +where + Event: EventInterface, +{ ([0 as u8; 5], 0) } @@ -46,17 +44,23 @@ fn emit_with_keys( context: &mut Context, randomness: Field, event: Event, - inner_compute: fn(Event) -> ([u8; OB], Field) -) where Event: EventInterface { + inner_compute: fn(Event) -> ([u8; OB], Field), +) +where + Event: EventInterface, +{ let (log, log_hash) = inner_compute(event); context.emit_raw_log(randomness, log, log_hash); } -pub fn encode_event_with_randomness( +fn encode_event_with_randomness( context: &mut Context, - randomness: Field -) -> fn[(&mut Context, Field)](Event) -> () where Event: EventInterface { - | e: Event | { + randomness: Field, +) -> fn[(&mut Context, Field)](Event) -> () +where + Event: EventInterface, +{ + |e: Event| { unsafe { func(context.a); } diff --git a/noir/noir-repo/test_programs/execution_success/references/src/main.nr b/noir/noir-repo/test_programs/execution_success/references/src/main.nr index 1a9be5f82b9..4ddbf8aa1e3 100644 --- a/noir/noir-repo/test_programs/execution_success/references/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/references/src/main.nr @@ -40,9 +40,13 @@ fn add1(x: &mut Field) { *x += 1; } -struct S { y: Field } +struct S { + y: Field, +} -struct Nested { y: &mut &mut Field } +struct Nested { + y: &mut &mut Field, +} struct C { foo: Field, @@ -50,7 +54,7 @@ struct C { } struct C2 { - array: &mut [Field; 2] + array: &mut [Field; 2], } impl S { @@ -74,8 +78,12 @@ fn regression_1887() { assert(foo.bar.x == 32); } -struct Foo { bar: Bar } -struct Bar { x: Field } +struct Foo { + bar: Bar, +} +struct Bar { + x: Field, +} impl Bar { fn mutate(&mut self) { diff --git a/noir/noir-repo/test_programs/execution_success/regression/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression/src/main.nr index e6226de29ef..1c2f557d2cd 100644 --- a/noir/noir-repo/test_programs/execution_success/regression/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression/src/main.nr @@ -34,16 +34,16 @@ fn compact_decode(input: [u8; N], length: Field) -> ([U4; NIBBLE_LEN for i in 1..input.len() { if i as u32 < length as u32 { let x = input[i]; - nibble[2*i - 1] = U4::from_u8(x >> 4); - nibble[2*i] = U4::from_u8(x & 0x0f); + nibble[2 * i - 1] = U4::from_u8(x >> 4); + nibble[2 * i] = U4::from_u8(x & 0x0f); } } } else { for i in 0..2 { if (i as u32) < length as u32 - 1 { let x = input[i + 1]; - nibble[2*i] = U4::from_u8(x >> 4); - nibble[2*i + 1] = U4::from_u8(x & 0x0f); + nibble[2 * i] = U4::from_u8(x >> 4); + nibble[2 * i + 1] = U4::from_u8(x & 0x0f); } } } @@ -63,7 +63,7 @@ fn enc(value: [u8; N], value_length: Field) -> ([u8; 32], Field) { out_value[0] = 0x80 + value_length as u8; for i in 1..value.len() { - out_value[i] = value[i-1]; + out_value[i] = value[i - 1]; } let out = (out_value, value_length + 1); @@ -100,24 +100,25 @@ fn main(x: [u8; 5], z: Field) { assert(len == 5); assert( [nib[0], nib[1], nib[2], nib[3], nib[4]] - == [U4::from_u8(15), U4::from_u8(1), U4::from_u8(12), U4::from_u8(11), U4::from_u8(8)] + == [U4::from_u8(15), U4::from_u8(1), U4::from_u8(12), U4::from_u8(11), U4::from_u8(8)], ); // Issue 1169 let val1 = [ 0xb8, 0x8f, 0x61, 0xe6, 0xfb, 0xda, 0x83, 0xfb, 0xff, 0xfa, 0xbe, 0x36, 0x41, 0x12, 0x13, 0x74, 0x80, 0x39, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 + 0x00, 0x00, ]; let val1_length = 20; let enc_val1 = enc(val1, val1_length); assert( - enc_val1.0 == [ - 0x94, 0xb8, 0x8f, 0x61, 0xe6, 0xfb, 0xda, 0x83, 0xfb, 0xff, 0xfa, 0xbe, 0x36, 0x41, - 0x12, 0x13, 0x74, 0x80, 0x39, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - ] + enc_val1.0 + == [ + 0x94, 0xb8, 0x8f, 0x61, 0xe6, 0xfb, 0xda, 0x83, 0xfb, 0xff, 0xfa, 0xbe, 0x36, 0x41, + 0x12, 0x13, 0x74, 0x80, 0x39, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ], ); assert(enc_val1.1 == 21); // Issue 2399 diff --git a/noir/noir-repo/test_programs/execution_success/regression_3394/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_3394/src/main.nr index 59494253757..393e5c91bc2 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_3394/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_3394/src/main.nr @@ -1,4 +1,4 @@ fn main() { - let x : i8 = -128; + let x: i8 = -128; std::println(x); } diff --git a/noir/noir-repo/test_programs/execution_success/regression_3607/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_3607/src/main.nr index 9c7ef243f60..a2a5ed19d91 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_3607/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_3607/src/main.nr @@ -1,8 +1,8 @@ fn main(mut x: u32) { if x == 0 { - x = (x+1) / x; + x = (x + 1) / x; } else { - x = (x+1) / x; + x = (x + 1) / x; } assert(x != 0); } diff --git a/noir/noir-repo/test_programs/execution_success/regression_3889/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_3889/src/main.nr index 402a69a10da..2b54ae54418 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_3889/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_3889/src/main.nr @@ -1,5 +1,5 @@ mod Foo { - struct NewType{ + struct NewType { a: Field, } } diff --git a/noir/noir-repo/test_programs/execution_success/regression_4088/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_4088/src/main.nr index b2a050b5db3..25097b14ae8 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_4088/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_4088/src/main.nr @@ -16,7 +16,10 @@ fn check(serialized_note: [Field; N]) { assert(serialized_note[0] == 0); } -fn oopsie(note: Note) where Note: Serialize { +fn oopsie(note: Note) +where + Note: Serialize, +{ let serialized_note = Note::serialize(note); check(serialized_note) diff --git a/noir/noir-repo/test_programs/execution_success/regression_4124/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_4124/src/main.nr index b0e1a394c32..c2407ea91b9 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_4124/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_4124/src/main.nr @@ -24,7 +24,10 @@ impl PublicMutable { PublicMutable { storage_slot } } - pub fn read(_self: Self) -> T where T: MyDeserialize { + pub fn read(_self: Self) -> T + where + T: MyDeserialize, + { // storage_read returns slice here let fields: [Field; T_SERIALIZED_LEN] = storage_read(); T::deserialize(fields) diff --git a/noir/noir-repo/test_programs/execution_success/regression_4449/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_4449/src/main.nr index 66bab2e09f4..3fda39bd874 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_4449/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_4449/src/main.nr @@ -1,5 +1,4 @@ // Regression test for issue #4449 - fn main(x: u8, result: [u8; 32]) { let x = x % 31; let mut digest = [0; 32]; diff --git a/noir/noir-repo/test_programs/execution_success/regression_4709/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_4709/src/main.nr index 1df09c53b55..9d730542641 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_4709/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_4709/src/main.nr @@ -1,262 +1,3845 @@ // Regression test for issue #4709 global EXPONENTIATE: [[Field; 257]; 257] = [ -[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], -[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], -[1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1], -[1, 3, 9, 27, 81, 243, 215, 131, 136, 151, 196, 74, 222, 152, 199, 83, 249, 233, 185, 41, 123, 112, 79, 237, 197, 77, 231, 179, 23, 69, 207, 107, 64, 192, 62, 186, 44, 132, 139, 160, 223, 155, 208, 110, 73, 219, 143, 172, 2, 6, 18, 54, 162, 229, 173, 5, 15, 45, 135, 148, 187, 47, 141, 166, 241, 209, 113, 82, 246, 224, 158, 217, 137, 154, 205, 101, 46, 138, 157, 214, 128, 127, 124, 115, 88, 7, 21, 63, 189, 53, 159, 220, 146, 181, 29, 87, 4, 12, 36, 108, 67, 201, 89, 10, 30, 90, 13, 39, 117, 94, 25, 75, 225, 161, 226, 164, 235, 191, 59, 177, 17, 51, 153, 202, 92, 19, 57, 171, 256, 254, 248, 230, 176, 14, 42, 126, 121, 106, 61, 183, 35, 105, 58, 174, 8, 24, 72, 216, 134, 145, 178, 20, 60, 180, 26, 78, 234, 188, 50, 150, 193, 65, 195, 71, 213, 125, 118, 97, 34, 102, 49, 147, 184, 38, 114, 85, 255, 251, 239, 203, 95, 28, 84, 252, 242, 212, 122, 109, 70, 210, 116, 91, 16, 48, 144, 175, 11, 33, 99, 40, 120, 103, 52, 156, 211, 119, 100, 43, 129, 130, 133, 142, 169, 250, 236, 194, 68, 204, 98, 37, 111, 76, 228, 170, 253, 245, 221, 149, 190, 56, 168, 247, 227, 167, 244, 218, 140, 163, 232, 182, 32, 96, 31, 93, 22, 66, 198, 80, 240, 206, 104, 55, 165, 238, 200, 86, 1], -[1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1], -[1, 5, 25, 125, 111, 41, 205, 254, 242, 182, 139, 181, 134, 156, 9, 45, 225, 97, 228, 112, 46, 230, 122, 96, 223, 87, 178, 119, 81, 148, 226, 102, 253, 237, 157, 14, 70, 93, 208, 12, 60, 43, 215, 47, 235, 147, 221, 77, 128, 126, 116, 66, 73, 108, 26, 130, 136, 166, 59, 38, 190, 179, 124, 106, 16, 80, 143, 201, 234, 142, 196, 209, 17, 85, 168, 69, 88, 183, 144, 206, 2, 10, 50, 250, 222, 82, 153, 251, 227, 107, 21, 105, 11, 55, 18, 90, 193, 194, 199, 224, 92, 203, 244, 192, 189, 174, 99, 238, 162, 39, 195, 204, 249, 217, 57, 28, 140, 186, 159, 24, 120, 86, 173, 94, 213, 37, 185, 154, 256, 252, 232, 132, 146, 216, 52, 3, 15, 75, 118, 76, 123, 101, 248, 212, 32, 160, 29, 145, 211, 27, 135, 161, 34, 170, 79, 138, 176, 109, 31, 155, 4, 20, 100, 243, 187, 164, 49, 245, 197, 214, 42, 210, 22, 110, 36, 180, 129, 131, 141, 191, 184, 149, 231, 127, 121, 91, 198, 219, 67, 78, 133, 151, 241, 177, 114, 56, 23, 115, 61, 48, 240, 172, 89, 188, 169, 74, 113, 51, 255, 247, 207, 7, 35, 175, 104, 6, 30, 150, 236, 152, 246, 202, 239, 167, 64, 63, 58, 33, 165, 54, 13, 65, 68, 83, 158, 19, 95, 218, 62, 53, 8, 40, 200, 229, 117, 71, 98, 233, 137, 171, 84, 163, 44, 220, 72, 103, 1], -[1, 6, 36, 216, 11, 66, 139, 63, 121, 212, 244, 179, 46, 19, 114, 170, 249, 209, 226, 71, 169, 243, 173, 10, 60, 103, 104, 110, 146, 105, 116, 182, 64, 127, 248, 203, 190, 112, 158, 177, 34, 204, 196, 148, 117, 188, 100, 86, 2, 12, 72, 175, 22, 132, 21, 126, 242, 167, 231, 101, 92, 38, 228, 83, 241, 161, 195, 142, 81, 229, 89, 20, 120, 206, 208, 220, 35, 210, 232, 107, 128, 254, 239, 149, 123, 224, 59, 97, 68, 151, 135, 39, 234, 119, 200, 172, 4, 24, 144, 93, 44, 7, 42, 252, 227, 77, 205, 202, 184, 76, 199, 166, 225, 65, 133, 27, 162, 201, 178, 40, 240, 155, 159, 183, 70, 163, 207, 214, 256, 251, 221, 41, 246, 191, 118, 194, 136, 45, 13, 78, 211, 238, 143, 87, 8, 48, 31, 186, 88, 14, 84, 247, 197, 154, 153, 147, 111, 152, 141, 75, 193, 130, 9, 54, 67, 145, 99, 80, 223, 53, 61, 109, 140, 69, 157, 171, 255, 245, 185, 82, 235, 125, 236, 131, 15, 90, 26, 156, 165, 219, 29, 174, 16, 96, 62, 115, 176, 28, 168, 237, 137, 51, 49, 37, 222, 47, 25, 150, 129, 3, 18, 108, 134, 33, 198, 160, 189, 106, 122, 218, 23, 138, 57, 85, 253, 233, 113, 164, 213, 250, 215, 5, 30, 180, 52, 55, 73, 181, 58, 91, 32, 192, 124, 230, 95, 56, 79, 217, 17, 102, 98, 74, 187, 94, 50, 43, 1], -[1, 7, 49, 86, 88, 102, 200, 115, 34, 238, 124, 97, 165, 127, 118, 55, 128, 125, 104, 214, 213, 206, 157, 71, 240, 138, 195, 80, 46, 65, 198, 101, 193, 66, 205, 150, 22, 154, 50, 93, 137, 188, 31, 217, 234, 96, 158, 78, 32, 224, 26, 182, 246, 180, 232, 82, 60, 163, 113, 20, 140, 209, 178, 218, 241, 145, 244, 166, 134, 167, 141, 216, 227, 47, 72, 247, 187, 24, 168, 148, 8, 56, 135, 174, 190, 45, 58, 149, 15, 105, 221, 5, 35, 245, 173, 183, 253, 229, 61, 170, 162, 106, 228, 54, 121, 76, 18, 126, 111, 6, 42, 37, 2, 14, 98, 172, 176, 204, 143, 230, 68, 219, 248, 194, 73, 254, 236, 110, 256, 250, 208, 171, 169, 155, 57, 142, 223, 19, 133, 160, 92, 130, 139, 202, 129, 132, 153, 43, 44, 51, 100, 186, 17, 119, 62, 177, 211, 192, 59, 156, 64, 191, 52, 107, 235, 103, 207, 164, 120, 69, 226, 40, 23, 161, 99, 179, 225, 33, 231, 75, 11, 77, 25, 175, 197, 94, 144, 237, 117, 48, 79, 39, 16, 112, 13, 91, 123, 90, 116, 41, 30, 210, 185, 10, 70, 233, 89, 109, 249, 201, 122, 83, 67, 212, 199, 108, 242, 152, 36, 252, 222, 12, 84, 74, 4, 28, 196, 87, 95, 151, 29, 203, 136, 181, 239, 131, 146, 251, 215, 220, 255, 243, 159, 85, 81, 53, 114, 27, 189, 38, 9, 63, 184, 3, 21, 147, 1], -[1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1], -[1, 9, 81, 215, 136, 196, 222, 199, 249, 185, 123, 79, 197, 231, 23, 207, 64, 62, 44, 139, 223, 208, 73, 143, 2, 18, 162, 173, 15, 135, 187, 141, 241, 113, 246, 158, 137, 205, 46, 157, 128, 124, 88, 21, 189, 159, 146, 29, 4, 36, 67, 89, 30, 13, 117, 25, 225, 226, 235, 59, 17, 153, 92, 57, 256, 248, 176, 42, 121, 61, 35, 58, 8, 72, 134, 178, 60, 26, 234, 50, 193, 195, 213, 118, 34, 49, 184, 114, 255, 239, 95, 84, 242, 122, 70, 116, 16, 144, 11, 99, 120, 52, 211, 100, 129, 133, 169, 236, 68, 98, 111, 228, 253, 221, 190, 168, 227, 244, 140, 232, 32, 31, 22, 198, 240, 104, 165, 200, 1, 9, 81, 215, 136, 196, 222, 199, 249, 185, 123, 79, 197, 231, 23, 207, 64, 62, 44, 139, 223, 208, 73, 143, 2, 18, 162, 173, 15, 135, 187, 141, 241, 113, 246, 158, 137, 205, 46, 157, 128, 124, 88, 21, 189, 159, 146, 29, 4, 36, 67, 89, 30, 13, 117, 25, 225, 226, 235, 59, 17, 153, 92, 57, 256, 248, 176, 42, 121, 61, 35, 58, 8, 72, 134, 178, 60, 26, 234, 50, 193, 195, 213, 118, 34, 49, 184, 114, 255, 239, 95, 84, 242, 122, 70, 116, 16, 144, 11, 99, 120, 52, 211, 100, 129, 133, 169, 236, 68, 98, 111, 228, 253, 221, 190, 168, 227, 244, 140, 232, 32, 31, 22, 198, 240, 104, 165, 200, 1], -[1, 10, 100, 229, 234, 27, 13, 130, 15, 150, 215, 94, 169, 148, 195, 151, 225, 194, 141, 125, 222, 164, 98, 209, 34, 83, 59, 76, 246, 147, 185, 51, 253, 217, 114, 112, 92, 149, 205, 251, 197, 171, 168, 138, 95, 179, 248, 167, 128, 252, 207, 14, 140, 115, 122, 192, 121, 182, 21, 210, 44, 183, 31, 53, 16, 160, 58, 66, 146, 175, 208, 24, 240, 87, 99, 219, 134, 55, 36, 103, 2, 20, 200, 201, 211, 54, 26, 3, 30, 43, 173, 188, 81, 39, 133, 45, 193, 131, 25, 250, 187, 71, 196, 161, 68, 166, 118, 152, 235, 37, 113, 102, 249, 177, 228, 224, 184, 41, 153, 245, 137, 85, 79, 19, 190, 101, 239, 77, 256, 247, 157, 28, 23, 230, 244, 127, 242, 107, 42, 163, 88, 109, 62, 106, 32, 63, 116, 132, 35, 93, 159, 48, 223, 174, 198, 181, 11, 110, 72, 206, 4, 40, 143, 145, 165, 108, 52, 6, 60, 86, 89, 119, 162, 78, 9, 90, 129, 5, 50, 243, 117, 142, 135, 65, 136, 75, 236, 47, 213, 74, 226, 204, 241, 97, 199, 191, 111, 82, 49, 233, 17, 170, 158, 38, 123, 202, 221, 154, 255, 237, 57, 56, 46, 203, 231, 254, 227, 214, 84, 69, 176, 218, 124, 212, 64, 126, 232, 7, 70, 186, 61, 96, 189, 91, 139, 105, 22, 220, 144, 155, 8, 80, 29, 33, 73, 216, 104, 12, 120, 172, 178, 238, 67, 156, 18, 180, 1], -[1, 11, 121, 46, 249, 169, 60, 146, 64, 190, 34, 117, 2, 22, 242, 92, 241, 81, 120, 35, 128, 123, 68, 234, 4, 44, 227, 184, 225, 162, 240, 70, 256, 246, 136, 211, 8, 88, 197, 111, 193, 67, 223, 140, 255, 235, 15, 165, 16, 176, 137, 222, 129, 134, 189, 23, 253, 213, 30, 73, 32, 95, 17, 187, 1, 11, 121, 46, 249, 169, 60, 146, 64, 190, 34, 117, 2, 22, 242, 92, 241, 81, 120, 35, 128, 123, 68, 234, 4, 44, 227, 184, 225, 162, 240, 70, 256, 246, 136, 211, 8, 88, 197, 111, 193, 67, 223, 140, 255, 235, 15, 165, 16, 176, 137, 222, 129, 134, 189, 23, 253, 213, 30, 73, 32, 95, 17, 187, 1, 11, 121, 46, 249, 169, 60, 146, 64, 190, 34, 117, 2, 22, 242, 92, 241, 81, 120, 35, 128, 123, 68, 234, 4, 44, 227, 184, 225, 162, 240, 70, 256, 246, 136, 211, 8, 88, 197, 111, 193, 67, 223, 140, 255, 235, 15, 165, 16, 176, 137, 222, 129, 134, 189, 23, 253, 213, 30, 73, 32, 95, 17, 187, 1, 11, 121, 46, 249, 169, 60, 146, 64, 190, 34, 117, 2, 22, 242, 92, 241, 81, 120, 35, 128, 123, 68, 234, 4, 44, 227, 184, 225, 162, 240, 70, 256, 246, 136, 211, 8, 88, 197, 111, 193, 67, 223, 140, 255, 235, 15, 165, 16, 176, 137, 222, 129, 134, 189, 23, 253, 213, 30, 73, 32, 95, 17, 187, 1], -[1, 12, 144, 186, 176, 56, 158, 97, 136, 90, 52, 110, 35, 163, 157, 85, 249, 161, 133, 54, 134, 66, 21, 252, 197, 51, 98, 148, 234, 238, 29, 91, 64, 254, 221, 82, 213, 243, 89, 40, 223, 106, 244, 101, 184, 152, 25, 43, 2, 24, 31, 115, 95, 112, 59, 194, 15, 180, 104, 220, 70, 69, 57, 170, 241, 65, 9, 108, 11, 132, 42, 247, 137, 102, 196, 39, 211, 219, 58, 182, 128, 251, 185, 164, 169, 229, 178, 80, 189, 212, 231, 202, 111, 47, 50, 86, 4, 48, 62, 230, 190, 224, 118, 131, 30, 103, 208, 183, 140, 138, 114, 83, 225, 130, 18, 216, 22, 7, 84, 237, 17, 204, 135, 78, 165, 181, 116, 107, 256, 245, 113, 71, 81, 201, 99, 160, 121, 167, 205, 147, 222, 94, 100, 172, 8, 96, 124, 203, 123, 191, 236, 5, 60, 206, 159, 109, 23, 19, 228, 166, 193, 3, 36, 175, 44, 14, 168, 217, 34, 151, 13, 156, 73, 105, 232, 214, 255, 233, 226, 142, 162, 145, 198, 63, 242, 77, 153, 37, 187, 188, 200, 87, 16, 192, 248, 149, 246, 125, 215, 10, 120, 155, 61, 218, 46, 38, 199, 75, 129, 6, 72, 93, 88, 28, 79, 177, 68, 45, 26, 55, 146, 210, 207, 171, 253, 209, 195, 27, 67, 33, 139, 126, 227, 154, 49, 74, 117, 119, 143, 174, 32, 127, 239, 41, 235, 250, 173, 20, 240, 53, 122, 179, 92, 76, 141, 150, 1], -[1, 13, 169, 141, 34, 185, 92, 168, 128, 122, 44, 58, 240, 36, 211, 173, 193, 196, 235, 228, 137, 239, 23, 42, 32, 159, 11, 143, 60, 9, 117, 236, 241, 49, 123, 57, 227, 124, 70, 139, 8, 104, 67, 100, 15, 195, 222, 59, 253, 205, 95, 207, 121, 31, 146, 99, 2, 26, 81, 25, 68, 113, 184, 79, 256, 244, 88, 116, 223, 72, 165, 89, 129, 135, 213, 199, 17, 221, 46, 84, 64, 61, 22, 29, 120, 18, 234, 215, 225, 98, 246, 114, 197, 248, 140, 21, 16, 208, 134, 200, 30, 133, 187, 118, 249, 153, 190, 157, 242, 62, 35, 198, 4, 52, 162, 50, 136, 226, 111, 158, 255, 231, 176, 232, 189, 144, 73, 178, 1, 13, 169, 141, 34, 185, 92, 168, 128, 122, 44, 58, 240, 36, 211, 173, 193, 196, 235, 228, 137, 239, 23, 42, 32, 159, 11, 143, 60, 9, 117, 236, 241, 49, 123, 57, 227, 124, 70, 139, 8, 104, 67, 100, 15, 195, 222, 59, 253, 205, 95, 207, 121, 31, 146, 99, 2, 26, 81, 25, 68, 113, 184, 79, 256, 244, 88, 116, 223, 72, 165, 89, 129, 135, 213, 199, 17, 221, 46, 84, 64, 61, 22, 29, 120, 18, 234, 215, 225, 98, 246, 114, 197, 248, 140, 21, 16, 208, 134, 200, 30, 133, 187, 118, 249, 153, 190, 157, 242, 62, 35, 198, 4, 52, 162, 50, 136, 226, 111, 158, 255, 231, 176, 232, 189, 144, 73, 178, 1], -[1, 14, 196, 174, 123, 180, 207, 71, 223, 38, 18, 252, 187, 48, 158, 156, 128, 250, 159, 170, 67, 167, 25, 93, 17, 238, 248, 131, 35, 233, 178, 179, 193, 132, 49, 172, 95, 45, 116, 82, 120, 138, 133, 63, 111, 12, 168, 39, 32, 191, 104, 171, 81, 106, 199, 216, 197, 188, 62, 97, 73, 251, 173, 109, 241, 33, 205, 43, 88, 204, 29, 149, 30, 163, 226, 80, 92, 3, 42, 74, 8, 112, 26, 107, 213, 155, 114, 54, 242, 47, 144, 217, 211, 127, 236, 220, 253, 201, 244, 75, 22, 51, 200, 230, 136, 105, 185, 20, 23, 65, 139, 147, 2, 28, 135, 91, 246, 103, 157, 142, 189, 76, 36, 247, 117, 96, 59, 55, 256, 243, 61, 83, 134, 77, 50, 186, 34, 219, 239, 5, 70, 209, 99, 101, 129, 7, 98, 87, 190, 90, 232, 164, 240, 19, 9, 126, 222, 24, 79, 78, 64, 125, 208, 85, 162, 212, 141, 175, 137, 119, 124, 194, 146, 245, 89, 218, 225, 66, 153, 86, 176, 151, 58, 41, 60, 69, 195, 160, 184, 6, 84, 148, 16, 224, 52, 214, 169, 53, 228, 108, 227, 94, 31, 177, 165, 254, 215, 183, 249, 145, 231, 150, 44, 102, 143, 203, 15, 210, 113, 40, 46, 130, 21, 37, 4, 56, 13, 182, 235, 206, 57, 27, 121, 152, 72, 237, 234, 192, 118, 110, 255, 229, 122, 166, 11, 154, 100, 115, 68, 181, 221, 10, 140, 161, 198, 202, 1], -[1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1], -[1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1], -[1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1], -[1, 18, 67, 178, 120, 104, 73, 29, 8, 144, 22, 139, 189, 61, 70, 232, 64, 124, 176, 84, 227, 231, 46, 57, 255, 221, 123, 158, 17, 49, 111, 199, 241, 226, 213, 236, 136, 135, 117, 50, 129, 9, 162, 89, 60, 52, 165, 143, 4, 72, 11, 198, 223, 159, 35, 116, 32, 62, 88, 42, 242, 244, 23, 157, 256, 239, 190, 79, 137, 153, 184, 228, 249, 113, 235, 118, 68, 196, 187, 25, 193, 133, 81, 173, 30, 26, 211, 200, 2, 36, 134, 99, 240, 208, 146, 58, 16, 31, 44, 21, 121, 122, 140, 207, 128, 248, 95, 168, 197, 205, 92, 114, 253, 185, 246, 59, 34, 98, 222, 141, 225, 195, 169, 215, 15, 13, 234, 100, 1, 18, 67, 178, 120, 104, 73, 29, 8, 144, 22, 139, 189, 61, 70, 232, 64, 124, 176, 84, 227, 231, 46, 57, 255, 221, 123, 158, 17, 49, 111, 199, 241, 226, 213, 236, 136, 135, 117, 50, 129, 9, 162, 89, 60, 52, 165, 143, 4, 72, 11, 198, 223, 159, 35, 116, 32, 62, 88, 42, 242, 244, 23, 157, 256, 239, 190, 79, 137, 153, 184, 228, 249, 113, 235, 118, 68, 196, 187, 25, 193, 133, 81, 173, 30, 26, 211, 200, 2, 36, 134, 99, 240, 208, 146, 58, 16, 31, 44, 21, 121, 122, 140, 207, 128, 248, 95, 168, 197, 205, 92, 114, 253, 185, 246, 59, 34, 98, 222, 141, 225, 195, 169, 215, 15, 13, 234, 100, 1], -[1, 19, 104, 177, 22, 161, 232, 39, 227, 201, 221, 87, 111, 53, 236, 115, 129, 138, 52, 217, 11, 209, 116, 148, 242, 229, 239, 172, 184, 155, 118, 186, 193, 69, 26, 237, 134, 233, 58, 74, 121, 243, 248, 86, 92, 206, 59, 93, 225, 163, 13, 247, 67, 245, 29, 37, 189, 250, 124, 43, 46, 103, 158, 175, 241, 210, 135, 252, 162, 251, 143, 147, 223, 125, 62, 150, 23, 180, 79, 216, 249, 105, 196, 126, 81, 254, 200, 202, 240, 191, 31, 75, 140, 90, 168, 108, 253, 181, 98, 63, 169, 127, 100, 101, 120, 224, 144, 166, 70, 45, 84, 54, 255, 219, 49, 160, 213, 192, 50, 179, 60, 112, 72, 83, 35, 151, 42, 27, 256, 238, 153, 80, 235, 96, 25, 218, 30, 56, 36, 170, 146, 204, 21, 142, 128, 119, 205, 40, 246, 48, 141, 109, 15, 28, 18, 85, 73, 102, 139, 71, 64, 188, 231, 20, 123, 24, 199, 183, 136, 14, 9, 171, 165, 51, 198, 164, 32, 94, 244, 10, 190, 12, 228, 220, 68, 7, 133, 214, 211, 154, 99, 82, 16, 47, 122, 5, 95, 6, 114, 110, 34, 132, 195, 107, 234, 77, 178, 41, 8, 152, 61, 131, 176, 3, 57, 55, 17, 66, 226, 182, 117, 167, 89, 149, 4, 76, 159, 194, 88, 130, 157, 156, 137, 33, 113, 91, 187, 212, 173, 203, 2, 38, 208, 97, 44, 65, 207, 78, 197, 145, 185, 174, 222, 106, 215, 230, 1], -[1, 20, 143, 33, 146, 93, 61, 192, 242, 214, 168, 19, 123, 147, 113, 204, 225, 131, 50, 229, 211, 108, 104, 24, 223, 91, 21, 163, 176, 179, 239, 154, 253, 177, 199, 125, 187, 142, 13, 3, 60, 172, 99, 181, 22, 183, 62, 212, 128, 247, 57, 112, 184, 82, 98, 161, 136, 150, 173, 119, 67, 55, 72, 155, 16, 63, 232, 14, 23, 203, 205, 245, 17, 83, 118, 47, 169, 39, 9, 180, 2, 40, 29, 66, 35, 186, 122, 127, 227, 171, 79, 38, 246, 37, 226, 151, 193, 5, 100, 201, 165, 216, 208, 48, 189, 182, 42, 69, 95, 101, 221, 51, 249, 97, 141, 250, 117, 27, 26, 6, 120, 87, 198, 105, 44, 109, 124, 167, 256, 237, 114, 224, 111, 164, 196, 65, 15, 43, 89, 238, 134, 110, 144, 53, 32, 126, 207, 28, 46, 149, 153, 233, 34, 166, 236, 94, 81, 78, 18, 103, 4, 80, 58, 132, 70, 115, 244, 254, 197, 85, 158, 76, 235, 74, 195, 45, 129, 10, 200, 145, 73, 175, 159, 96, 121, 107, 84, 138, 190, 202, 185, 102, 241, 194, 25, 243, 234, 54, 52, 12, 240, 174, 139, 210, 88, 218, 248, 77, 255, 217, 228, 191, 222, 71, 135, 130, 30, 86, 178, 219, 11, 220, 31, 106, 64, 252, 157, 56, 92, 41, 49, 209, 68, 75, 215, 188, 162, 156, 36, 206, 8, 160, 116, 7, 140, 230, 231, 251, 137, 170, 59, 152, 213, 148, 133, 90, 1], -[1, 21, 184, 9, 189, 114, 81, 159, 255, 215, 146, 239, 136, 29, 95, 196, 4, 84, 222, 36, 242, 199, 67, 122, 249, 89, 70, 185, 30, 116, 123, 13, 16, 79, 117, 144, 197, 25, 11, 231, 225, 99, 23, 226, 120, 207, 235, 52, 64, 59, 211, 62, 17, 100, 44, 153, 129, 139, 92, 133, 223, 57, 169, 208, 256, 236, 73, 248, 68, 143, 176, 98, 2, 42, 111, 18, 121, 228, 162, 61, 253, 173, 35, 221, 15, 58, 190, 135, 8, 168, 187, 72, 227, 141, 134, 244, 241, 178, 140, 113, 60, 232, 246, 26, 32, 158, 234, 31, 137, 50, 22, 205, 193, 198, 46, 195, 240, 157, 213, 104, 128, 118, 165, 124, 34, 200, 88, 49, 1, 21, 184, 9, 189, 114, 81, 159, 255, 215, 146, 239, 136, 29, 95, 196, 4, 84, 222, 36, 242, 199, 67, 122, 249, 89, 70, 185, 30, 116, 123, 13, 16, 79, 117, 144, 197, 25, 11, 231, 225, 99, 23, 226, 120, 207, 235, 52, 64, 59, 211, 62, 17, 100, 44, 153, 129, 139, 92, 133, 223, 57, 169, 208, 256, 236, 73, 248, 68, 143, 176, 98, 2, 42, 111, 18, 121, 228, 162, 61, 253, 173, 35, 221, 15, 58, 190, 135, 8, 168, 187, 72, 227, 141, 134, 244, 241, 178, 140, 113, 60, 232, 246, 26, 32, 158, 234, 31, 137, 50, 22, 205, 193, 198, 46, 195, 240, 157, 213, 104, 128, 118, 165, 124, 34, 200, 88, 49, 1], -[1, 22, 227, 111, 129, 11, 242, 184, 193, 134, 121, 92, 225, 67, 189, 46, 241, 162, 223, 23, 249, 81, 240, 140, 253, 169, 120, 70, 255, 213, 60, 35, 256, 235, 30, 146, 128, 246, 15, 73, 64, 123, 136, 165, 32, 190, 68, 211, 16, 95, 34, 234, 8, 176, 17, 117, 4, 88, 137, 187, 2, 44, 197, 222, 1, 22, 227, 111, 129, 11, 242, 184, 193, 134, 121, 92, 225, 67, 189, 46, 241, 162, 223, 23, 249, 81, 240, 140, 253, 169, 120, 70, 255, 213, 60, 35, 256, 235, 30, 146, 128, 246, 15, 73, 64, 123, 136, 165, 32, 190, 68, 211, 16, 95, 34, 234, 8, 176, 17, 117, 4, 88, 137, 187, 2, 44, 197, 222, 1, 22, 227, 111, 129, 11, 242, 184, 193, 134, 121, 92, 225, 67, 189, 46, 241, 162, 223, 23, 249, 81, 240, 140, 253, 169, 120, 70, 255, 213, 60, 35, 256, 235, 30, 146, 128, 246, 15, 73, 64, 123, 136, 165, 32, 190, 68, 211, 16, 95, 34, 234, 8, 176, 17, 117, 4, 88, 137, 187, 2, 44, 197, 222, 1, 22, 227, 111, 129, 11, 242, 184, 193, 134, 121, 92, 225, 67, 189, 46, 241, 162, 223, 23, 249, 81, 240, 140, 253, 169, 120, 70, 255, 213, 60, 35, 256, 235, 30, 146, 128, 246, 15, 73, 64, 123, 136, 165, 32, 190, 68, 211, 16, 95, 34, 234, 8, 176, 17, 117, 4, 88, 137, 187, 2, 44, 197, 222, 1], -[1, 23, 15, 88, 225, 35, 34, 11, 253, 165, 197, 162, 128, 117, 121, 213, 16, 111, 240, 123, 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, 137, 67, 256, 234, 242, 169, 32, 222, 223, 246, 4, 92, 60, 95, 129, 140, 136, 44, 241, 146, 17, 134, 255, 211, 227, 81, 64, 187, 189, 235, 8, 184, 120, 190, 1, 23, 15, 88, 225, 35, 34, 11, 253, 165, 197, 162, 128, 117, 121, 213, 16, 111, 240, 123, 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, 137, 67, 256, 234, 242, 169, 32, 222, 223, 246, 4, 92, 60, 95, 129, 140, 136, 44, 241, 146, 17, 134, 255, 211, 227, 81, 64, 187, 189, 235, 8, 184, 120, 190, 1, 23, 15, 88, 225, 35, 34, 11, 253, 165, 197, 162, 128, 117, 121, 213, 16, 111, 240, 123, 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, 137, 67, 256, 234, 242, 169, 32, 222, 223, 246, 4, 92, 60, 95, 129, 140, 136, 44, 241, 146, 17, 134, 255, 211, 227, 81, 64, 187, 189, 235, 8, 184, 120, 190, 1, 23, 15, 88, 225, 35, 34, 11, 253, 165, 197, 162, 128, 117, 121, 213, 16, 111, 240, 123, 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, 137, 67, 256, 234, 242, 169, 32, 222, 223, 246, 4, 92, 60, 95, 129, 140, 136, 44, 241, 146, 17, 134, 255, 211, 227, 81, 64, 187, 189, 235, 8, 184, 120, 190, 1], -[1, 24, 62, 203, 246, 250, 89, 80, 121, 77, 49, 148, 211, 181, 232, 171, 249, 65, 18, 175, 88, 56, 59, 131, 60, 155, 122, 101, 111, 94, 200, 174, 64, 251, 113, 142, 67, 66, 42, 237, 34, 45, 52, 220, 140, 19, 199, 150, 2, 48, 124, 149, 235, 243, 178, 160, 242, 154, 98, 39, 165, 105, 207, 85, 241, 130, 36, 93, 176, 112, 118, 5, 120, 53, 244, 202, 222, 188, 143, 91, 128, 245, 226, 27, 134, 132, 84, 217, 68, 90, 104, 183, 23, 38, 141, 43, 4, 96, 248, 41, 213, 229, 99, 63, 227, 51, 196, 78, 73, 210, 157, 170, 225, 3, 72, 186, 95, 224, 236, 10, 240, 106, 231, 147, 187, 119, 29, 182, 256, 233, 195, 54, 11, 7, 168, 177, 136, 180, 208, 109, 46, 76, 25, 86, 8, 192, 239, 82, 169, 201, 198, 126, 197, 102, 135, 156, 146, 163, 57, 83, 193, 6, 144, 115, 190, 191, 215, 20, 223, 212, 205, 37, 117, 238, 58, 107, 255, 209, 133, 108, 22, 14, 79, 97, 15, 103, 159, 218, 92, 152, 50, 172, 16, 127, 221, 164, 81, 145, 139, 252, 137, 204, 13, 55, 35, 69, 114, 166, 129, 12, 31, 230, 123, 125, 173, 40, 189, 167, 153, 74, 234, 219, 116, 214, 253, 161, 9, 216, 44, 28, 158, 194, 30, 206, 61, 179, 184, 47, 100, 87, 32, 254, 185, 71, 162, 33, 21, 247, 17, 151, 26, 110, 70, 138, 228, 75, 1], -[1, 25, 111, 205, 242, 139, 134, 9, 225, 228, 46, 122, 223, 178, 81, 226, 253, 157, 70, 208, 60, 215, 235, 221, 128, 116, 73, 26, 136, 59, 190, 124, 16, 143, 234, 196, 17, 168, 88, 144, 2, 50, 222, 153, 227, 21, 11, 18, 193, 199, 92, 244, 189, 99, 162, 195, 249, 57, 140, 159, 120, 173, 213, 185, 256, 232, 146, 52, 15, 118, 123, 248, 32, 29, 211, 135, 34, 79, 176, 31, 4, 100, 187, 49, 197, 42, 22, 36, 129, 141, 184, 231, 121, 198, 67, 133, 241, 114, 23, 61, 240, 89, 169, 113, 255, 207, 35, 104, 30, 236, 246, 239, 64, 58, 165, 13, 68, 158, 95, 62, 8, 200, 117, 98, 137, 84, 44, 72, 1, 25, 111, 205, 242, 139, 134, 9, 225, 228, 46, 122, 223, 178, 81, 226, 253, 157, 70, 208, 60, 215, 235, 221, 128, 116, 73, 26, 136, 59, 190, 124, 16, 143, 234, 196, 17, 168, 88, 144, 2, 50, 222, 153, 227, 21, 11, 18, 193, 199, 92, 244, 189, 99, 162, 195, 249, 57, 140, 159, 120, 173, 213, 185, 256, 232, 146, 52, 15, 118, 123, 248, 32, 29, 211, 135, 34, 79, 176, 31, 4, 100, 187, 49, 197, 42, 22, 36, 129, 141, 184, 231, 121, 198, 67, 133, 241, 114, 23, 61, 240, 89, 169, 113, 255, 207, 35, 104, 30, 236, 246, 239, 64, 58, 165, 13, 68, 158, 95, 62, 8, 200, 117, 98, 137, 84, 44, 72, 1], -[1, 26, 162, 100, 30, 9, 234, 173, 129, 13, 81, 50, 15, 133, 117, 215, 193, 135, 169, 25, 136, 195, 187, 236, 225, 196, 213, 141, 68, 226, 222, 118, 241, 98, 235, 199, 34, 113, 111, 59, 249, 49, 246, 228, 17, 185, 184, 158, 253, 153, 123, 114, 137, 221, 92, 79, 255, 205, 190, 57, 197, 239, 46, 168, 256, 231, 95, 157, 227, 248, 23, 84, 128, 244, 176, 207, 242, 124, 140, 42, 64, 122, 88, 232, 121, 62, 70, 21, 32, 61, 44, 116, 189, 31, 35, 139, 16, 159, 22, 58, 223, 144, 146, 198, 8, 208, 11, 29, 240, 72, 73, 99, 4, 104, 134, 143, 120, 36, 165, 178, 2, 52, 67, 200, 60, 18, 211, 89, 1, 26, 162, 100, 30, 9, 234, 173, 129, 13, 81, 50, 15, 133, 117, 215, 193, 135, 169, 25, 136, 195, 187, 236, 225, 196, 213, 141, 68, 226, 222, 118, 241, 98, 235, 199, 34, 113, 111, 59, 249, 49, 246, 228, 17, 185, 184, 158, 253, 153, 123, 114, 137, 221, 92, 79, 255, 205, 190, 57, 197, 239, 46, 168, 256, 231, 95, 157, 227, 248, 23, 84, 128, 244, 176, 207, 242, 124, 140, 42, 64, 122, 88, 232, 121, 62, 70, 21, 32, 61, 44, 116, 189, 31, 35, 139, 16, 159, 22, 58, 223, 144, 146, 198, 8, 208, 11, 29, 240, 72, 73, 99, 4, 104, 134, 143, 120, 36, 165, 178, 2, 52, 67, 200, 60, 18, 211, 89, 1], -[1, 27, 215, 151, 222, 83, 185, 112, 197, 179, 207, 192, 44, 160, 208, 219, 2, 54, 173, 45, 187, 166, 113, 224, 137, 101, 157, 127, 88, 63, 159, 181, 4, 108, 89, 90, 117, 75, 226, 191, 17, 202, 57, 254, 176, 126, 61, 105, 8, 216, 178, 180, 234, 150, 195, 125, 34, 147, 114, 251, 95, 252, 122, 210, 16, 175, 99, 103, 211, 43, 133, 250, 68, 37, 228, 245, 190, 247, 244, 163, 32, 93, 198, 206, 165, 86, 9, 243, 136, 74, 199, 233, 123, 237, 231, 69, 64, 186, 139, 155, 73, 172, 18, 229, 15, 148, 141, 209, 246, 217, 205, 138, 128, 115, 21, 53, 146, 87, 36, 201, 30, 39, 25, 161, 235, 177, 153, 19, 256, 230, 42, 106, 35, 174, 72, 145, 60, 78, 50, 65, 213, 97, 49, 38, 255, 203, 84, 212, 70, 91, 144, 33, 120, 156, 100, 130, 169, 194, 98, 76, 253, 149, 168, 167, 140, 182, 31, 66, 240, 55, 200, 3, 81, 131, 196, 152, 249, 41, 79, 77, 23, 107, 62, 132, 223, 110, 143, 6, 162, 5, 135, 47, 241, 82, 158, 154, 46, 214, 124, 7, 189, 220, 29, 12, 67, 10, 13, 94, 225, 164, 59, 51, 92, 171, 248, 14, 121, 183, 58, 24, 134, 20, 26, 188, 193, 71, 118, 102, 184, 85, 239, 28, 242, 109, 116, 48, 11, 40, 52, 119, 129, 142, 236, 204, 111, 170, 221, 56, 227, 218, 232, 96, 22, 80, 104, 238, 1], -[1, 28, 13, 107, 169, 106, 141, 93, 34, 181, 185, 40, 92, 6, 168, 78, 128, 243, 122, 75, 44, 204, 58, 82, 240, 38, 36, 237, 211, 254, 173, 218, 193, 7, 196, 91, 235, 155, 228, 216, 137, 238, 239, 10, 23, 130, 42, 148, 32, 125, 159, 83, 11, 51, 143, 149, 60, 138, 9, 252, 117, 192, 236, 183, 241, 66, 49, 87, 123, 103, 57, 54, 227, 188, 124, 131, 70, 161, 139, 37, 8, 224, 104, 85, 67, 77, 100, 230, 15, 163, 195, 63, 222, 48, 59, 110, 253, 145, 205, 86, 95, 90, 207, 142, 121, 47, 31, 97, 146, 233, 99, 202, 2, 56, 26, 214, 81, 212, 25, 186, 68, 105, 113, 80, 184, 12, 79, 156, 256, 229, 244, 150, 88, 151, 116, 164, 223, 76, 72, 217, 165, 251, 89, 179, 129, 14, 135, 182, 213, 53, 199, 175, 17, 219, 221, 20, 46, 3, 84, 39, 64, 250, 61, 166, 22, 102, 29, 41, 120, 19, 18, 247, 234, 127, 215, 109, 225, 132, 98, 174, 246, 206, 114, 108, 197, 119, 248, 5, 140, 65, 21, 74, 16, 191, 208, 170, 134, 154, 200, 203, 30, 69, 133, 126, 187, 96, 118, 220, 249, 33, 153, 172, 190, 180, 157, 27, 242, 94, 62, 194, 35, 209, 198, 147, 4, 112, 52, 171, 162, 167, 50, 115, 136, 210, 226, 160, 111, 24, 158, 55, 255, 201, 231, 43, 176, 45, 232, 71, 189, 152, 144, 177, 73, 245, 178, 101, 1], -[1, 29, 70, 231, 17, 236, 162, 72, 32, 157, 184, 196, 30, 99, 44, 248, 253, 141, 234, 104, 189, 84, 123, 226, 129, 143, 35, 244, 137, 118, 81, 36, 16, 207, 92, 98, 15, 178, 22, 124, 255, 199, 117, 52, 223, 42, 190, 113, 193, 200, 146, 122, 197, 59, 169, 18, 8, 232, 46, 49, 136, 89, 11, 62, 256, 228, 187, 26, 240, 21, 95, 185, 225, 100, 73, 61, 227, 158, 213, 9, 4, 116, 23, 153, 68, 173, 134, 31, 128, 114, 222, 13, 120, 139, 176, 221, 241, 50, 165, 159, 242, 79, 235, 133, 2, 58, 140, 205, 34, 215, 67, 144, 64, 57, 111, 135, 60, 198, 88, 239, 249, 25, 211, 208, 121, 168, 246, 195, 1, 29, 70, 231, 17, 236, 162, 72, 32, 157, 184, 196, 30, 99, 44, 248, 253, 141, 234, 104, 189, 84, 123, 226, 129, 143, 35, 244, 137, 118, 81, 36, 16, 207, 92, 98, 15, 178, 22, 124, 255, 199, 117, 52, 223, 42, 190, 113, 193, 200, 146, 122, 197, 59, 169, 18, 8, 232, 46, 49, 136, 89, 11, 62, 256, 228, 187, 26, 240, 21, 95, 185, 225, 100, 73, 61, 227, 158, 213, 9, 4, 116, 23, 153, 68, 173, 134, 31, 128, 114, 222, 13, 120, 139, 176, 221, 241, 50, 165, 159, 242, 79, 235, 133, 2, 58, 140, 205, 34, 215, 67, 144, 64, 57, 111, 135, 60, 198, 88, 239, 249, 25, 211, 208, 121, 168, 246, 195, 1], -[1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1], -[1, 31, 190, 236, 120, 122, 184, 50, 8, 248, 235, 89, 189, 205, 187, 143, 64, 185, 81, 198, 227, 98, 211, 116, 255, 195, 134, 42, 17, 13, 146, 157, 241, 18, 44, 79, 136, 104, 140, 228, 129, 144, 95, 118, 60, 61, 92, 25, 4, 124, 246, 173, 223, 231, 222, 200, 32, 221, 169, 99, 242, 49, 234, 58, 256, 226, 67, 21, 137, 135, 73, 207, 249, 9, 22, 168, 68, 52, 70, 114, 193, 72, 176, 59, 30, 159, 46, 141, 2, 62, 123, 215, 240, 244, 111, 100, 16, 239, 213, 178, 121, 153, 117, 29, 128, 113, 162, 139, 197, 196, 165, 232, 253, 133, 11, 84, 34, 26, 35, 57, 225, 36, 88, 158, 15, 208, 23, 199, 1, 31, 190, 236, 120, 122, 184, 50, 8, 248, 235, 89, 189, 205, 187, 143, 64, 185, 81, 198, 227, 98, 211, 116, 255, 195, 134, 42, 17, 13, 146, 157, 241, 18, 44, 79, 136, 104, 140, 228, 129, 144, 95, 118, 60, 61, 92, 25, 4, 124, 246, 173, 223, 231, 222, 200, 32, 221, 169, 99, 242, 49, 234, 58, 256, 226, 67, 21, 137, 135, 73, 207, 249, 9, 22, 168, 68, 52, 70, 114, 193, 72, 176, 59, 30, 159, 46, 141, 2, 62, 123, 215, 240, 244, 111, 100, 16, 239, 213, 178, 121, 153, 117, 29, 128, 113, 162, 139, 197, 196, 165, 232, 253, 133, 11, 84, 34, 26, 35, 57, 225, 36, 88, 158, 15, 208, 23, 199, 1], -[1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1], -[1, 33, 61, 214, 123, 204, 50, 108, 223, 163, 239, 177, 187, 3, 99, 183, 128, 112, 98, 150, 67, 155, 232, 203, 17, 47, 9, 40, 35, 127, 79, 37, 193, 201, 208, 182, 95, 51, 141, 27, 120, 105, 124, 237, 111, 65, 89, 110, 32, 28, 153, 166, 81, 103, 58, 115, 197, 76, 195, 10, 73, 96, 84, 202, 241, 243, 52, 174, 88, 77, 228, 71, 30, 219, 31, 252, 92, 209, 215, 156, 8, 7, 231, 170, 213, 90, 143, 93, 242, 19, 113, 131, 211, 24, 21, 179, 253, 125, 13, 172, 22, 212, 57, 82, 136, 119, 72, 63, 23, 245, 118, 39, 2, 66, 122, 171, 246, 151, 100, 216, 189, 69, 221, 97, 117, 6, 198, 109, 256, 224, 196, 43, 134, 53, 207, 149, 34, 94, 18, 80, 70, 254, 158, 74, 129, 145, 159, 107, 190, 102, 25, 54, 240, 210, 248, 217, 222, 130, 178, 220, 64, 56, 49, 75, 162, 206, 116, 230, 137, 152, 133, 20, 146, 192, 168, 147, 225, 229, 104, 91, 176, 154, 199, 142, 60, 181, 62, 247, 184, 161, 173, 55, 16, 14, 205, 83, 169, 180, 29, 186, 227, 38, 226, 5, 165, 48, 42, 101, 249, 250, 26, 87, 44, 167, 114, 164, 15, 238, 144, 126, 46, 233, 236, 78, 4, 132, 244, 85, 235, 45, 200, 175, 121, 138, 185, 194, 234, 12, 139, 218, 255, 191, 135, 86, 11, 106, 157, 41, 68, 188, 36, 160, 140, 251, 59, 148, 1], -[1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1], -[1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, 81, 8, 23, 34, 162, 16, 46, 68, 67, 32, 92, 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, 256, 222, 60, 44, 255, 187, 120, 88, 253, 117, 240, 176, 249, 234, 223, 95, 241, 211, 189, 190, 225, 165, 121, 123, 193, 73, 242, 246, 129, 146, 227, 235, 1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, 81, 8, 23, 34, 162, 16, 46, 68, 67, 32, 92, 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, 256, 222, 60, 44, 255, 187, 120, 88, 253, 117, 240, 176, 249, 234, 223, 95, 241, 211, 189, 190, 225, 165, 121, 123, 193, 73, 242, 246, 129, 146, 227, 235, 1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, 81, 8, 23, 34, 162, 16, 46, 68, 67, 32, 92, 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, 256, 222, 60, 44, 255, 187, 120, 88, 253, 117, 240, 176, 249, 234, 223, 95, 241, 211, 189, 190, 225, 165, 121, 123, 193, 73, 242, 246, 129, 146, 227, 235, 1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, 81, 8, 23, 34, 162, 16, 46, 68, 67, 32, 92, 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, 256, 222, 60, 44, 255, 187, 120, 88, 253, 117, 240, 176, 249, 234, 223, 95, 241, 211, 189, 190, 225, 165, 121, 123, 193, 73, 242, 246, 129, 146, 227, 235, 1], -[1, 36, 11, 139, 121, 244, 46, 114, 249, 226, 169, 173, 60, 104, 146, 116, 64, 248, 190, 158, 34, 196, 117, 100, 2, 72, 22, 21, 242, 231, 92, 228, 241, 195, 81, 89, 120, 208, 35, 232, 128, 239, 123, 59, 68, 135, 234, 200, 4, 144, 44, 42, 227, 205, 184, 199, 225, 133, 162, 178, 240, 159, 70, 207, 256, 221, 246, 118, 136, 13, 211, 143, 8, 31, 88, 84, 197, 153, 111, 141, 193, 9, 67, 99, 223, 61, 140, 157, 255, 185, 235, 236, 15, 26, 165, 29, 16, 62, 176, 168, 137, 49, 222, 25, 129, 18, 134, 198, 189, 122, 23, 57, 253, 113, 213, 215, 30, 52, 73, 58, 32, 124, 95, 79, 17, 98, 187, 50, 1, 36, 11, 139, 121, 244, 46, 114, 249, 226, 169, 173, 60, 104, 146, 116, 64, 248, 190, 158, 34, 196, 117, 100, 2, 72, 22, 21, 242, 231, 92, 228, 241, 195, 81, 89, 120, 208, 35, 232, 128, 239, 123, 59, 68, 135, 234, 200, 4, 144, 44, 42, 227, 205, 184, 199, 225, 133, 162, 178, 240, 159, 70, 207, 256, 221, 246, 118, 136, 13, 211, 143, 8, 31, 88, 84, 197, 153, 111, 141, 193, 9, 67, 99, 223, 61, 140, 157, 255, 185, 235, 236, 15, 26, 165, 29, 16, 62, 176, 168, 137, 49, 222, 25, 129, 18, 134, 198, 189, 122, 23, 57, 253, 113, 213, 215, 30, 52, 73, 58, 32, 124, 95, 79, 17, 98, 187, 50, 1], -[1, 37, 84, 24, 117, 217, 62, 238, 68, 203, 58, 90, 246, 107, 104, 250, 255, 183, 89, 209, 23, 80, 133, 38, 121, 108, 141, 77, 22, 43, 49, 14, 4, 148, 79, 96, 211, 97, 248, 181, 15, 41, 232, 103, 213, 171, 159, 229, 249, 218, 99, 65, 92, 63, 18, 152, 227, 175, 50, 51, 88, 172, 196, 56, 16, 78, 59, 127, 73, 131, 221, 210, 60, 164, 157, 155, 81, 170, 122, 145, 225, 101, 139, 3, 111, 252, 72, 94, 137, 186, 200, 204, 95, 174, 13, 224, 64, 55, 236, 251, 35, 10, 113, 69, 240, 142, 114, 106, 67, 166, 231, 66, 129, 147, 42, 12, 187, 237, 31, 119, 34, 230, 29, 45, 123, 182, 52, 125, 256, 220, 173, 233, 140, 40, 195, 19, 189, 54, 199, 167, 11, 150, 153, 7, 2, 74, 168, 48, 234, 177, 124, 219, 136, 149, 116, 180, 235, 214, 208, 243, 253, 109, 178, 161, 46, 160, 9, 76, 242, 216, 25, 154, 44, 86, 98, 28, 8, 39, 158, 192, 165, 194, 239, 105, 30, 82, 207, 206, 169, 85, 61, 201, 241, 179, 198, 130, 184, 126, 36, 47, 197, 93, 100, 102, 176, 87, 135, 112, 32, 156, 118, 254, 146, 5, 185, 163, 120, 71, 57, 53, 162, 83, 244, 33, 193, 202, 21, 6, 222, 247, 144, 188, 17, 115, 143, 151, 190, 91, 26, 191, 128, 110, 215, 245, 70, 20, 226, 138, 223, 27, 228, 212, 134, 75, 205, 132, 1], -[1, 38, 159, 131, 95, 12, 199, 109, 30, 112, 144, 75, 23, 103, 59, 186, 129, 19, 208, 194, 176, 6, 228, 183, 15, 56, 72, 166, 140, 180, 158, 93, 193, 138, 104, 97, 88, 3, 114, 220, 136, 28, 36, 83, 70, 90, 79, 175, 225, 69, 52, 177, 44, 130, 57, 110, 68, 14, 18, 170, 35, 45, 168, 216, 241, 163, 26, 217, 22, 65, 157, 55, 34, 7, 9, 85, 146, 151, 84, 108, 249, 210, 13, 237, 11, 161, 207, 156, 17, 132, 133, 171, 73, 204, 42, 54, 253, 105, 135, 247, 134, 209, 232, 78, 137, 66, 195, 214, 165, 102, 21, 27, 255, 181, 196, 252, 67, 233, 116, 39, 197, 33, 226, 107, 211, 51, 139, 142, 256, 219, 98, 126, 162, 245, 58, 148, 227, 145, 113, 182, 234, 154, 198, 71, 128, 238, 49, 63, 81, 251, 29, 74, 242, 201, 185, 91, 117, 77, 99, 164, 64, 119, 153, 160, 169, 254, 143, 37, 121, 229, 221, 174, 187, 167, 178, 82, 32, 188, 205, 80, 213, 127, 200, 147, 189, 243, 239, 87, 222, 212, 89, 41, 16, 94, 231, 40, 235, 192, 100, 202, 223, 250, 248, 172, 111, 106, 173, 149, 8, 47, 244, 20, 246, 96, 50, 101, 240, 125, 124, 86, 184, 53, 215, 203, 4, 152, 122, 10, 123, 48, 25, 179, 120, 191, 62, 43, 92, 155, 236, 230, 2, 76, 61, 5, 190, 24, 141, 218, 60, 224, 31, 150, 46, 206, 118, 115, 1], -[1, 39, 236, 209, 184, 237, 248, 163, 189, 175, 143, 180, 81, 75, 98, 224, 255, 179, 42, 96, 146, 40, 18, 188, 136, 164, 228, 154, 95, 107, 61, 66, 4, 156, 173, 65, 222, 177, 221, 138, 242, 186, 58, 206, 67, 43, 135, 125, 249, 202, 168, 127, 70, 160, 72, 238, 30, 142, 141, 102, 123, 171, 244, 7, 16, 110, 178, 3, 117, 194, 113, 38, 197, 230, 232, 53, 11, 172, 26, 243, 225, 37, 158, 251, 23, 126, 31, 181, 120, 54, 50, 151, 235, 170, 205, 28, 64, 183, 198, 12, 211, 5, 195, 152, 17, 149, 157, 212, 44, 174, 104, 201, 129, 148, 118, 233, 92, 247, 124, 210, 223, 216, 200, 90, 169, 166, 49, 112, 256, 218, 21, 48, 73, 20, 9, 94, 68, 82, 114, 77, 176, 182, 159, 33, 2, 78, 215, 161, 111, 217, 239, 69, 121, 93, 29, 103, 162, 150, 196, 191, 253, 101, 84, 192, 35, 80, 36, 119, 15, 71, 199, 51, 190, 214, 122, 132, 8, 55, 89, 130, 187, 97, 185, 19, 227, 115, 116, 155, 134, 86, 13, 250, 241, 147, 79, 254, 140, 63, 144, 219, 60, 27, 25, 204, 246, 85, 231, 14, 32, 220, 99, 6, 234, 131, 226, 76, 137, 203, 207, 106, 22, 87, 52, 229, 193, 74, 59, 245, 46, 252, 62, 105, 240, 108, 100, 45, 213, 83, 153, 56, 128, 109, 139, 24, 165, 10, 133, 47, 34, 41, 57, 167, 88, 91, 208, 145, 1], -[1, 40, 58, 7, 23, 149, 49, 161, 15, 86, 99, 105, 88, 179, 221, 102, 225, 5, 200, 33, 35, 115, 231, 245, 34, 75, 173, 238, 11, 183, 124, 77, 253, 97, 25, 229, 165, 175, 61, 127, 197, 170, 118, 94, 162, 55, 144, 106, 128, 237, 228, 125, 117, 54, 104, 48, 121, 214, 79, 76, 213, 39, 18, 206, 16, 126, 157, 112, 111, 71, 13, 6, 240, 91, 42, 138, 123, 37, 195, 90, 2, 80, 116, 14, 46, 41, 98, 65, 30, 172, 198, 210, 176, 101, 185, 204, 193, 10, 143, 66, 70, 230, 205, 233, 68, 150, 89, 219, 22, 109, 248, 154, 249, 194, 50, 201, 73, 93, 122, 254, 137, 83, 236, 188, 67, 110, 31, 212, 256, 217, 199, 250, 234, 108, 208, 96, 242, 171, 158, 152, 169, 78, 36, 155, 32, 252, 57, 224, 222, 142, 26, 12, 223, 182, 84, 19, 246, 74, 133, 180, 4, 160, 232, 28, 92, 82, 196, 130, 60, 87, 139, 163, 95, 202, 113, 151, 129, 20, 29, 132, 140, 203, 153, 209, 136, 43, 178, 181, 44, 218, 239, 51, 241, 131, 100, 145, 146, 186, 244, 251, 17, 166, 215, 119, 134, 220, 62, 167, 255, 177, 141, 243, 211, 216, 159, 192, 227, 85, 59, 47, 81, 156, 72, 53, 64, 247, 114, 191, 187, 27, 52, 24, 189, 107, 168, 38, 235, 148, 9, 103, 8, 63, 207, 56, 184, 164, 135, 3, 120, 174, 21, 69, 190, 147, 226, 45, 1], -[1, 41, 139, 45, 46, 87, 226, 14, 60, 147, 116, 130, 190, 80, 196, 69, 2, 82, 21, 90, 92, 174, 195, 28, 120, 37, 232, 3, 123, 160, 135, 138, 4, 164, 42, 180, 184, 91, 133, 56, 240, 74, 207, 6, 246, 63, 13, 19, 8, 71, 84, 103, 111, 182, 9, 112, 223, 148, 157, 12, 235, 126, 26, 38, 16, 142, 168, 206, 222, 107, 18, 224, 189, 39, 57, 24, 213, 252, 52, 76, 32, 27, 79, 155, 187, 214, 36, 191, 121, 78, 114, 48, 169, 247, 104, 152, 64, 54, 158, 53, 117, 171, 72, 125, 242, 156, 228, 96, 81, 237, 208, 47, 128, 108, 59, 106, 234, 85, 144, 250, 227, 55, 199, 192, 162, 217, 159, 94, 256, 216, 118, 212, 211, 170, 31, 243, 197, 110, 141, 127, 67, 177, 61, 188, 255, 175, 236, 167, 165, 83, 62, 229, 137, 220, 25, 254, 134, 97, 122, 119, 253, 93, 215, 77, 73, 166, 124, 201, 17, 183, 50, 251, 11, 194, 244, 238, 249, 186, 173, 154, 146, 75, 248, 145, 34, 109, 100, 245, 22, 131, 231, 219, 241, 115, 89, 51, 35, 150, 239, 33, 68, 218, 200, 233, 44, 5, 205, 181, 225, 230, 178, 102, 70, 43, 221, 66, 136, 179, 143, 209, 88, 10, 153, 105, 193, 203, 99, 204, 140, 86, 185, 132, 15, 101, 29, 161, 176, 20, 49, 210, 129, 149, 198, 151, 23, 172, 113, 7, 30, 202, 58, 65, 95, 40, 98, 163, 1], -[1, 42, 222, 72, 197, 50, 44, 49, 2, 84, 187, 144, 137, 100, 88, 98, 4, 168, 117, 31, 17, 200, 176, 196, 8, 79, 234, 62, 34, 143, 95, 135, 16, 158, 211, 124, 68, 29, 190, 13, 32, 59, 165, 248, 136, 58, 123, 26, 64, 118, 73, 239, 15, 116, 246, 52, 128, 236, 146, 221, 30, 232, 235, 104, 256, 215, 35, 185, 60, 207, 213, 208, 255, 173, 70, 113, 120, 157, 169, 159, 253, 89, 140, 226, 240, 57, 81, 61, 249, 178, 23, 195, 223, 114, 162, 122, 241, 99, 46, 133, 189, 228, 67, 244, 225, 198, 92, 9, 121, 199, 134, 231, 193, 139, 184, 18, 242, 141, 11, 205, 129, 21, 111, 36, 227, 25, 22, 153, 1, 42, 222, 72, 197, 50, 44, 49, 2, 84, 187, 144, 137, 100, 88, 98, 4, 168, 117, 31, 17, 200, 176, 196, 8, 79, 234, 62, 34, 143, 95, 135, 16, 158, 211, 124, 68, 29, 190, 13, 32, 59, 165, 248, 136, 58, 123, 26, 64, 118, 73, 239, 15, 116, 246, 52, 128, 236, 146, 221, 30, 232, 235, 104, 256, 215, 35, 185, 60, 207, 213, 208, 255, 173, 70, 113, 120, 157, 169, 159, 253, 89, 140, 226, 240, 57, 81, 61, 249, 178, 23, 195, 223, 114, 162, 122, 241, 99, 46, 133, 189, 228, 67, 244, 225, 198, 92, 9, 121, 199, 134, 231, 193, 139, 184, 18, 242, 141, 11, 205, 129, 21, 111, 36, 227, 25, 22, 153, 1], -[1, 43, 50, 94, 187, 74, 98, 102, 17, 217, 79, 56, 95, 230, 124, 192, 32, 91, 58, 181, 73, 55, 52, 180, 30, 5, 215, 250, 213, 164, 113, 233, 253, 85, 57, 138, 23, 218, 122, 106, 189, 160, 198, 33, 134, 108, 18, 3, 129, 150, 25, 47, 222, 37, 49, 51, 137, 237, 168, 28, 176, 115, 62, 96, 16, 174, 29, 219, 165, 156, 26, 90, 15, 131, 236, 125, 235, 82, 185, 245, 255, 171, 157, 69, 140, 109, 61, 53, 223, 80, 99, 145, 67, 54, 9, 130, 193, 75, 141, 152, 111, 147, 153, 154, 197, 247, 84, 14, 88, 186, 31, 48, 8, 87, 143, 238, 211, 78, 13, 45, 136, 194, 118, 191, 246, 41, 221, 251, 256, 214, 207, 163, 70, 183, 159, 155, 240, 40, 178, 201, 162, 27, 133, 65, 225, 166, 199, 76, 184, 202, 205, 77, 227, 252, 42, 7, 44, 93, 144, 24, 4, 172, 200, 119, 234, 39, 135, 151, 68, 97, 59, 224, 123, 149, 239, 254, 128, 107, 232, 210, 35, 220, 208, 206, 120, 20, 89, 229, 81, 142, 195, 161, 241, 83, 228, 38, 92, 101, 231, 167, 242, 126, 21, 132, 22, 175, 72, 12, 2, 86, 100, 188, 117, 148, 196, 204, 34, 177, 158, 112, 190, 203, 248, 127, 64, 182, 116, 105, 146, 110, 104, 103, 60, 10, 173, 243, 169, 71, 226, 209, 249, 170, 114, 19, 46, 179, 244, 212, 121, 63, 139, 66, 11, 216, 36, 6, 1], -[1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, 35, 255, 169, 240, 23, 241, 67, 121, 184, 129, 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, 146, 256, 213, 120, 140, 249, 162, 189, 92, 193, 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, 73, 128, 235, 60, 70, 253, 81, 223, 46, 225, 134, 242, 111, 1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, 35, 255, 169, 240, 23, 241, 67, 121, 184, 129, 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, 146, 256, 213, 120, 140, 249, 162, 189, 92, 193, 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, 73, 128, 235, 60, 70, 253, 81, 223, 46, 225, 134, 242, 111, 1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, 35, 255, 169, 240, 23, 241, 67, 121, 184, 129, 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, 146, 256, 213, 120, 140, 249, 162, 189, 92, 193, 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, 73, 128, 235, 60, 70, 253, 81, 223, 46, 225, 134, 242, 111, 1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, 35, 255, 169, 240, 23, 241, 67, 121, 184, 129, 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, 146, 256, 213, 120, 140, 249, 162, 189, 92, 193, 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, 73, 128, 235, 60, 70, 253, 81, 223, 46, 225, 134, 242, 111, 1], -[1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, 256, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40, 1], -[1, 46, 60, 190, 2, 92, 120, 123, 4, 184, 240, 246, 8, 111, 223, 235, 16, 222, 189, 213, 32, 187, 121, 169, 64, 117, 242, 81, 128, 234, 227, 162, 256, 211, 197, 67, 255, 165, 137, 134, 253, 73, 17, 11, 249, 146, 34, 22, 241, 35, 68, 44, 225, 70, 136, 88, 193, 140, 15, 176, 129, 23, 30, 95, 1, 46, 60, 190, 2, 92, 120, 123, 4, 184, 240, 246, 8, 111, 223, 235, 16, 222, 189, 213, 32, 187, 121, 169, 64, 117, 242, 81, 128, 234, 227, 162, 256, 211, 197, 67, 255, 165, 137, 134, 253, 73, 17, 11, 249, 146, 34, 22, 241, 35, 68, 44, 225, 70, 136, 88, 193, 140, 15, 176, 129, 23, 30, 95, 1, 46, 60, 190, 2, 92, 120, 123, 4, 184, 240, 246, 8, 111, 223, 235, 16, 222, 189, 213, 32, 187, 121, 169, 64, 117, 242, 81, 128, 234, 227, 162, 256, 211, 197, 67, 255, 165, 137, 134, 253, 73, 17, 11, 249, 146, 34, 22, 241, 35, 68, 44, 225, 70, 136, 88, 193, 140, 15, 176, 129, 23, 30, 95, 1, 46, 60, 190, 2, 92, 120, 123, 4, 184, 240, 246, 8, 111, 223, 235, 16, 222, 189, 213, 32, 187, 121, 169, 64, 117, 242, 81, 128, 234, 227, 162, 256, 211, 197, 67, 255, 165, 137, 134, 253, 73, 17, 11, 249, 146, 34, 22, 241, 35, 68, 44, 225, 70, 136, 88, 193, 140, 15, 176, 129, 23, 30, 95, 1], -[1, 47, 153, 252, 22, 6, 25, 147, 227, 132, 36, 150, 111, 77, 21, 216, 129, 152, 205, 126, 11, 3, 141, 202, 242, 66, 18, 75, 184, 167, 139, 108, 193, 76, 231, 63, 134, 130, 199, 101, 121, 33, 9, 166, 92, 212, 198, 54, 225, 38, 244, 160, 67, 65, 228, 179, 189, 145, 133, 83, 46, 106, 99, 27, 241, 19, 122, 80, 162, 161, 114, 218, 223, 201, 195, 170, 23, 53, 178, 142, 249, 138, 61, 40, 81, 209, 57, 109, 240, 229, 226, 85, 140, 155, 89, 71, 253, 69, 159, 20, 169, 233, 157, 183, 120, 243, 113, 171, 70, 206, 173, 164, 255, 163, 208, 10, 213, 245, 207, 220, 60, 250, 185, 214, 35, 103, 215, 82, 256, 210, 104, 5, 235, 251, 232, 110, 30, 125, 221, 107, 146, 180, 236, 41, 128, 105, 52, 131, 246, 254, 116, 55, 15, 191, 239, 182, 73, 90, 118, 149, 64, 181, 26, 194, 123, 127, 58, 156, 136, 224, 248, 91, 165, 45, 59, 203, 32, 219, 13, 97, 190, 192, 29, 78, 68, 112, 124, 174, 211, 151, 158, 230, 16, 238, 135, 177, 95, 96, 143, 39, 34, 56, 62, 87, 234, 204, 79, 115, 8, 119, 196, 217, 176, 48, 200, 148, 17, 28, 31, 172, 117, 102, 168, 186, 4, 188, 98, 237, 88, 24, 100, 74, 137, 14, 144, 86, 187, 51, 84, 93, 2, 94, 49, 247, 44, 12, 50, 37, 197, 7, 72, 43, 222, 154, 42, 175, 1], -[1, 48, 248, 82, 81, 33, 42, 217, 136, 103, 61, 101, 222, 119, 58, 214, 249, 130, 72, 115, 123, 250, 178, 63, 197, 204, 26, 220, 23, 76, 50, 87, 64, 245, 195, 108, 44, 56, 118, 10, 223, 167, 49, 39, 73, 163, 114, 75, 2, 96, 239, 164, 162, 66, 84, 177, 15, 206, 122, 202, 187, 238, 116, 171, 241, 3, 144, 230, 246, 243, 99, 126, 137, 151, 52, 183, 46, 152, 100, 174, 128, 233, 133, 216, 88, 112, 236, 20, 189, 77, 98, 78, 146, 69, 228, 150, 4, 192, 221, 71, 67, 132, 168, 97, 30, 155, 244, 147, 117, 219, 232, 85, 225, 6, 31, 203, 235, 229, 198, 252, 17, 45, 104, 109, 92, 47, 200, 91, 256, 209, 9, 175, 176, 224, 215, 40, 121, 154, 196, 156, 35, 138, 199, 43, 8, 127, 185, 142, 134, 7, 79, 194, 60, 53, 231, 37, 234, 181, 207, 170, 193, 12, 62, 149, 213, 201, 139, 247, 34, 90, 208, 218, 184, 94, 143, 182, 255, 161, 18, 93, 95, 191, 173, 80, 242, 51, 135, 55, 70, 19, 141, 86, 16, 254, 113, 27, 11, 14, 158, 131, 120, 106, 205, 74, 211, 105, 157, 83, 129, 24, 124, 41, 169, 145, 21, 237, 68, 180, 159, 179, 111, 188, 29, 107, 253, 65, 36, 186, 190, 125, 89, 160, 227, 102, 13, 110, 140, 38, 25, 172, 32, 251, 226, 54, 22, 28, 59, 5, 240, 212, 153, 148, 165, 210, 57, 166, 1], -[1, 49, 88, 200, 34, 124, 165, 118, 128, 104, 213, 157, 240, 195, 46, 198, 193, 205, 22, 50, 137, 31, 234, 158, 32, 26, 246, 232, 60, 113, 140, 178, 241, 244, 134, 141, 227, 72, 187, 168, 8, 135, 190, 58, 15, 221, 35, 173, 253, 61, 162, 228, 121, 18, 111, 42, 2, 98, 176, 143, 68, 248, 73, 236, 256, 208, 169, 57, 223, 133, 92, 139, 129, 153, 44, 100, 17, 62, 211, 59, 64, 52, 235, 207, 120, 226, 23, 99, 225, 231, 11, 25, 197, 144, 117, 79, 16, 13, 123, 116, 30, 185, 70, 89, 249, 122, 67, 199, 242, 36, 222, 84, 4, 196, 95, 29, 136, 239, 146, 215, 255, 159, 81, 114, 189, 9, 184, 21, 1, 49, 88, 200, 34, 124, 165, 118, 128, 104, 213, 157, 240, 195, 46, 198, 193, 205, 22, 50, 137, 31, 234, 158, 32, 26, 246, 232, 60, 113, 140, 178, 241, 244, 134, 141, 227, 72, 187, 168, 8, 135, 190, 58, 15, 221, 35, 173, 253, 61, 162, 228, 121, 18, 111, 42, 2, 98, 176, 143, 68, 248, 73, 236, 256, 208, 169, 57, 223, 133, 92, 139, 129, 153, 44, 100, 17, 62, 211, 59, 64, 52, 235, 207, 120, 226, 23, 99, 225, 231, 11, 25, 197, 144, 117, 79, 16, 13, 123, 116, 30, 185, 70, 89, 249, 122, 67, 199, 242, 36, 222, 84, 4, 196, 95, 29, 136, 239, 146, 215, 255, 159, 81, 114, 189, 9, 184, 21, 1], -[1, 50, 187, 98, 17, 79, 95, 124, 32, 58, 73, 52, 30, 215, 213, 113, 253, 57, 23, 122, 189, 198, 134, 18, 129, 25, 222, 49, 137, 168, 176, 62, 16, 29, 165, 26, 15, 236, 235, 185, 255, 157, 140, 61, 223, 99, 67, 9, 193, 141, 111, 153, 197, 84, 88, 31, 8, 143, 211, 13, 136, 118, 246, 221, 256, 207, 70, 159, 240, 178, 162, 133, 225, 199, 184, 205, 227, 42, 44, 144, 4, 200, 234, 135, 68, 59, 123, 239, 128, 232, 35, 208, 120, 89, 81, 195, 241, 228, 92, 231, 242, 21, 22, 72, 2, 100, 117, 196, 34, 158, 190, 248, 64, 116, 146, 104, 60, 173, 169, 226, 249, 114, 46, 244, 121, 139, 11, 36, 1, 50, 187, 98, 17, 79, 95, 124, 32, 58, 73, 52, 30, 215, 213, 113, 253, 57, 23, 122, 189, 198, 134, 18, 129, 25, 222, 49, 137, 168, 176, 62, 16, 29, 165, 26, 15, 236, 235, 185, 255, 157, 140, 61, 223, 99, 67, 9, 193, 141, 111, 153, 197, 84, 88, 31, 8, 143, 211, 13, 136, 118, 246, 221, 256, 207, 70, 159, 240, 178, 162, 133, 225, 199, 184, 205, 227, 42, 44, 144, 4, 200, 234, 135, 68, 59, 123, 239, 128, 232, 35, 208, 120, 89, 81, 195, 241, 228, 92, 231, 242, 21, 22, 72, 2, 100, 117, 196, 34, 158, 190, 248, 64, 116, 146, 104, 60, 173, 169, 226, 249, 114, 46, 244, 121, 139, 11, 36, 1], -[1, 51, 31, 39, 190, 181, 236, 214, 120, 209, 122, 54, 184, 132, 50, 237, 8, 151, 248, 55, 235, 163, 89, 170, 189, 130, 205, 175, 187, 28, 143, 97, 64, 180, 185, 183, 81, 19, 198, 75, 227, 12, 98, 115, 211, 224, 116, 5, 255, 155, 195, 179, 134, 152, 42, 86, 17, 96, 13, 149, 146, 250, 157, 40, 241, 212, 18, 147, 44, 188, 79, 174, 136, 254, 104, 164, 140, 201, 228, 63, 129, 154, 144, 148, 95, 219, 118, 107, 60, 233, 61, 27, 92, 66, 25, 247, 4, 204, 124, 156, 246, 210, 173, 85, 223, 65, 231, 216, 222, 14, 200, 177, 32, 90, 221, 220, 169, 138, 99, 166, 242, 6, 49, 186, 234, 112, 58, 131, 256, 206, 226, 218, 67, 76, 21, 43, 137, 48, 135, 203, 73, 125, 207, 20, 249, 106, 9, 202, 22, 94, 168, 87, 68, 127, 52, 82, 70, 229, 114, 160, 193, 77, 72, 74, 176, 238, 59, 182, 30, 245, 159, 142, 46, 33, 141, 252, 2, 102, 62, 78, 123, 105, 215, 171, 240, 161, 244, 108, 111, 7, 100, 217, 16, 45, 239, 110, 213, 69, 178, 83, 121, 3, 153, 93, 117, 56, 29, 194, 128, 103, 113, 109, 162, 38, 139, 150, 197, 24, 196, 230, 165, 191, 232, 10, 253, 53, 133, 101, 11, 47, 84, 172, 34, 192, 26, 41, 35, 243, 57, 80, 225, 167, 36, 37, 88, 119, 158, 91, 15, 251, 208, 71, 23, 145, 199, 126, 1], -[1, 52, 134, 29, 223, 31, 70, 42, 128, 231, 190, 114, 17, 113, 222, 236, 193, 13, 162, 200, 120, 72, 146, 139, 32, 122, 176, 157, 197, 221, 184, 59, 241, 196, 169, 50, 30, 18, 165, 99, 8, 159, 44, 232, 242, 248, 46, 79, 253, 49, 235, 141, 136, 133, 234, 89, 2, 104, 11, 58, 189, 62, 140, 84, 256, 205, 123, 228, 34, 226, 187, 215, 129, 26, 67, 143, 240, 144, 35, 21, 64, 244, 95, 57, 137, 185, 111, 118, 225, 135, 81, 100, 60, 36, 73, 198, 16, 61, 88, 207, 227, 239, 92, 158, 249, 98, 213, 25, 15, 9, 211, 178, 4, 208, 22, 116, 121, 124, 23, 168, 255, 153, 246, 199, 68, 195, 117, 173, 1, 52, 134, 29, 223, 31, 70, 42, 128, 231, 190, 114, 17, 113, 222, 236, 193, 13, 162, 200, 120, 72, 146, 139, 32, 122, 176, 157, 197, 221, 184, 59, 241, 196, 169, 50, 30, 18, 165, 99, 8, 159, 44, 232, 242, 248, 46, 79, 253, 49, 235, 141, 136, 133, 234, 89, 2, 104, 11, 58, 189, 62, 140, 84, 256, 205, 123, 228, 34, 226, 187, 215, 129, 26, 67, 143, 240, 144, 35, 21, 64, 244, 95, 57, 137, 185, 111, 118, 225, 135, 81, 100, 60, 36, 73, 198, 16, 61, 88, 207, 227, 239, 92, 158, 249, 98, 213, 25, 15, 9, 211, 178, 4, 208, 22, 116, 121, 124, 23, 168, 255, 153, 246, 199, 68, 195, 117, 173, 1], -[1, 53, 239, 74, 67, 210, 79, 75, 120, 192, 153, 142, 73, 14, 228, 5, 8, 167, 113, 78, 22, 138, 118, 86, 189, 251, 196, 108, 70, 112, 25, 40, 64, 51, 133, 110, 176, 76, 173, 174, 227, 209, 26, 93, 46, 125, 200, 63, 255, 151, 36, 109, 123, 94, 99, 107, 17, 130, 208, 230, 111, 229, 58, 247, 241, 180, 31, 101, 213, 238, 21, 85, 136, 12, 122, 41, 117, 33, 207, 177, 129, 155, 248, 37, 162, 105, 168, 166, 60, 96, 205, 71, 165, 7, 114, 131, 4, 212, 185, 39, 11, 69, 59, 43, 223, 254, 98, 54, 35, 56, 141, 20, 32, 154, 195, 55, 88, 38, 215, 87, 242, 233, 13, 175, 23, 191, 100, 160, 256, 204, 18, 183, 190, 47, 178, 182, 137, 65, 104, 115, 184, 243, 29, 252, 249, 90, 144, 179, 235, 119, 139, 171, 68, 6, 61, 149, 187, 145, 232, 217, 193, 206, 124, 147, 81, 181, 84, 83, 30, 48, 231, 164, 211, 132, 57, 194, 2, 106, 221, 148, 134, 163, 158, 150, 240, 127, 49, 27, 146, 28, 199, 10, 16, 77, 226, 156, 44, 19, 236, 172, 121, 245, 135, 216, 140, 224, 50, 80, 128, 102, 9, 220, 95, 152, 89, 91, 197, 161, 52, 186, 92, 250, 143, 126, 253, 45, 72, 218, 246, 188, 198, 214, 34, 3, 159, 203, 222, 201, 116, 237, 225, 103, 62, 202, 169, 219, 42, 170, 15, 24, 244, 82, 234, 66, 157, 97, 1], -[1, 54, 89, 180, 211, 86, 18, 201, 60, 156, 200, 6, 67, 20, 52, 238, 2, 108, 178, 103, 165, 172, 36, 145, 120, 55, 143, 12, 134, 40, 104, 219, 4, 216, 99, 206, 73, 87, 72, 33, 240, 110, 29, 24, 11, 80, 208, 181, 8, 175, 198, 155, 146, 174, 144, 66, 223, 220, 58, 48, 22, 160, 159, 105, 16, 93, 139, 53, 35, 91, 31, 132, 189, 183, 116, 96, 44, 63, 61, 210, 32, 186, 21, 106, 70, 182, 62, 7, 121, 109, 232, 192, 88, 126, 122, 163, 64, 115, 42, 212, 140, 107, 124, 14, 242, 218, 207, 127, 176, 252, 244, 69, 128, 230, 84, 167, 23, 214, 248, 28, 227, 179, 157, 254, 95, 247, 231, 138, 256, 203, 168, 77, 46, 171, 239, 56, 197, 101, 57, 251, 190, 237, 205, 19, 255, 149, 79, 154, 92, 85, 221, 112, 137, 202, 114, 245, 123, 217, 153, 38, 253, 41, 158, 51, 184, 170, 185, 224, 17, 147, 228, 233, 246, 177, 49, 76, 249, 82, 59, 102, 111, 83, 113, 191, 34, 37, 199, 209, 235, 97, 98, 152, 241, 164, 118, 204, 222, 166, 226, 125, 68, 74, 141, 161, 213, 194, 196, 47, 225, 71, 236, 151, 187, 75, 195, 250, 136, 148, 25, 65, 169, 131, 135, 94, 193, 142, 215, 45, 117, 150, 133, 243, 15, 39, 50, 130, 81, 5, 13, 188, 129, 27, 173, 90, 234, 43, 9, 229, 30, 78, 100, 3, 162, 10, 26, 119, 1], -[1, 55, 198, 96, 140, 247, 221, 76, 68, 142, 100, 103, 11, 91, 122, 28, 255, 147, 118, 65, 234, 20, 72, 105, 121, 230, 57, 51, 235, 75, 13, 201, 4, 220, 21, 127, 46, 217, 113, 47, 15, 54, 143, 155, 44, 107, 231, 112, 249, 74, 215, 3, 165, 80, 31, 163, 227, 149, 228, 204, 169, 43, 52, 33, 16, 109, 84, 251, 184, 97, 195, 188, 60, 216, 58, 106, 176, 171, 153, 191, 225, 39, 89, 12, 146, 63, 124, 138, 137, 82, 141, 45, 162, 172, 208, 132, 64, 179, 79, 233, 222, 131, 9, 238, 240, 93, 232, 167, 190, 170, 98, 250, 129, 156, 99, 48, 70, 252, 239, 38, 34, 71, 50, 180, 134, 174, 61, 14, 256, 202, 59, 161, 117, 10, 36, 181, 189, 115, 157, 154, 246, 166, 135, 229, 2, 110, 139, 192, 23, 237, 185, 152, 136, 27, 200, 206, 22, 182, 244, 56, 253, 37, 236, 130, 211, 40, 144, 210, 242, 203, 114, 102, 213, 150, 26, 145, 8, 183, 42, 254, 92, 177, 226, 94, 30, 108, 29, 53, 88, 214, 205, 224, 241, 148, 173, 6, 73, 160, 62, 69, 197, 41, 199, 151, 81, 86, 104, 66, 32, 218, 168, 245, 111, 194, 133, 119, 120, 175, 116, 212, 95, 85, 49, 125, 193, 78, 178, 24, 35, 126, 248, 19, 17, 164, 25, 90, 67, 87, 159, 7, 128, 101, 158, 209, 187, 5, 18, 219, 223, 186, 207, 77, 123, 83, 196, 243, 1], -[1, 56, 52, 85, 134, 51, 29, 82, 223, 152, 31, 194, 70, 65, 42, 39, 128, 229, 231, 86, 190, 103, 114, 216, 17, 181, 113, 160, 222, 96, 236, 109, 193, 14, 13, 214, 162, 77, 200, 149, 120, 38, 72, 177, 146, 209, 139, 74, 32, 250, 122, 150, 176, 90, 157, 54, 197, 238, 221, 40, 184, 24, 59, 220, 241, 132, 196, 182, 169, 212, 50, 230, 30, 138, 18, 237, 165, 245, 99, 147, 8, 191, 159, 166, 44, 151, 232, 142, 242, 188, 248, 10, 46, 6, 79, 55, 253, 33, 49, 174, 235, 53, 141, 186, 136, 163, 133, 252, 234, 254, 89, 101, 2, 112, 104, 170, 11, 102, 58, 164, 189, 47, 62, 131, 140, 130, 84, 78, 256, 201, 205, 172, 123, 206, 228, 175, 34, 105, 226, 63, 187, 192, 215, 218, 129, 28, 26, 171, 67, 154, 143, 41, 240, 76, 144, 97, 35, 161, 21, 148, 64, 243, 244, 43, 95, 180, 57, 108, 137, 219, 185, 80, 111, 48, 118, 183, 225, 7, 135, 107, 81, 167, 100, 203, 60, 19, 36, 217, 73, 233, 198, 37, 16, 125, 61, 75, 88, 45, 207, 27, 227, 119, 239, 20, 92, 12, 158, 110, 249, 66, 98, 91, 213, 106, 25, 115, 15, 69, 9, 247, 211, 251, 178, 202, 4, 224, 208, 83, 22, 204, 116, 71, 121, 94, 124, 5, 23, 3, 168, 156, 255, 145, 153, 87, 246, 155, 199, 93, 68, 210, 195, 126, 117, 127, 173, 179, 1], -[1, 57, 165, 153, 240, 59, 22, 226, 32, 25, 140, 13, 227, 89, 190, 36, 253, 29, 111, 159, 68, 21, 169, 124, 129, 157, 211, 205, 120, 158, 11, 113, 16, 141, 70, 135, 242, 173, 95, 18, 255, 143, 184, 208, 34, 139, 213, 62, 193, 207, 234, 231, 60, 79, 134, 185, 8, 199, 35, 196, 121, 215, 176, 9, 256, 200, 92, 104, 17, 198, 235, 31, 225, 232, 117, 244, 30, 168, 67, 221, 4, 228, 146, 98, 189, 236, 88, 133, 128, 100, 46, 52, 137, 99, 246, 144, 241, 116, 187, 122, 15, 84, 162, 239, 2, 114, 73, 49, 223, 118, 44, 195, 64, 50, 23, 26, 197, 178, 123, 72, 249, 58, 222, 61, 136, 42, 81, 248, 1, 57, 165, 153, 240, 59, 22, 226, 32, 25, 140, 13, 227, 89, 190, 36, 253, 29, 111, 159, 68, 21, 169, 124, 129, 157, 211, 205, 120, 158, 11, 113, 16, 141, 70, 135, 242, 173, 95, 18, 255, 143, 184, 208, 34, 139, 213, 62, 193, 207, 234, 231, 60, 79, 134, 185, 8, 199, 35, 196, 121, 215, 176, 9, 256, 200, 92, 104, 17, 198, 235, 31, 225, 232, 117, 244, 30, 168, 67, 221, 4, 228, 146, 98, 189, 236, 88, 133, 128, 100, 46, 52, 137, 99, 246, 144, 241, 116, 187, 122, 15, 84, 162, 239, 2, 114, 73, 49, 223, 118, 44, 195, 64, 50, 23, 26, 197, 178, 123, 72, 249, 58, 222, 61, 136, 42, 81, 248, 1], -[1, 58, 23, 49, 15, 99, 88, 221, 225, 200, 35, 231, 34, 173, 11, 124, 253, 25, 165, 61, 197, 118, 162, 144, 128, 228, 117, 104, 121, 79, 213, 18, 16, 157, 111, 13, 240, 42, 123, 195, 2, 116, 46, 98, 30, 198, 176, 185, 193, 143, 70, 205, 68, 89, 22, 248, 249, 50, 73, 122, 137, 236, 67, 31, 256, 199, 234, 208, 242, 158, 169, 36, 32, 57, 222, 26, 223, 84, 246, 133, 4, 232, 92, 196, 60, 139, 95, 113, 129, 29, 140, 153, 136, 178, 44, 239, 241, 100, 146, 244, 17, 215, 134, 62, 255, 141, 211, 159, 227, 59, 81, 72, 64, 114, 187, 52, 189, 168, 235, 9, 8, 207, 184, 135, 120, 21, 190, 226, 1, 58, 23, 49, 15, 99, 88, 221, 225, 200, 35, 231, 34, 173, 11, 124, 253, 25, 165, 61, 197, 118, 162, 144, 128, 228, 117, 104, 121, 79, 213, 18, 16, 157, 111, 13, 240, 42, 123, 195, 2, 116, 46, 98, 30, 198, 176, 185, 193, 143, 70, 205, 68, 89, 22, 248, 249, 50, 73, 122, 137, 236, 67, 31, 256, 199, 234, 208, 242, 158, 169, 36, 32, 57, 222, 26, 223, 84, 246, 133, 4, 232, 92, 196, 60, 139, 95, 113, 129, 29, 140, 153, 136, 178, 44, 239, 241, 100, 146, 244, 17, 215, 134, 62, 255, 141, 211, 159, 227, 59, 81, 72, 64, 114, 187, 52, 189, 168, 235, 9, 8, 207, 184, 135, 120, 21, 190, 226, 1], -[1, 59, 140, 36, 68, 157, 11, 135, 255, 139, 234, 185, 121, 200, 235, 244, 4, 236, 46, 144, 15, 114, 44, 26, 249, 42, 165, 226, 227, 29, 169, 205, 16, 173, 184, 62, 60, 199, 176, 104, 225, 168, 146, 133, 137, 116, 162, 49, 64, 178, 222, 248, 240, 25, 190, 159, 129, 158, 70, 18, 34, 207, 134, 196, 256, 198, 117, 221, 189, 100, 246, 122, 2, 118, 23, 72, 136, 57, 22, 13, 253, 21, 211, 113, 242, 143, 213, 231, 8, 215, 92, 31, 30, 228, 88, 52, 241, 84, 73, 195, 197, 58, 81, 153, 32, 89, 111, 124, 120, 141, 95, 208, 193, 79, 35, 9, 17, 232, 67, 98, 128, 99, 187, 239, 223, 50, 123, 61, 1, 59, 140, 36, 68, 157, 11, 135, 255, 139, 234, 185, 121, 200, 235, 244, 4, 236, 46, 144, 15, 114, 44, 26, 249, 42, 165, 226, 227, 29, 169, 205, 16, 173, 184, 62, 60, 199, 176, 104, 225, 168, 146, 133, 137, 116, 162, 49, 64, 178, 222, 248, 240, 25, 190, 159, 129, 158, 70, 18, 34, 207, 134, 196, 256, 198, 117, 221, 189, 100, 246, 122, 2, 118, 23, 72, 136, 57, 22, 13, 253, 21, 211, 113, 242, 143, 213, 231, 8, 215, 92, 31, 30, 228, 88, 52, 241, 84, 73, 195, 197, 58, 81, 153, 32, 89, 111, 124, 120, 141, 95, 208, 193, 79, 35, 9, 17, 232, 67, 98, 128, 99, 187, 239, 223, 50, 123, 61, 1], -[1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1], -[1, 61, 123, 50, 223, 239, 187, 99, 128, 98, 67, 232, 17, 9, 35, 79, 193, 208, 95, 141, 120, 124, 111, 89, 32, 153, 81, 58, 197, 195, 73, 84, 241, 52, 88, 228, 30, 31, 92, 215, 8, 231, 213, 143, 242, 113, 211, 21, 253, 13, 22, 57, 136, 72, 23, 118, 2, 122, 246, 100, 189, 221, 117, 198, 256, 196, 134, 207, 34, 18, 70, 158, 129, 159, 190, 25, 240, 248, 222, 178, 64, 49, 162, 116, 137, 133, 146, 168, 225, 104, 176, 199, 60, 62, 184, 173, 16, 205, 169, 29, 227, 226, 165, 42, 249, 26, 44, 114, 15, 144, 46, 236, 4, 244, 235, 200, 121, 185, 234, 139, 255, 135, 11, 157, 68, 36, 140, 59, 1, 61, 123, 50, 223, 239, 187, 99, 128, 98, 67, 232, 17, 9, 35, 79, 193, 208, 95, 141, 120, 124, 111, 89, 32, 153, 81, 58, 197, 195, 73, 84, 241, 52, 88, 228, 30, 31, 92, 215, 8, 231, 213, 143, 242, 113, 211, 21, 253, 13, 22, 57, 136, 72, 23, 118, 2, 122, 246, 100, 189, 221, 117, 198, 256, 196, 134, 207, 34, 18, 70, 158, 129, 159, 190, 25, 240, 248, 222, 178, 64, 49, 162, 116, 137, 133, 146, 168, 225, 104, 176, 199, 60, 62, 184, 173, 16, 205, 169, 29, 227, 226, 165, 42, 249, 26, 44, 114, 15, 144, 46, 236, 4, 244, 235, 200, 121, 185, 234, 139, 255, 135, 11, 157, 68, 36, 140, 59, 1], -[1, 62, 246, 89, 121, 49, 211, 232, 249, 18, 88, 59, 60, 122, 111, 200, 64, 113, 67, 42, 34, 52, 140, 199, 2, 124, 235, 178, 242, 98, 165, 207, 241, 36, 176, 118, 120, 244, 222, 143, 128, 226, 134, 84, 68, 104, 23, 141, 4, 248, 213, 99, 227, 196, 73, 157, 225, 72, 95, 236, 240, 231, 187, 29, 256, 195, 11, 168, 136, 208, 46, 25, 8, 239, 169, 198, 197, 135, 146, 57, 193, 144, 190, 215, 223, 205, 117, 58, 255, 133, 22, 79, 15, 159, 92, 50, 16, 221, 81, 139, 137, 13, 35, 114, 129, 31, 123, 173, 189, 153, 234, 116, 253, 9, 44, 158, 30, 61, 184, 100, 32, 185, 162, 21, 17, 26, 70, 228, 1, 62, 246, 89, 121, 49, 211, 232, 249, 18, 88, 59, 60, 122, 111, 200, 64, 113, 67, 42, 34, 52, 140, 199, 2, 124, 235, 178, 242, 98, 165, 207, 241, 36, 176, 118, 120, 244, 222, 143, 128, 226, 134, 84, 68, 104, 23, 141, 4, 248, 213, 99, 227, 196, 73, 157, 225, 72, 95, 236, 240, 231, 187, 29, 256, 195, 11, 168, 136, 208, 46, 25, 8, 239, 169, 198, 197, 135, 146, 57, 193, 144, 190, 215, 223, 205, 117, 58, 255, 133, 22, 79, 15, 159, 92, 50, 16, 221, 81, 139, 137, 13, 35, 114, 129, 31, 123, 173, 189, 153, 234, 116, 253, 9, 44, 158, 30, 61, 184, 100, 32, 185, 162, 21, 17, 26, 70, 228, 1], -[1, 63, 114, 243, 146, 203, 196, 12, 242, 83, 89, 210, 123, 39, 144, 77, 225, 40, 207, 191, 211, 186, 153, 130, 223, 171, 236, 219, 176, 37, 18, 106, 253, 5, 58, 56, 187, 216, 244, 209, 60, 182, 158, 188, 22, 101, 195, 206, 128, 97, 200, 7, 184, 27, 159, 251, 136, 87, 84, 152, 67, 109, 185, 90, 16, 237, 25, 33, 23, 164, 52, 192, 17, 43, 139, 19, 169, 110, 248, 204, 2, 126, 228, 229, 35, 149, 135, 24, 227, 166, 178, 163, 246, 78, 31, 154, 193, 80, 157, 125, 165, 115, 49, 3, 189, 85, 215, 181, 95, 74, 36, 212, 249, 10, 116, 112, 117, 175, 231, 161, 120, 107, 59, 119, 44, 202, 133, 155, 256, 194, 143, 14, 111, 54, 61, 245, 15, 174, 168, 47, 134, 218, 113, 180, 32, 217, 50, 66, 46, 71, 104, 127, 34, 86, 21, 38, 81, 220, 239, 151, 4, 252, 199, 201, 70, 41, 13, 48, 197, 75, 99, 69, 235, 156, 62, 51, 129, 160, 57, 250, 73, 230, 98, 6, 121, 170, 173, 105, 190, 148, 72, 167, 241, 20, 232, 224, 234, 93, 205, 65, 240, 214, 118, 238, 88, 147, 9, 53, 255, 131, 29, 28, 222, 108, 122, 233, 30, 91, 79, 94, 11, 179, 226, 103, 64, 177, 100, 132, 92, 142, 208, 254, 68, 172, 42, 76, 162, 183, 221, 45, 8, 247, 141, 145, 140, 82, 26, 96, 137, 150, 198, 138, 213, 55, 124, 102, 1], -[1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1], -[1, 65, 113, 149, 176, 132, 99, 10, 136, 102, 205, 218, 35, 219, 100, 75, 249, 251, 124, 93, 134, 229, 236, 177, 197, 212, 159, 55, 234, 47, 228, 171, 64, 48, 36, 27, 213, 224, 168, 126, 223, 103, 13, 74, 184, 138, 232, 174, 2, 130, 226, 41, 95, 7, 198, 20, 15, 204, 153, 179, 70, 181, 200, 150, 241, 245, 248, 186, 11, 201, 215, 97, 137, 167, 61, 110, 211, 94, 199, 85, 128, 96, 72, 54, 169, 191, 79, 252, 189, 206, 26, 148, 111, 19, 207, 91, 4, 3, 195, 82, 190, 14, 139, 40, 30, 151, 49, 101, 140, 105, 143, 43, 225, 233, 239, 115, 22, 145, 173, 194, 17, 77, 122, 220, 165, 188, 141, 170, 256, 192, 144, 108, 81, 125, 158, 247, 121, 155, 52, 39, 222, 38, 157, 182, 8, 6, 133, 164, 123, 28, 21, 80, 60, 45, 98, 202, 23, 210, 29, 86, 193, 209, 221, 230, 44, 33, 89, 131, 34, 154, 244, 183, 73, 119, 25, 83, 255, 127, 31, 216, 162, 250, 59, 237, 242, 53, 104, 78, 187, 76, 57, 107, 16, 12, 9, 71, 246, 56, 42, 160, 120, 90, 196, 147, 46, 163, 58, 172, 129, 161, 185, 203, 88, 66, 178, 5, 68, 51, 231, 109, 146, 238, 50, 166, 253, 254, 62, 175, 67, 243, 118, 217, 227, 106, 208, 156, 117, 152, 114, 214, 32, 24, 18, 142, 235, 112, 84, 63, 240, 180, 135, 37, 92, 69, 116, 87, 1], -[1, 66, 244, 170, 169, 103, 116, 203, 34, 188, 72, 126, 92, 161, 89, 220, 128, 224, 135, 172, 44, 77, 199, 27, 240, 163, 221, 194, 211, 48, 84, 147, 193, 145, 61, 171, 235, 90, 29, 115, 137, 47, 18, 160, 23, 233, 215, 55, 32, 56, 98, 43, 11, 212, 114, 71, 60, 105, 248, 177, 117, 12, 21, 101, 241, 229, 208, 107, 123, 151, 200, 93, 227, 76, 133, 40, 70, 251, 118, 78, 8, 14, 153, 75, 67, 53, 157, 82, 15, 219, 62, 237, 222, 3, 198, 218, 253, 250, 52, 91, 95, 102, 50, 216, 121, 19, 226, 10, 146, 127, 158, 148, 2, 132, 231, 83, 81, 206, 232, 149, 68, 119, 144, 252, 184, 65, 178, 183, 256, 191, 13, 87, 88, 154, 141, 54, 223, 69, 185, 131, 165, 96, 168, 37, 129, 33, 122, 85, 213, 180, 58, 230, 17, 94, 36, 63, 46, 209, 173, 110, 64, 112, 196, 86, 22, 167, 228, 142, 120, 210, 239, 97, 234, 24, 42, 202, 225, 201, 159, 214, 246, 45, 143, 186, 197, 152, 9, 80, 140, 245, 236, 156, 16, 28, 49, 150, 134, 106, 57, 164, 30, 181, 124, 217, 187, 6, 139, 179, 249, 243, 104, 182, 190, 204, 100, 175, 242, 38, 195, 20, 35, 254, 59, 39, 4, 7, 205, 166, 162, 155, 207, 41, 136, 238, 31, 247, 111, 130, 99, 109, 255, 125, 26, 174, 176, 51, 25, 108, 189, 138, 113, 5, 73, 192, 79, 74, 1], -[1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, 46, 255, 123, 17, 111, 241, 213, 136, 117, 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, 23, 256, 190, 137, 184, 249, 235, 68, 187, 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, 140, 128, 95, 197, 92, 253, 246, 34, 222, 225, 169, 15, 234, 1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, 46, 255, 123, 17, 111, 241, 213, 136, 117, 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, 23, 256, 190, 137, 184, 249, 235, 68, 187, 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, 140, 128, 95, 197, 92, 253, 246, 34, 222, 225, 169, 15, 234, 1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, 46, 255, 123, 17, 111, 241, 213, 136, 117, 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, 23, 256, 190, 137, 184, 249, 235, 68, 187, 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, 140, 128, 95, 197, 92, 253, 246, 34, 222, 225, 169, 15, 234, 1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, 46, 255, 123, 17, 111, 241, 213, 136, 117, 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, 23, 256, 190, 137, 184, 249, 235, 68, 187, 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, 140, 128, 95, 197, 92, 253, 246, 34, 222, 225, 169, 15, 234, 1], -[1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1], -[1, 69, 135, 63, 235, 24, 114, 156, 227, 243, 62, 166, 146, 51, 178, 203, 129, 163, 196, 160, 246, 12, 57, 78, 242, 250, 31, 83, 73, 154, 89, 230, 193, 210, 98, 80, 123, 6, 157, 39, 121, 125, 144, 170, 165, 77, 173, 115, 225, 105, 49, 40, 190, 3, 207, 148, 189, 191, 72, 85, 211, 167, 215, 186, 241, 181, 153, 20, 95, 130, 232, 74, 223, 224, 36, 171, 234, 212, 236, 93, 249, 219, 205, 10, 176, 65, 116, 37, 240, 112, 18, 214, 117, 106, 118, 175, 253, 238, 231, 5, 88, 161, 58, 147, 120, 56, 9, 107, 187, 53, 59, 216, 255, 119, 244, 131, 44, 209, 29, 202, 60, 28, 133, 182, 222, 155, 158, 108, 256, 188, 122, 194, 22, 233, 143, 101, 30, 14, 195, 91, 111, 206, 79, 54, 128, 94, 61, 97, 11, 245, 200, 179, 15, 7, 226, 174, 184, 103, 168, 27, 64, 47, 159, 177, 134, 251, 100, 218, 136, 132, 113, 87, 92, 180, 84, 142, 32, 152, 208, 217, 67, 254, 50, 109, 68, 66, 185, 172, 46, 90, 42, 71, 16, 76, 104, 237, 162, 127, 25, 183, 34, 33, 221, 86, 23, 45, 21, 164, 8, 38, 52, 247, 81, 192, 141, 220, 17, 145, 239, 43, 140, 151, 139, 82, 4, 19, 26, 252, 169, 96, 199, 110, 137, 201, 248, 150, 70, 204, 198, 41, 2, 138, 13, 126, 213, 48, 228, 55, 197, 229, 124, 75, 35, 102, 99, 149, 1], -[1, 70, 17, 162, 32, 184, 30, 44, 253, 234, 189, 123, 129, 35, 137, 81, 16, 92, 15, 22, 255, 117, 223, 190, 193, 146, 197, 169, 8, 46, 136, 11, 256, 187, 240, 95, 225, 73, 227, 213, 4, 23, 68, 134, 128, 222, 120, 176, 241, 165, 242, 235, 2, 140, 34, 67, 64, 111, 60, 88, 249, 211, 121, 246, 1, 70, 17, 162, 32, 184, 30, 44, 253, 234, 189, 123, 129, 35, 137, 81, 16, 92, 15, 22, 255, 117, 223, 190, 193, 146, 197, 169, 8, 46, 136, 11, 256, 187, 240, 95, 225, 73, 227, 213, 4, 23, 68, 134, 128, 222, 120, 176, 241, 165, 242, 235, 2, 140, 34, 67, 64, 111, 60, 88, 249, 211, 121, 246, 1, 70, 17, 162, 32, 184, 30, 44, 253, 234, 189, 123, 129, 35, 137, 81, 16, 92, 15, 22, 255, 117, 223, 190, 193, 146, 197, 169, 8, 46, 136, 11, 256, 187, 240, 95, 225, 73, 227, 213, 4, 23, 68, 134, 128, 222, 120, 176, 241, 165, 242, 235, 2, 140, 34, 67, 64, 111, 60, 88, 249, 211, 121, 246, 1, 70, 17, 162, 32, 184, 30, 44, 253, 234, 189, 123, 129, 35, 137, 81, 16, 92, 15, 22, 255, 117, 223, 190, 193, 146, 197, 169, 8, 46, 136, 11, 256, 187, 240, 95, 225, 73, 227, 213, 4, 23, 68, 134, 128, 222, 120, 176, 241, 165, 242, 235, 2, 140, 34, 67, 64, 111, 60, 88, 249, 211, 121, 246, 1], -[1, 71, 158, 167, 35, 172, 133, 191, 197, 109, 29, 3, 213, 217, 244, 105, 2, 142, 59, 77, 70, 87, 9, 125, 137, 218, 58, 6, 169, 177, 231, 210, 4, 27, 118, 154, 140, 174, 18, 250, 17, 179, 116, 12, 81, 97, 205, 163, 8, 54, 236, 51, 23, 91, 36, 243, 34, 101, 232, 24, 162, 194, 153, 69, 16, 108, 215, 102, 46, 182, 72, 229, 68, 202, 207, 48, 67, 131, 49, 138, 32, 216, 173, 204, 92, 107, 144, 201, 136, 147, 157, 96, 134, 5, 98, 19, 64, 175, 89, 151, 184, 214, 31, 145, 15, 37, 57, 192, 11, 10, 196, 38, 128, 93, 178, 45, 111, 171, 62, 33, 30, 74, 114, 127, 22, 20, 135, 76, 256, 186, 99, 90, 222, 85, 124, 66, 60, 148, 228, 254, 44, 40, 13, 152, 255, 115, 198, 180, 187, 170, 248, 132, 120, 39, 199, 251, 88, 80, 26, 47, 253, 230, 139, 103, 117, 83, 239, 7, 240, 78, 141, 245, 176, 160, 52, 94, 249, 203, 21, 206, 234, 166, 221, 14, 223, 156, 25, 233, 95, 63, 104, 188, 241, 149, 42, 155, 211, 75, 185, 28, 189, 55, 50, 209, 190, 126, 208, 119, 225, 41, 84, 53, 165, 150, 113, 56, 121, 110, 100, 161, 123, 252, 159, 238, 193, 82, 168, 106, 73, 43, 226, 112, 242, 220, 200, 65, 246, 247, 61, 219, 129, 164, 79, 212, 146, 86, 195, 224, 227, 183, 143, 130, 235, 237, 122, 181, 1], -[1, 72, 44, 84, 137, 98, 117, 200, 8, 62, 95, 158, 68, 13, 165, 58, 64, 239, 246, 236, 30, 104, 35, 207, 255, 113, 169, 89, 240, 61, 23, 114, 241, 133, 67, 198, 121, 231, 184, 141, 129, 36, 22, 42, 197, 49, 187, 100, 4, 31, 176, 79, 34, 135, 211, 29, 32, 248, 123, 118, 15, 52, 146, 232, 256, 185, 213, 173, 120, 159, 140, 57, 249, 195, 162, 99, 189, 244, 92, 199, 193, 18, 11, 21, 227, 153, 222, 50, 2, 144, 88, 168, 17, 196, 234, 143, 16, 124, 190, 59, 136, 26, 73, 116, 128, 221, 235, 215, 60, 208, 70, 157, 253, 226, 81, 178, 223, 122, 46, 228, 225, 9, 134, 139, 242, 205, 111, 25, 1, 72, 44, 84, 137, 98, 117, 200, 8, 62, 95, 158, 68, 13, 165, 58, 64, 239, 246, 236, 30, 104, 35, 207, 255, 113, 169, 89, 240, 61, 23, 114, 241, 133, 67, 198, 121, 231, 184, 141, 129, 36, 22, 42, 197, 49, 187, 100, 4, 31, 176, 79, 34, 135, 211, 29, 32, 248, 123, 118, 15, 52, 146, 232, 256, 185, 213, 173, 120, 159, 140, 57, 249, 195, 162, 99, 189, 244, 92, 199, 193, 18, 11, 21, 227, 153, 222, 50, 2, 144, 88, 168, 17, 196, 234, 143, 16, 124, 190, 59, 136, 26, 73, 116, 128, 221, 235, 215, 60, 208, 70, 157, 253, 226, 81, 178, 223, 122, 46, 228, 225, 9, 134, 139, 242, 205, 111, 25, 1], -[1, 73, 189, 176, 255, 111, 136, 162, 4, 35, 242, 190, 249, 187, 30, 134, 16, 140, 197, 246, 225, 234, 120, 22, 64, 46, 17, 213, 129, 165, 223, 88, 256, 184, 68, 81, 2, 146, 121, 95, 253, 222, 15, 67, 8, 70, 227, 123, 241, 117, 60, 11, 32, 23, 137, 235, 193, 211, 240, 44, 128, 92, 34, 169, 1, 73, 189, 176, 255, 111, 136, 162, 4, 35, 242, 190, 249, 187, 30, 134, 16, 140, 197, 246, 225, 234, 120, 22, 64, 46, 17, 213, 129, 165, 223, 88, 256, 184, 68, 81, 2, 146, 121, 95, 253, 222, 15, 67, 8, 70, 227, 123, 241, 117, 60, 11, 32, 23, 137, 235, 193, 211, 240, 44, 128, 92, 34, 169, 1, 73, 189, 176, 255, 111, 136, 162, 4, 35, 242, 190, 249, 187, 30, 134, 16, 140, 197, 246, 225, 234, 120, 22, 64, 46, 17, 213, 129, 165, 223, 88, 256, 184, 68, 81, 2, 146, 121, 95, 253, 222, 15, 67, 8, 70, 227, 123, 241, 117, 60, 11, 32, 23, 137, 235, 193, 211, 240, 44, 128, 92, 34, 169, 1, 73, 189, 176, 255, 111, 136, 162, 4, 35, 242, 190, 249, 187, 30, 134, 16, 140, 197, 246, 225, 234, 120, 22, 64, 46, 17, 213, 129, 165, 223, 88, 256, 184, 68, 81, 2, 146, 121, 95, 253, 222, 15, 67, 8, 70, 227, 123, 241, 117, 60, 11, 32, 23, 137, 235, 193, 211, 240, 44, 128, 92, 34, 169, 1], -[1, 74, 79, 192, 73, 5, 113, 138, 189, 108, 25, 51, 176, 174, 26, 125, 255, 109, 99, 130, 111, 247, 31, 238, 136, 41, 207, 155, 162, 166, 205, 7, 4, 39, 59, 254, 35, 20, 195, 38, 242, 175, 100, 204, 190, 182, 104, 243, 249, 179, 139, 6, 187, 217, 124, 181, 30, 164, 57, 106, 134, 150, 49, 28, 16, 156, 236, 245, 140, 80, 9, 152, 197, 186, 143, 45, 246, 214, 159, 201, 225, 202, 42, 24, 234, 97, 239, 210, 120, 142, 228, 167, 22, 86, 196, 112, 64, 110, 173, 209, 46, 63, 36, 94, 17, 230, 58, 180, 213, 85, 122, 33, 129, 37, 168, 96, 165, 131, 185, 69, 223, 54, 141, 154, 88, 87, 13, 191, 256, 183, 178, 65, 184, 252, 144, 119, 68, 149, 232, 206, 81, 83, 231, 132, 2, 148, 158, 127, 146, 10, 226, 19, 121, 216, 50, 102, 95, 91, 52, 250, 253, 218, 198, 3, 222, 237, 62, 219, 15, 82, 157, 53, 67, 75, 153, 14, 8, 78, 118, 251, 70, 40, 133, 76, 227, 93, 200, 151, 123, 107, 208, 229, 241, 101, 21, 12, 117, 177, 248, 105, 60, 71, 114, 212, 11, 43, 98, 56, 32, 55, 215, 233, 23, 160, 18, 47, 137, 115, 29, 90, 235, 171, 61, 145, 193, 147, 84, 48, 211, 194, 221, 163, 240, 27, 199, 77, 44, 172, 135, 224, 128, 220, 89, 161, 92, 126, 72, 188, 34, 203, 116, 103, 169, 170, 244, 66, 1], -[1, 75, 228, 138, 70, 110, 26, 151, 17, 247, 21, 33, 162, 71, 185, 254, 32, 87, 100, 47, 184, 179, 61, 206, 30, 194, 158, 28, 44, 216, 9, 161, 253, 214, 116, 219, 234, 74, 153, 167, 189, 40, 173, 125, 123, 230, 31, 12, 129, 166, 114, 69, 35, 55, 13, 204, 137, 252, 139, 145, 81, 164, 221, 127, 16, 172, 50, 152, 92, 218, 159, 103, 15, 97, 79, 14, 22, 108, 133, 209, 255, 107, 58, 238, 117, 37, 205, 212, 223, 20, 215, 191, 190, 115, 144, 6, 193, 83, 57, 163, 146, 156, 135, 102, 197, 126, 198, 201, 169, 82, 239, 192, 8, 86, 25, 76, 46, 109, 208, 180, 136, 177, 168, 7, 11, 54, 195, 233, 256, 182, 29, 119, 187, 147, 231, 106, 240, 10, 236, 224, 95, 186, 72, 3, 225, 170, 157, 210, 73, 78, 196, 51, 227, 63, 99, 229, 213, 41, 248, 96, 4, 43, 141, 38, 23, 183, 104, 90, 68, 217, 84, 132, 134, 27, 226, 245, 128, 91, 143, 188, 222, 202, 244, 53, 120, 5, 118, 112, 176, 93, 36, 130, 241, 85, 207, 105, 165, 39, 98, 154, 242, 160, 178, 243, 235, 149, 124, 48, 2, 150, 199, 19, 140, 220, 52, 45, 34, 237, 42, 66, 67, 142, 113, 251, 64, 174, 200, 94, 111, 101, 122, 155, 60, 131, 59, 56, 88, 175, 18, 65, 249, 171, 232, 181, 211, 148, 49, 77, 121, 80, 89, 250, 246, 203, 62, 24, 1], -[1, 76, 122, 20, 235, 127, 143, 74, 227, 33, 195, 171, 146, 45, 79, 93, 129, 38, 61, 10, 246, 192, 200, 37, 242, 145, 226, 214, 73, 151, 168, 175, 193, 19, 159, 5, 123, 96, 100, 147, 121, 201, 113, 107, 165, 204, 84, 216, 225, 138, 208, 131, 190, 48, 50, 202, 189, 229, 185, 182, 211, 102, 42, 108, 241, 69, 104, 194, 95, 24, 25, 101, 223, 243, 221, 91, 234, 51, 21, 54, 249, 163, 52, 97, 176, 12, 141, 179, 240, 250, 239, 174, 117, 154, 139, 27, 253, 210, 26, 177, 88, 6, 199, 218, 120, 125, 248, 87, 187, 77, 198, 142, 255, 105, 13, 217, 44, 3, 228, 109, 60, 191, 124, 172, 222, 167, 99, 71, 256, 181, 135, 237, 22, 130, 114, 183, 30, 224, 62, 86, 111, 212, 178, 164, 128, 219, 196, 247, 11, 65, 57, 220, 15, 112, 31, 43, 184, 106, 89, 82, 64, 238, 98, 252, 134, 161, 157, 110, 136, 56, 144, 150, 92, 53, 173, 41, 32, 119, 49, 126, 67, 209, 207, 55, 68, 28, 72, 75, 46, 155, 215, 149, 16, 188, 153, 63, 162, 233, 232, 156, 34, 14, 36, 166, 23, 206, 236, 203, 8, 94, 205, 160, 81, 245, 116, 78, 17, 7, 18, 83, 140, 103, 118, 230, 4, 47, 231, 80, 169, 251, 58, 39, 137, 132, 9, 170, 70, 180, 59, 115, 2, 152, 244, 40, 213, 254, 29, 148, 197, 66, 133, 85, 35, 90, 158, 186, 1], -[1, 77, 18, 101, 67, 19, 178, 85, 120, 245, 104, 41, 73, 224, 29, 177, 8, 102, 144, 37, 22, 152, 139, 166, 189, 161, 61, 71, 70, 250, 232, 131, 64, 45, 124, 39, 176, 188, 84, 43, 227, 3, 231, 54, 46, 201, 57, 20, 255, 103, 221, 55, 123, 219, 158, 87, 17, 24, 49, 175, 111, 66, 199, 160, 241, 53, 226, 183, 213, 210, 236, 182, 136, 192, 135, 115, 117, 14, 50, 252, 129, 167, 9, 179, 162, 138, 89, 171, 60, 251, 52, 149, 165, 112, 143, 217, 4, 51, 72, 147, 11, 76, 198, 83, 223, 209, 159, 164, 35, 125, 116, 194, 32, 151, 62, 148, 88, 94, 42, 150, 242, 130, 244, 27, 23, 229, 157, 10, 256, 180, 239, 156, 190, 238, 79, 172, 137, 12, 153, 216, 184, 33, 228, 80, 249, 155, 113, 220, 235, 105, 118, 91, 68, 96, 196, 186, 187, 7, 25, 126, 193, 212, 133, 218, 81, 69, 173, 214, 30, 254, 26, 203, 211, 56, 200, 237, 2, 154, 36, 202, 134, 38, 99, 170, 240, 233, 208, 82, 146, 191, 58, 97, 16, 204, 31, 74, 44, 47, 21, 75, 121, 65, 122, 142, 140, 243, 207, 5, 128, 90, 248, 78, 95, 119, 168, 86, 197, 6, 205, 108, 92, 145, 114, 40, 253, 206, 185, 110, 246, 181, 59, 174, 34, 48, 98, 93, 222, 132, 141, 63, 225, 106, 195, 109, 169, 163, 215, 107, 15, 127, 13, 230, 234, 28, 100, 247, 1], -[1, 78, 173, 130, 117, 131, 195, 47, 68, 164, 199, 102, 246, 170, 153, 112, 255, 101, 168, 254, 23, 252, 124, 163, 121, 186, 116, 53, 22, 174, 208, 33, 4, 55, 178, 6, 211, 10, 9, 188, 15, 142, 25, 151, 213, 166, 98, 191, 249, 147, 158, 245, 92, 237, 239, 138, 227, 230, 207, 212, 88, 182, 61, 132, 16, 220, 198, 24, 73, 40, 36, 238, 60, 54, 100, 90, 81, 150, 135, 250, 225, 74, 118, 209, 111, 177, 185, 38, 137, 149, 57, 77, 95, 214, 244, 14, 64, 109, 21, 96, 35, 160, 144, 181, 240, 216, 143, 103, 67, 86, 26, 229, 129, 39, 215, 65, 187, 194, 226, 152, 34, 82, 228, 51, 123, 85, 205, 56, 256, 179, 84, 127, 140, 126, 62, 210, 189, 93, 58, 155, 11, 87, 104, 145, 2, 156, 89, 3, 234, 5, 133, 94, 136, 71, 141, 204, 235, 83, 49, 224, 253, 202, 79, 251, 46, 247, 248, 69, 242, 115, 232, 106, 44, 91, 159, 66, 8, 110, 99, 12, 165, 20, 18, 119, 30, 27, 50, 45, 169, 75, 196, 125, 241, 37, 59, 233, 184, 217, 221, 19, 197, 203, 157, 167, 176, 107, 122, 7, 32, 183, 139, 48, 146, 80, 72, 219, 120, 108, 200, 180, 162, 43, 13, 243, 193, 148, 236, 161, 222, 97, 113, 76, 17, 41, 114, 154, 190, 171, 231, 28, 128, 218, 42, 192, 70, 63, 31, 105, 223, 175, 29, 206, 134, 172, 52, 201, 1], -[1, 79, 73, 113, 189, 25, 176, 26, 255, 99, 111, 31, 136, 207, 162, 205, 4, 59, 35, 195, 242, 100, 190, 104, 249, 139, 187, 124, 30, 57, 134, 49, 16, 236, 140, 9, 197, 143, 246, 159, 225, 42, 234, 239, 120, 228, 22, 196, 64, 173, 46, 36, 17, 58, 213, 122, 129, 168, 165, 185, 223, 141, 88, 13, 256, 178, 184, 144, 68, 232, 81, 231, 2, 158, 146, 226, 121, 50, 95, 52, 253, 198, 222, 62, 15, 157, 67, 153, 8, 118, 70, 133, 227, 200, 123, 208, 241, 21, 117, 248, 60, 114, 11, 98, 32, 215, 23, 18, 137, 29, 235, 61, 193, 84, 211, 221, 240, 199, 44, 135, 128, 89, 92, 72, 34, 116, 169, 244, 1, 79, 73, 113, 189, 25, 176, 26, 255, 99, 111, 31, 136, 207, 162, 205, 4, 59, 35, 195, 242, 100, 190, 104, 249, 139, 187, 124, 30, 57, 134, 49, 16, 236, 140, 9, 197, 143, 246, 159, 225, 42, 234, 239, 120, 228, 22, 196, 64, 173, 46, 36, 17, 58, 213, 122, 129, 168, 165, 185, 223, 141, 88, 13, 256, 178, 184, 144, 68, 232, 81, 231, 2, 158, 146, 226, 121, 50, 95, 52, 253, 198, 222, 62, 15, 157, 67, 153, 8, 118, 70, 133, 227, 200, 123, 208, 241, 21, 117, 248, 60, 114, 11, 98, 32, 215, 23, 18, 137, 29, 235, 61, 193, 84, 211, 221, 240, 199, 44, 135, 128, 89, 92, 72, 34, 116, 169, 244, 1], -[1, 80, 232, 56, 111, 142, 52, 48, 242, 85, 118, 188, 134, 183, 248, 51, 225, 10, 29, 7, 46, 82, 135, 6, 223, 107, 79, 152, 81, 55, 31, 167, 253, 194, 100, 33, 70, 203, 49, 65, 60, 174, 42, 19, 235, 39, 36, 53, 128, 217, 141, 229, 73, 186, 231, 233, 136, 86, 198, 163, 190, 37, 133, 103, 16, 252, 114, 125, 234, 216, 61, 254, 17, 75, 89, 181, 88, 101, 113, 45, 2, 160, 207, 112, 222, 27, 104, 96, 227, 170, 236, 119, 11, 109, 239, 102, 193, 20, 58, 14, 92, 164, 13, 12, 189, 214, 158, 47, 162, 110, 62, 77, 249, 131, 200, 66, 140, 149, 98, 130, 120, 91, 84, 38, 213, 78, 72, 106, 256, 177, 25, 201, 146, 115, 205, 209, 15, 172, 139, 69, 123, 74, 9, 206, 32, 247, 228, 250, 211, 175, 122, 251, 34, 150, 178, 105, 176, 202, 226, 90, 4, 63, 157, 224, 187, 54, 208, 192, 197, 83, 215, 238, 22, 218, 221, 204, 129, 40, 116, 28, 184, 71, 26, 24, 121, 171, 59, 94, 67, 220, 124, 154, 241, 5, 143, 132, 23, 41, 196, 3, 240, 182, 168, 76, 169, 156, 144, 212, 255, 97, 50, 145, 35, 230, 153, 161, 30, 87, 21, 138, 246, 148, 18, 155, 64, 237, 199, 243, 165, 93, 244, 245, 68, 43, 99, 210, 95, 147, 195, 180, 8, 126, 57, 191, 117, 108, 159, 127, 137, 166, 173, 219, 44, 179, 185, 151, 1], -[1, 81, 136, 222, 249, 123, 197, 23, 64, 44, 223, 73, 2, 162, 15, 187, 241, 246, 137, 46, 128, 88, 189, 146, 4, 67, 30, 117, 225, 235, 17, 92, 256, 176, 121, 35, 8, 134, 60, 234, 193, 213, 34, 184, 255, 95, 242, 70, 16, 11, 120, 211, 129, 169, 68, 111, 253, 190, 227, 140, 32, 22, 240, 165, 1, 81, 136, 222, 249, 123, 197, 23, 64, 44, 223, 73, 2, 162, 15, 187, 241, 246, 137, 46, 128, 88, 189, 146, 4, 67, 30, 117, 225, 235, 17, 92, 256, 176, 121, 35, 8, 134, 60, 234, 193, 213, 34, 184, 255, 95, 242, 70, 16, 11, 120, 211, 129, 169, 68, 111, 253, 190, 227, 140, 32, 22, 240, 165, 1, 81, 136, 222, 249, 123, 197, 23, 64, 44, 223, 73, 2, 162, 15, 187, 241, 246, 137, 46, 128, 88, 189, 146, 4, 67, 30, 117, 225, 235, 17, 92, 256, 176, 121, 35, 8, 134, 60, 234, 193, 213, 34, 184, 255, 95, 242, 70, 16, 11, 120, 211, 129, 169, 68, 111, 253, 190, 227, 140, 32, 22, 240, 165, 1, 81, 136, 222, 249, 123, 197, 23, 64, 44, 223, 73, 2, 162, 15, 187, 241, 246, 137, 46, 128, 88, 189, 146, 4, 67, 30, 117, 225, 235, 17, 92, 256, 176, 121, 35, 8, 134, 60, 234, 193, 213, 34, 184, 255, 95, 242, 70, 16, 11, 120, 211, 129, 169, 68, 111, 253, 190, 227, 140, 32, 22, 240, 165, 1], -[1, 82, 42, 103, 222, 214, 72, 250, 197, 220, 50, 245, 44, 10, 49, 163, 2, 164, 84, 206, 187, 171, 144, 243, 137, 183, 100, 233, 88, 20, 98, 69, 4, 71, 168, 155, 117, 85, 31, 229, 17, 109, 200, 209, 176, 40, 196, 138, 8, 142, 79, 53, 234, 170, 62, 201, 34, 218, 143, 161, 95, 80, 135, 19, 16, 27, 158, 106, 211, 83, 124, 145, 68, 179, 29, 65, 190, 160, 13, 38, 32, 54, 59, 212, 165, 166, 248, 33, 136, 101, 58, 130, 123, 63, 26, 76, 64, 108, 118, 167, 73, 75, 239, 66, 15, 202, 116, 3, 246, 126, 52, 152, 128, 216, 236, 77, 146, 150, 221, 132, 30, 147, 232, 6, 235, 252, 104, 47, 256, 175, 215, 154, 35, 43, 185, 7, 60, 37, 207, 12, 213, 247, 208, 94, 255, 93, 173, 51, 70, 86, 113, 14, 120, 74, 157, 24, 169, 237, 159, 188, 253, 186, 89, 102, 140, 172, 226, 28, 240, 148, 57, 48, 81, 217, 61, 119, 249, 115, 178, 204, 23, 87, 195, 56, 223, 39, 114, 96, 162, 177, 122, 238, 241, 230, 99, 151, 46, 174, 133, 112, 189, 78, 228, 192, 67, 97, 244, 219, 225, 203, 198, 45, 92, 91, 9, 224, 121, 156, 199, 127, 134, 194, 231, 181, 193, 149, 139, 90, 184, 182, 18, 191, 242, 55, 141, 254, 11, 131, 205, 105, 129, 41, 21, 180, 111, 107, 36, 125, 227, 110, 25, 251, 22, 5, 153, 210, 1], -[1, 83, 207, 219, 187, 101, 159, 90, 17, 126, 178, 125, 95, 175, 133, 245, 32, 86, 199, 69, 73, 148, 205, 53, 30, 177, 42, 145, 213, 203, 144, 130, 253, 182, 200, 152, 23, 110, 135, 154, 189, 10, 59, 14, 134, 71, 239, 48, 129, 170, 232, 238, 222, 179, 208, 45, 137, 63, 89, 191, 176, 216, 195, 251, 16, 43, 228, 163, 165, 74, 231, 155, 15, 217, 21, 201, 235, 230, 72, 65, 255, 91, 100, 76, 140, 55, 196, 77, 223, 5, 158, 7, 67, 164, 248, 24, 193, 85, 116, 119, 111, 218, 104, 151, 197, 160, 173, 224, 88, 108, 226, 254, 8, 150, 114, 210, 211, 37, 244, 206, 136, 237, 139, 229, 246, 115, 36, 161, 256, 174, 50, 38, 70, 156, 98, 167, 240, 131, 79, 132, 162, 82, 124, 12, 225, 171, 58, 188, 184, 109, 52, 204, 227, 80, 215, 112, 44, 54, 113, 127, 4, 75, 57, 105, 234, 147, 122, 103, 68, 247, 198, 243, 123, 186, 18, 209, 128, 87, 25, 19, 35, 78, 49, 212, 120, 194, 168, 66, 81, 41, 62, 6, 241, 214, 29, 94, 92, 183, 26, 102, 242, 40, 236, 56, 22, 27, 185, 192, 2, 166, 157, 181, 117, 202, 61, 180, 34, 252, 99, 250, 190, 93, 9, 233, 64, 172, 141, 138, 146, 39, 153, 106, 60, 97, 84, 33, 169, 149, 31, 3, 249, 107, 143, 47, 46, 220, 13, 51, 121, 20, 118, 28, 11, 142, 221, 96, 1], -[1, 84, 117, 62, 68, 58, 246, 104, 255, 89, 23, 133, 121, 141, 22, 49, 4, 79, 211, 248, 15, 232, 213, 159, 249, 99, 92, 18, 227, 50, 88, 196, 16, 59, 73, 221, 60, 157, 81, 122, 225, 139, 111, 72, 137, 200, 95, 13, 64, 236, 35, 113, 240, 114, 67, 231, 129, 42, 187, 31, 34, 29, 123, 52, 256, 173, 140, 195, 189, 199, 11, 153, 2, 168, 234, 124, 136, 116, 235, 208, 253, 178, 46, 9, 242, 25, 44, 98, 8, 158, 165, 239, 30, 207, 169, 61, 241, 198, 184, 36, 197, 100, 176, 135, 32, 118, 146, 185, 120, 57, 162, 244, 193, 21, 222, 144, 17, 143, 190, 26, 128, 215, 70, 226, 223, 228, 134, 205, 1, 84, 117, 62, 68, 58, 246, 104, 255, 89, 23, 133, 121, 141, 22, 49, 4, 79, 211, 248, 15, 232, 213, 159, 249, 99, 92, 18, 227, 50, 88, 196, 16, 59, 73, 221, 60, 157, 81, 122, 225, 139, 111, 72, 137, 200, 95, 13, 64, 236, 35, 113, 240, 114, 67, 231, 129, 42, 187, 31, 34, 29, 123, 52, 256, 173, 140, 195, 189, 199, 11, 153, 2, 168, 234, 124, 136, 116, 235, 208, 253, 178, 46, 9, 242, 25, 44, 98, 8, 158, 165, 239, 30, 207, 169, 61, 241, 198, 184, 36, 197, 100, 176, 135, 32, 118, 146, 185, 120, 57, 162, 244, 193, 21, 222, 144, 17, 143, 190, 26, 128, 215, 70, 226, 223, 228, 134, 205, 1], -[1, 85, 29, 152, 70, 39, 231, 103, 17, 160, 236, 14, 162, 149, 72, 209, 32, 150, 157, 238, 184, 220, 196, 212, 30, 237, 99, 191, 44, 142, 248, 6, 253, 174, 141, 163, 234, 101, 104, 102, 189, 131, 84, 201, 123, 175, 226, 192, 129, 171, 143, 76, 35, 148, 244, 180, 137, 80, 118, 7, 81, 203, 36, 233, 16, 75, 207, 119, 92, 110, 98, 106, 15, 247, 178, 224, 22, 71, 124, 3, 255, 87, 199, 210, 117, 179, 52, 51, 223, 194, 42, 229, 190, 216, 113, 96, 193, 214, 200, 38, 146, 74, 122, 90, 197, 40, 59, 132, 169, 230, 18, 245, 8, 166, 232, 188, 46, 55, 49, 53, 136, 252, 89, 112, 11, 164, 62, 130, 256, 172, 228, 105, 187, 218, 26, 154, 240, 97, 21, 243, 95, 108, 185, 48, 225, 107, 100, 19, 73, 37, 61, 45, 227, 20, 158, 66, 213, 115, 9, 251, 4, 83, 116, 94, 23, 156, 153, 155, 68, 126, 173, 56, 134, 82, 31, 65, 128, 86, 114, 181, 222, 109, 13, 77, 120, 177, 139, 250, 176, 54, 221, 24, 241, 182, 50, 138, 165, 147, 159, 151, 242, 10, 79, 33, 235, 186, 133, 254, 2, 170, 58, 47, 140, 78, 205, 206, 34, 63, 215, 28, 67, 41, 144, 161, 64, 43, 57, 219, 111, 183, 135, 167, 60, 217, 198, 125, 88, 27, 239, 12, 249, 91, 25, 69, 211, 202, 208, 204, 121, 5, 168, 145, 246, 93, 195, 127, 1], -[1, 86, 200, 238, 165, 55, 104, 206, 240, 80, 198, 66, 22, 93, 31, 96, 32, 182, 232, 163, 140, 218, 244, 167, 227, 247, 168, 56, 190, 149, 221, 245, 253, 170, 228, 76, 111, 37, 98, 204, 68, 194, 236, 250, 169, 142, 133, 130, 129, 43, 100, 119, 211, 156, 52, 103, 120, 40, 99, 33, 11, 175, 144, 48, 16, 91, 116, 210, 70, 109, 122, 212, 242, 252, 84, 28, 95, 203, 239, 251, 255, 85, 114, 38, 184, 147, 49, 102, 34, 97, 118, 125, 213, 71, 195, 65, 193, 150, 50, 188, 234, 78, 26, 180, 60, 20, 178, 145, 134, 216, 72, 24, 8, 174, 58, 105, 35, 183, 61, 106, 121, 126, 42, 14, 176, 230, 248, 254, 256, 171, 57, 19, 92, 202, 153, 51, 17, 177, 59, 191, 235, 164, 226, 161, 225, 75, 25, 94, 117, 39, 13, 90, 30, 10, 89, 201, 67, 108, 36, 12, 4, 87, 29, 181, 146, 220, 159, 53, 189, 63, 21, 7, 88, 115, 124, 127, 128, 214, 157, 138, 46, 101, 205, 154, 137, 217, 158, 224, 246, 82, 113, 209, 241, 166, 141, 47, 187, 148, 135, 45, 15, 5, 173, 229, 162, 54, 18, 6, 2, 172, 143, 219, 73, 110, 208, 155, 223, 160, 139, 132, 44, 186, 62, 192, 64, 107, 207, 69, 23, 179, 231, 77, 197, 237, 79, 112, 123, 41, 185, 233, 249, 83, 199, 152, 222, 74, 196, 151, 136, 131, 215, 243, 81, 27, 9, 3, 1], -[1, 87, 116, 69, 92, 37, 135, 180, 240, 63, 84, 112, 235, 142, 18, 24, 32, 214, 114, 152, 117, 156, 208, 106, 227, 217, 118, 243, 67, 175, 62, 254, 253, 166, 50, 238, 146, 109, 231, 51, 68, 5, 178, 66, 88, 203, 185, 161, 129, 172, 58, 163, 46, 147, 196, 90, 120, 160, 42, 56, 246, 71, 9, 12, 16, 107, 57, 76, 187, 78, 104, 53, 242, 237, 59, 250, 162, 216, 31, 127, 255, 83, 25, 119, 73, 183, 244, 154, 34, 131, 89, 33, 44, 230, 221, 209, 193, 86, 29, 210, 23, 202, 98, 45, 60, 80, 21, 28, 123, 164, 133, 6, 8, 182, 157, 38, 222, 39, 52, 155, 121, 247, 158, 125, 81, 108, 144, 192, 256, 170, 141, 188, 165, 220, 122, 77, 17, 194, 173, 145, 22, 115, 239, 233, 225, 43, 143, 105, 140, 101, 49, 151, 30, 40, 139, 14, 190, 82, 195, 3, 4, 91, 207, 19, 111, 148, 26, 206, 189, 252, 79, 191, 169, 54, 72, 96, 128, 85, 199, 94, 211, 110, 61, 167, 137, 97, 215, 201, 11, 186, 248, 245, 241, 150, 200, 181, 70, 179, 153, 204, 15, 20, 198, 7, 95, 41, 226, 130, 2, 174, 232, 138, 184, 74, 13, 103, 223, 126, 168, 224, 213, 27, 36, 48, 64, 171, 228, 47, 234, 55, 159, 212, 197, 177, 236, 229, 134, 93, 124, 251, 249, 75, 100, 219, 35, 218, 205, 102, 136, 10, 99, 132, 176, 149, 113, 65, 1], -[1, 88, 34, 165, 128, 213, 240, 46, 193, 22, 137, 234, 32, 246, 60, 140, 241, 134, 227, 187, 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, 68, 73, 256, 169, 223, 92, 129, 44, 17, 211, 64, 235, 120, 23, 225, 11, 197, 117, 16, 123, 30, 70, 249, 67, 242, 222, 4, 95, 136, 146, 255, 81, 189, 184, 1, 88, 34, 165, 128, 213, 240, 46, 193, 22, 137, 234, 32, 246, 60, 140, 241, 134, 227, 187, 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, 68, 73, 256, 169, 223, 92, 129, 44, 17, 211, 64, 235, 120, 23, 225, 11, 197, 117, 16, 123, 30, 70, 249, 67, 242, 222, 4, 95, 136, 146, 255, 81, 189, 184, 1, 88, 34, 165, 128, 213, 240, 46, 193, 22, 137, 234, 32, 246, 60, 140, 241, 134, 227, 187, 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, 68, 73, 256, 169, 223, 92, 129, 44, 17, 211, 64, 235, 120, 23, 225, 11, 197, 117, 16, 123, 30, 70, 249, 67, 242, 222, 4, 95, 136, 146, 255, 81, 189, 184, 1, 88, 34, 165, 128, 213, 240, 46, 193, 22, 137, 234, 32, 246, 60, 140, 241, 134, 227, 187, 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, 68, 73, 256, 169, 223, 92, 129, 44, 17, 211, 64, 235, 120, 23, 225, 11, 197, 117, 16, 123, 30, 70, 249, 67, 242, 222, 4, 95, 136, 146, 255, 81, 189, 184, 1], -[1, 89, 211, 18, 60, 200, 67, 52, 2, 178, 165, 36, 120, 143, 134, 104, 4, 99, 73, 72, 240, 29, 11, 208, 8, 198, 146, 144, 223, 58, 22, 159, 16, 139, 35, 31, 189, 116, 44, 61, 32, 21, 70, 62, 121, 232, 88, 122, 64, 42, 140, 124, 242, 207, 176, 244, 128, 84, 23, 248, 227, 157, 95, 231, 256, 168, 46, 239, 197, 57, 190, 205, 255, 79, 92, 221, 137, 114, 123, 153, 253, 158, 184, 185, 17, 228, 246, 49, 249, 59, 111, 113, 34, 199, 235, 98, 241, 118, 222, 226, 68, 141, 213, 196, 225, 236, 187, 195, 136, 25, 169, 135, 193, 215, 117, 133, 15, 50, 81, 13, 129, 173, 234, 9, 30, 100, 162, 26, 1, 89, 211, 18, 60, 200, 67, 52, 2, 178, 165, 36, 120, 143, 134, 104, 4, 99, 73, 72, 240, 29, 11, 208, 8, 198, 146, 144, 223, 58, 22, 159, 16, 139, 35, 31, 189, 116, 44, 61, 32, 21, 70, 62, 121, 232, 88, 122, 64, 42, 140, 124, 242, 207, 176, 244, 128, 84, 23, 248, 227, 157, 95, 231, 256, 168, 46, 239, 197, 57, 190, 205, 255, 79, 92, 221, 137, 114, 123, 153, 253, 158, 184, 185, 17, 228, 246, 49, 249, 59, 111, 113, 34, 199, 235, 98, 241, 118, 222, 226, 68, 141, 213, 196, 225, 236, 187, 195, 136, 25, 169, 135, 193, 215, 117, 133, 15, 50, 81, 13, 129, 173, 234, 9, 30, 100, 162, 26, 1], -[1, 90, 133, 148, 213, 152, 59, 170, 137, 251, 231, 230, 140, 7, 116, 160, 8, 206, 36, 156, 162, 188, 215, 75, 68, 209, 49, 41, 92, 56, 157, 252, 64, 106, 31, 220, 11, 219, 178, 86, 30, 130, 135, 71, 222, 191, 228, 217, 255, 77, 248, 218, 88, 210, 139, 174, 240, 12, 52, 54, 234, 243, 25, 194, 241, 102, 185, 202, 190, 138, 84, 107, 121, 96, 159, 175, 73, 145, 200, 10, 129, 45, 195, 74, 235, 76, 158, 85, 197, 254, 244, 115, 70, 132, 58, 80, 4, 103, 18, 78, 81, 94, 236, 166, 34, 233, 153, 149, 46, 28, 207, 126, 32, 53, 144, 110, 134, 238, 89, 43, 15, 65, 196, 164, 111, 224, 114, 237, 256, 167, 124, 109, 44, 105, 198, 87, 120, 6, 26, 27, 117, 250, 141, 97, 249, 51, 221, 101, 95, 69, 42, 182, 189, 48, 208, 216, 165, 201, 100, 5, 193, 151, 226, 37, 246, 38, 79, 171, 227, 127, 122, 186, 35, 66, 29, 40, 2, 180, 9, 39, 169, 47, 118, 83, 17, 245, 205, 203, 23, 14, 232, 63, 16, 155, 72, 55, 67, 119, 173, 150, 136, 161, 98, 82, 184, 112, 57, 247, 128, 212, 62, 183, 22, 181, 99, 172, 60, 3, 13, 142, 187, 125, 199, 177, 253, 154, 239, 179, 176, 163, 21, 91, 223, 24, 104, 108, 211, 229, 50, 131, 225, 204, 113, 147, 123, 19, 168, 214, 242, 192, 61, 93, 146, 33, 143, 20, 1], -[1, 91, 57, 47, 165, 109, 153, 45, 240, 252, 59, 229, 22, 203, 226, 6, 32, 85, 25, 219, 140, 147, 13, 155, 227, 97, 89, 132, 190, 71, 36, 192, 253, 150, 29, 69, 111, 78, 159, 77, 68, 20, 21, 112, 169, 216, 124, 233, 129, 174, 157, 152, 211, 183, 205, 151, 120, 126, 158, 243, 11, 230, 113, 3, 16, 171, 141, 238, 70, 202, 135, 206, 242, 177, 173, 66, 95, 164, 18, 96, 255, 75, 143, 163, 184, 39, 208, 167, 34, 10, 139, 56, 213, 108, 62, 245, 193, 87, 207, 76, 234, 220, 231, 204, 60, 63, 79, 250, 134, 115, 185, 130, 8, 214, 199, 119, 35, 101, 196, 103, 121, 217, 215, 33, 176, 82, 9, 48, 256, 166, 200, 210, 92, 148, 104, 212, 17, 5, 198, 28, 235, 54, 31, 251, 225, 172, 232, 38, 117, 110, 244, 102, 30, 160, 168, 125, 67, 186, 221, 65, 4, 107, 228, 188, 146, 179, 98, 180, 189, 237, 236, 145, 88, 41, 133, 24, 128, 83, 100, 105, 46, 74, 52, 106, 137, 131, 99, 14, 246, 27, 144, 254, 241, 86, 116, 19, 187, 55, 122, 51, 15, 80, 84, 191, 162, 93, 239, 161, 2, 182, 114, 94, 73, 218, 49, 90, 223, 247, 118, 201, 44, 149, 195, 12, 64, 170, 50, 181, 23, 37, 26, 53, 197, 194, 178, 7, 123, 142, 72, 127, 249, 43, 58, 138, 222, 156, 61, 154, 136, 40, 42, 224, 81, 175, 248, 209, 1], -[1, 92, 240, 235, 32, 117, 227, 67, 253, 146, 68, 88, 129, 46, 120, 246, 16, 187, 242, 162, 255, 73, 34, 44, 193, 23, 60, 123, 8, 222, 121, 81, 256, 165, 17, 22, 225, 140, 30, 190, 4, 111, 189, 169, 128, 211, 137, 11, 241, 70, 15, 95, 2, 184, 223, 213, 64, 234, 197, 134, 249, 35, 136, 176, 1, 92, 240, 235, 32, 117, 227, 67, 253, 146, 68, 88, 129, 46, 120, 246, 16, 187, 242, 162, 255, 73, 34, 44, 193, 23, 60, 123, 8, 222, 121, 81, 256, 165, 17, 22, 225, 140, 30, 190, 4, 111, 189, 169, 128, 211, 137, 11, 241, 70, 15, 95, 2, 184, 223, 213, 64, 234, 197, 134, 249, 35, 136, 176, 1, 92, 240, 235, 32, 117, 227, 67, 253, 146, 68, 88, 129, 46, 120, 246, 16, 187, 242, 162, 255, 73, 34, 44, 193, 23, 60, 123, 8, 222, 121, 81, 256, 165, 17, 22, 225, 140, 30, 190, 4, 111, 189, 169, 128, 211, 137, 11, 241, 70, 15, 95, 2, 184, 223, 213, 64, 234, 197, 134, 249, 35, 136, 176, 1, 92, 240, 235, 32, 117, 227, 67, 253, 146, 68, 88, 129, 46, 120, 246, 16, 187, 242, 162, 255, 73, 34, 44, 193, 23, 60, 123, 8, 222, 121, 81, 256, 165, 17, 22, 225, 140, 30, 190, 4, 111, 189, 169, 128, 211, 137, 11, 241, 70, 15, 95, 2, 184, 223, 213, 64, 234, 197, 134, 249, 35, 136, 176, 1], -[1, 93, 168, 204, 211, 91, 239, 125, 60, 183, 57, 161, 67, 63, 205, 47, 2, 186, 79, 151, 165, 182, 221, 250, 120, 109, 114, 65, 134, 126, 153, 94, 4, 115, 158, 45, 73, 107, 185, 243, 240, 218, 228, 130, 11, 252, 49, 188, 8, 230, 59, 90, 146, 214, 113, 229, 223, 179, 199, 3, 22, 247, 98, 119, 16, 203, 118, 180, 35, 171, 226, 201, 189, 101, 141, 6, 44, 237, 196, 238, 32, 149, 236, 103, 70, 85, 195, 145, 121, 202, 25, 12, 88, 217, 135, 219, 64, 41, 215, 206, 140, 170, 133, 33, 242, 147, 50, 24, 176, 177, 13, 181, 128, 82, 173, 155, 23, 83, 9, 66, 227, 37, 100, 48, 95, 97, 26, 105, 256, 164, 89, 53, 46, 166, 18, 132, 197, 74, 200, 96, 190, 194, 52, 210, 255, 71, 178, 106, 92, 75, 36, 7, 137, 148, 143, 192, 123, 131, 104, 163, 253, 142, 99, 212, 184, 150, 72, 14, 17, 39, 29, 127, 246, 5, 208, 69, 249, 27, 198, 167, 111, 43, 144, 28, 34, 78, 58, 254, 235, 10, 159, 138, 241, 54, 139, 77, 222, 86, 31, 56, 68, 156, 116, 251, 213, 20, 61, 19, 225, 108, 21, 154, 187, 172, 62, 112, 136, 55, 232, 245, 169, 40, 122, 38, 193, 216, 42, 51, 117, 87, 124, 224, 15, 110, 207, 233, 81, 80, 244, 76, 129, 175, 84, 102, 234, 174, 248, 191, 30, 220, 157, 209, 162, 160, 231, 152, 1], -[1, 94, 98, 217, 95, 192, 58, 55, 30, 250, 113, 85, 23, 106, 198, 108, 129, 47, 49, 237, 176, 96, 29, 156, 15, 125, 185, 171, 140, 53, 99, 54, 193, 152, 153, 247, 88, 48, 143, 78, 136, 191, 221, 214, 70, 155, 178, 27, 225, 76, 205, 252, 44, 24, 200, 39, 68, 224, 239, 107, 35, 206, 89, 142, 241, 38, 231, 126, 22, 12, 100, 148, 34, 112, 248, 182, 146, 103, 173, 71, 249, 19, 244, 63, 11, 6, 50, 74, 17, 56, 124, 91, 73, 180, 215, 164, 253, 138, 122, 160, 134, 3, 25, 37, 137, 28, 62, 174, 165, 90, 236, 82, 255, 69, 61, 80, 67, 130, 141, 147, 197, 14, 31, 87, 211, 45, 118, 41, 256, 163, 159, 40, 162, 65, 199, 202, 227, 7, 144, 172, 234, 151, 59, 149, 128, 210, 208, 20, 81, 161, 228, 101, 242, 132, 72, 86, 117, 204, 158, 203, 64, 105, 104, 10, 169, 209, 114, 179, 121, 66, 36, 43, 187, 102, 79, 230, 32, 181, 52, 5, 213, 233, 57, 218, 189, 33, 18, 150, 222, 51, 168, 115, 16, 219, 26, 131, 235, 245, 157, 109, 223, 145, 9, 75, 111, 154, 84, 186, 8, 238, 13, 194, 246, 251, 207, 183, 240, 201, 133, 166, 184, 77, 42, 93, 4, 119, 135, 97, 123, 254, 232, 220, 120, 229, 195, 83, 92, 167, 21, 175, 2, 188, 196, 177, 190, 127, 116, 110, 60, 243, 226, 170, 46, 212, 139, 216, 1], -[1, 95, 30, 23, 129, 176, 15, 140, 193, 88, 136, 70, 225, 44, 68, 35, 241, 22, 34, 146, 249, 11, 17, 73, 253, 134, 137, 165, 255, 67, 197, 211, 256, 162, 227, 234, 128, 81, 242, 117, 64, 169, 121, 187, 32, 213, 189, 222, 16, 235, 223, 111, 8, 246, 240, 184, 4, 123, 120, 92, 2, 190, 60, 46, 1, 95, 30, 23, 129, 176, 15, 140, 193, 88, 136, 70, 225, 44, 68, 35, 241, 22, 34, 146, 249, 11, 17, 73, 253, 134, 137, 165, 255, 67, 197, 211, 256, 162, 227, 234, 128, 81, 242, 117, 64, 169, 121, 187, 32, 213, 189, 222, 16, 235, 223, 111, 8, 246, 240, 184, 4, 123, 120, 92, 2, 190, 60, 46, 1, 95, 30, 23, 129, 176, 15, 140, 193, 88, 136, 70, 225, 44, 68, 35, 241, 22, 34, 146, 249, 11, 17, 73, 253, 134, 137, 165, 255, 67, 197, 211, 256, 162, 227, 234, 128, 81, 242, 117, 64, 169, 121, 187, 32, 213, 189, 222, 16, 235, 223, 111, 8, 246, 240, 184, 4, 123, 120, 92, 2, 190, 60, 46, 1, 95, 30, 23, 129, 176, 15, 140, 193, 88, 136, 70, 225, 44, 68, 35, 241, 22, 34, 146, 249, 11, 17, 73, 253, 134, 137, 165, 255, 67, 197, 211, 256, 162, 227, 234, 128, 81, 242, 117, 64, 169, 121, 187, 32, 213, 189, 222, 16, 235, 223, 111, 8, 246, 240, 184, 4, 123, 120, 92, 2, 190, 60, 46, 1], -[1, 96, 221, 142, 11, 28, 118, 20, 121, 51, 13, 220, 46, 47, 143, 107, 249, 3, 31, 149, 169, 33, 84, 97, 60, 106, 153, 39, 146, 138, 141, 172, 64, 233, 9, 93, 190, 250, 99, 252, 34, 180, 61, 202, 117, 181, 157, 166, 2, 192, 185, 27, 22, 56, 236, 40, 242, 102, 26, 183, 92, 94, 29, 214, 241, 6, 62, 41, 81, 66, 168, 194, 120, 212, 49, 78, 35, 19, 25, 87, 128, 209, 18, 186, 123, 243, 198, 247, 68, 103, 122, 147, 234, 105, 57, 75, 4, 127, 113, 54, 44, 112, 215, 80, 227, 204, 52, 109, 184, 188, 58, 171, 225, 12, 124, 82, 162, 132, 79, 131, 240, 167, 98, 156, 70, 38, 50, 174, 256, 161, 36, 115, 246, 229, 139, 237, 136, 206, 244, 37, 211, 210, 114, 150, 8, 254, 226, 108, 88, 224, 173, 160, 197, 151, 104, 218, 111, 119, 116, 85, 193, 24, 248, 164, 67, 7, 158, 5, 223, 77, 196, 55, 140, 76, 100, 91, 255, 65, 72, 230, 235, 201, 21, 217, 15, 155, 231, 74, 165, 163, 228, 43, 16, 251, 195, 216, 176, 191, 89, 63, 137, 45, 208, 179, 222, 238, 232, 170, 129, 48, 239, 71, 134, 14, 59, 10, 189, 154, 135, 110, 23, 152, 200, 182, 253, 130, 144, 203, 213, 145, 42, 177, 30, 53, 205, 148, 73, 69, 199, 86, 32, 245, 133, 175, 95, 125, 178, 126, 17, 90, 159, 101, 187, 219, 207, 83, 1], -[1, 97, 157, 66, 234, 82, 244, 24, 15, 170, 42, 219, 169, 202, 62, 103, 225, 237, 116, 201, 222, 203, 159, 3, 34, 214, 198, 188, 246, 218, 72, 45, 253, 126, 143, 250, 92, 186, 52, 161, 197, 91, 89, 152, 95, 220, 9, 102, 128, 80, 50, 224, 140, 216, 135, 245, 121, 172, 236, 19, 44, 156, 226, 77, 16, 10, 199, 28, 146, 27, 49, 127, 240, 150, 158, 163, 134, 148, 221, 106, 2, 194, 57, 132, 211, 164, 231, 48, 30, 83, 84, 181, 81, 147, 124, 206, 193, 217, 232, 145, 187, 149, 61, 6, 68, 171, 139, 119, 235, 179, 144, 90, 249, 252, 29, 243, 184, 115, 104, 65, 137, 182, 178, 47, 190, 183, 18, 204, 256, 160, 100, 191, 23, 175, 13, 233, 242, 87, 215, 38, 88, 55, 195, 154, 32, 20, 141, 56, 35, 54, 98, 254, 223, 43, 59, 69, 11, 39, 185, 212, 4, 131, 114, 7, 165, 71, 205, 96, 60, 166, 168, 105, 162, 37, 248, 155, 129, 177, 207, 33, 117, 41, 122, 12, 136, 85, 21, 238, 213, 101, 31, 180, 241, 247, 58, 229, 111, 230, 208, 130, 17, 107, 99, 94, 123, 109, 36, 151, 255, 63, 200, 125, 46, 93, 26, 209, 227, 174, 173, 76, 176, 110, 133, 51, 64, 40, 25, 112, 70, 108, 196, 251, 189, 86, 118, 138, 22, 78, 113, 167, 8, 5, 228, 14, 73, 142, 153, 192, 120, 75, 79, 210, 67, 74, 239, 53, 1], -[1, 98, 95, 58, 30, 113, 23, 198, 129, 49, 176, 29, 15, 185, 140, 99, 193, 153, 88, 143, 136, 221, 70, 178, 225, 205, 44, 200, 68, 239, 35, 89, 241, 231, 22, 100, 34, 248, 146, 173, 249, 244, 11, 50, 17, 124, 73, 215, 253, 122, 134, 25, 137, 62, 165, 236, 255, 61, 67, 141, 197, 31, 211, 118, 256, 159, 162, 199, 227, 144, 234, 59, 128, 208, 81, 228, 242, 72, 117, 158, 64, 104, 169, 114, 121, 36, 187, 79, 32, 52, 213, 57, 189, 18, 222, 168, 16, 26, 235, 157, 223, 9, 111, 84, 8, 13, 246, 207, 240, 133, 184, 42, 4, 135, 123, 232, 120, 195, 92, 21, 2, 196, 190, 116, 60, 226, 46, 139, 1, 98, 95, 58, 30, 113, 23, 198, 129, 49, 176, 29, 15, 185, 140, 99, 193, 153, 88, 143, 136, 221, 70, 178, 225, 205, 44, 200, 68, 239, 35, 89, 241, 231, 22, 100, 34, 248, 146, 173, 249, 244, 11, 50, 17, 124, 73, 215, 253, 122, 134, 25, 137, 62, 165, 236, 255, 61, 67, 141, 197, 31, 211, 118, 256, 159, 162, 199, 227, 144, 234, 59, 128, 208, 81, 228, 242, 72, 117, 158, 64, 104, 169, 114, 121, 36, 187, 79, 32, 52, 213, 57, 189, 18, 222, 168, 16, 26, 235, 157, 223, 9, 111, 84, 8, 13, 246, 207, 240, 133, 184, 42, 4, 135, 123, 232, 120, 195, 92, 21, 2, 196, 190, 116, 60, 226, 46, 139, 1], -[1, 99, 35, 124, 197, 228, 213, 13, 2, 198, 70, 248, 137, 199, 169, 26, 4, 139, 140, 239, 17, 141, 81, 52, 8, 21, 23, 221, 34, 25, 162, 104, 16, 42, 46, 185, 68, 50, 67, 208, 32, 84, 92, 113, 136, 100, 134, 159, 64, 168, 184, 226, 15, 200, 11, 61, 128, 79, 111, 195, 30, 143, 22, 122, 256, 158, 222, 133, 60, 29, 44, 244, 255, 59, 187, 9, 120, 58, 88, 231, 253, 118, 117, 18, 240, 116, 176, 205, 249, 236, 234, 36, 223, 232, 95, 153, 241, 215, 211, 72, 189, 207, 190, 49, 225, 173, 165, 144, 121, 157, 123, 98, 193, 89, 73, 31, 242, 57, 246, 196, 129, 178, 146, 62, 227, 114, 235, 135, 1, 99, 35, 124, 197, 228, 213, 13, 2, 198, 70, 248, 137, 199, 169, 26, 4, 139, 140, 239, 17, 141, 81, 52, 8, 21, 23, 221, 34, 25, 162, 104, 16, 42, 46, 185, 68, 50, 67, 208, 32, 84, 92, 113, 136, 100, 134, 159, 64, 168, 184, 226, 15, 200, 11, 61, 128, 79, 111, 195, 30, 143, 22, 122, 256, 158, 222, 133, 60, 29, 44, 244, 255, 59, 187, 9, 120, 58, 88, 231, 253, 118, 117, 18, 240, 116, 176, 205, 249, 236, 234, 36, 223, 232, 95, 153, 241, 215, 211, 72, 189, 207, 190, 49, 225, 173, 165, 144, 121, 157, 123, 98, 193, 89, 73, 31, 242, 57, 246, 196, 129, 178, 146, 62, 227, 114, 235, 135, 1], -[1, 100, 234, 13, 15, 215, 169, 195, 225, 141, 222, 98, 34, 59, 246, 185, 253, 114, 92, 205, 197, 168, 95, 248, 128, 207, 140, 122, 121, 21, 44, 31, 16, 58, 146, 208, 240, 99, 134, 36, 2, 200, 211, 26, 30, 173, 81, 133, 193, 25, 187, 196, 68, 118, 235, 113, 249, 228, 184, 153, 137, 79, 190, 239, 256, 157, 23, 244, 242, 42, 88, 62, 32, 116, 35, 159, 223, 198, 11, 72, 4, 143, 165, 52, 60, 89, 162, 9, 129, 50, 117, 135, 136, 236, 213, 226, 241, 199, 111, 49, 17, 158, 123, 221, 255, 57, 46, 231, 227, 84, 176, 124, 64, 232, 70, 61, 189, 139, 22, 144, 8, 29, 73, 104, 120, 178, 67, 18, 1, 100, 234, 13, 15, 215, 169, 195, 225, 141, 222, 98, 34, 59, 246, 185, 253, 114, 92, 205, 197, 168, 95, 248, 128, 207, 140, 122, 121, 21, 44, 31, 16, 58, 146, 208, 240, 99, 134, 36, 2, 200, 211, 26, 30, 173, 81, 133, 193, 25, 187, 196, 68, 118, 235, 113, 249, 228, 184, 153, 137, 79, 190, 239, 256, 157, 23, 244, 242, 42, 88, 62, 32, 116, 35, 159, 223, 198, 11, 72, 4, 143, 165, 52, 60, 89, 162, 9, 129, 50, 117, 135, 136, 236, 213, 226, 241, 199, 111, 49, 17, 158, 123, 221, 255, 57, 46, 231, 227, 84, 176, 124, 64, 232, 70, 61, 189, 139, 22, 144, 8, 29, 73, 104, 120, 178, 67, 18, 1], -[1, 101, 178, 245, 73, 177, 144, 152, 189, 71, 232, 45, 176, 43, 231, 201, 255, 55, 158, 24, 111, 160, 226, 210, 136, 115, 50, 167, 162, 171, 52, 112, 4, 147, 198, 209, 35, 194, 62, 94, 242, 27, 157, 180, 190, 172, 153, 33, 249, 220, 118, 96, 187, 126, 133, 69, 30, 203, 200, 154, 134, 170, 208, 191, 16, 74, 21, 65, 140, 5, 248, 119, 197, 108, 114, 206, 246, 174, 98, 132, 225, 109, 215, 127, 234, 247, 18, 19, 120, 41, 29, 102, 22, 166, 61, 250, 64, 39, 84, 3, 46, 20, 221, 219, 17, 175, 199, 53, 213, 182, 135, 14, 129, 179, 89, 251, 165, 217, 72, 76, 223, 164, 116, 151, 88, 150, 244, 229, 256, 156, 79, 12, 184, 80, 113, 105, 68, 186, 25, 212, 81, 214, 26, 56, 2, 202, 99, 233, 146, 97, 31, 47, 121, 142, 207, 90, 95, 86, 205, 145, 253, 110, 59, 48, 222, 63, 195, 163, 15, 230, 100, 77, 67, 85, 104, 224, 8, 37, 139, 161, 70, 131, 124, 188, 227, 54, 57, 103, 123, 87, 49, 66, 241, 183, 236, 192, 117, 252, 9, 138, 60, 149, 143, 51, 11, 83, 159, 125, 32, 148, 42, 130, 23, 10, 239, 238, 137, 216, 228, 155, 235, 91, 196, 7, 193, 218, 173, 254, 211, 237, 36, 38, 240, 82, 58, 204, 44, 75, 122, 243, 128, 78, 168, 6, 92, 40, 185, 181, 34, 93, 141, 106, 169, 107, 13, 28, 1], -[1, 102, 124, 55, 213, 138, 198, 150, 137, 96, 26, 82, 140, 145, 141, 247, 8, 45, 221, 183, 162, 76, 42, 172, 68, 254, 208, 142, 92, 132, 100, 177, 64, 103, 226, 179, 11, 94, 79, 91, 30, 233, 122, 108, 222, 28, 29, 131, 255, 53, 9, 147, 88, 238, 118, 214, 240, 65, 205, 93, 234, 224, 232, 20, 241, 167, 72, 148, 190, 105, 173, 170, 121, 6, 98, 230, 73, 250, 57, 160, 129, 51, 62, 156, 235, 69, 99, 75, 197, 48, 13, 41, 70, 201, 199, 252, 4, 151, 239, 220, 81, 38, 21, 86, 34, 127, 104, 71, 46, 66, 50, 217, 32, 180, 113, 218, 134, 47, 168, 174, 15, 245, 61, 54, 111, 14, 143, 194, 256, 155, 133, 202, 44, 119, 59, 107, 120, 161, 231, 175, 117, 112, 116, 10, 249, 212, 36, 74, 95, 181, 215, 85, 189, 3, 49, 115, 165, 125, 157, 80, 193, 154, 31, 78, 246, 163, 178, 166, 227, 24, 135, 149, 35, 229, 228, 126, 2, 204, 248, 110, 169, 19, 139, 43, 17, 192, 52, 164, 23, 33, 25, 237, 16, 90, 185, 109, 67, 152, 84, 87, 136, 251, 159, 27, 184, 7, 200, 97, 128, 206, 195, 101, 22, 188, 158, 182, 60, 209, 244, 216, 187, 56, 58, 5, 253, 106, 18, 37, 176, 219, 236, 171, 223, 130, 153, 186, 211, 191, 207, 40, 225, 77, 144, 39, 123, 210, 89, 83, 242, 12, 196, 203, 146, 243, 114, 63, 1], -[1, 103, 72, 220, 44, 163, 84, 171, 137, 233, 98, 71, 117, 229, 200, 40, 8, 53, 62, 218, 95, 19, 158, 83, 68, 65, 13, 54, 165, 33, 58, 63, 64, 167, 239, 202, 246, 152, 236, 150, 30, 6, 104, 175, 35, 7, 207, 247, 255, 51, 113, 74, 169, 188, 89, 172, 240, 48, 61, 115, 23, 56, 114, 177, 241, 151, 133, 78, 67, 219, 198, 91, 121, 127, 231, 149, 184, 191, 141, 131, 129, 180, 36, 110, 22, 210, 42, 214, 197, 245, 49, 164, 187, 243, 100, 20, 4, 155, 31, 109, 176, 138, 79, 170, 34, 161, 135, 27, 211, 145, 29, 160, 32, 212, 248, 101, 123, 76, 118, 75, 15, 3, 52, 216, 146, 132, 232, 252, 256, 154, 185, 37, 213, 94, 173, 86, 120, 24, 159, 186, 140, 28, 57, 217, 249, 204, 195, 39, 162, 238, 99, 174, 189, 192, 244, 203, 92, 224, 199, 194, 193, 90, 18, 55, 11, 105, 21, 107, 227, 251, 153, 82, 222, 250, 50, 10, 2, 206, 144, 183, 88, 69, 168, 85, 17, 209, 196, 142, 234, 201, 143, 80, 16, 106, 124, 179, 190, 38, 59, 166, 136, 130, 26, 108, 73, 66, 116, 126, 128, 77, 221, 147, 235, 47, 215, 43, 60, 12, 208, 93, 70, 14, 157, 237, 253, 102, 226, 148, 81, 119, 178, 87, 223, 96, 122, 230, 46, 112, 228, 97, 225, 45, 9, 156, 134, 181, 139, 182, 242, 254, 205, 41, 111, 125, 25, 5, 1], -[1, 104, 22, 232, 227, 221, 111, 236, 129, 52, 11, 116, 242, 239, 184, 118, 193, 26, 134, 58, 121, 248, 92, 59, 225, 13, 67, 29, 189, 124, 46, 158, 241, 135, 162, 143, 223, 62, 23, 79, 249, 196, 81, 200, 240, 31, 140, 168, 253, 98, 169, 100, 120, 144, 70, 84, 255, 49, 213, 50, 60, 72, 35, 42, 256, 153, 235, 25, 30, 36, 146, 21, 128, 205, 246, 141, 15, 18, 73, 139, 64, 231, 123, 199, 136, 9, 165, 198, 32, 244, 190, 228, 68, 133, 211, 99, 16, 122, 95, 114, 34, 195, 234, 178, 8, 61, 176, 57, 17, 226, 117, 89, 4, 159, 88, 157, 137, 113, 187, 173, 2, 208, 44, 207, 197, 185, 222, 215, 1, 104, 22, 232, 227, 221, 111, 236, 129, 52, 11, 116, 242, 239, 184, 118, 193, 26, 134, 58, 121, 248, 92, 59, 225, 13, 67, 29, 189, 124, 46, 158, 241, 135, 162, 143, 223, 62, 23, 79, 249, 196, 81, 200, 240, 31, 140, 168, 253, 98, 169, 100, 120, 144, 70, 84, 255, 49, 213, 50, 60, 72, 35, 42, 256, 153, 235, 25, 30, 36, 146, 21, 128, 205, 246, 141, 15, 18, 73, 139, 64, 231, 123, 199, 136, 9, 165, 198, 32, 244, 190, 228, 68, 133, 211, 99, 16, 122, 95, 114, 34, 195, 234, 178, 8, 61, 176, 57, 17, 226, 117, 89, 4, 159, 88, 157, 137, 113, 187, 173, 2, 208, 44, 207, 197, 185, 222, 215, 1], -[1, 105, 231, 97, 162, 48, 157, 37, 30, 66, 248, 83, 234, 155, 84, 82, 129, 181, 244, 177, 81, 24, 207, 147, 15, 33, 124, 170, 117, 206, 42, 41, 193, 219, 122, 217, 169, 12, 232, 202, 136, 145, 62, 85, 187, 103, 21, 149, 225, 238, 61, 237, 213, 6, 116, 101, 68, 201, 31, 171, 222, 180, 139, 203, 241, 119, 159, 247, 235, 3, 58, 179, 34, 229, 144, 214, 111, 90, 198, 230, 249, 188, 208, 252, 246, 130, 29, 218, 17, 243, 72, 107, 184, 45, 99, 115, 253, 94, 104, 126, 123, 65, 143, 109, 137, 250, 36, 182, 92, 151, 178, 186, 255, 47, 52, 63, 190, 161, 200, 183, 197, 125, 18, 91, 46, 204, 89, 93, 256, 152, 26, 160, 95, 209, 100, 220, 227, 191, 9, 174, 23, 102, 173, 175, 128, 76, 13, 80, 176, 233, 50, 110, 242, 224, 133, 87, 140, 51, 215, 216, 64, 38, 135, 40, 88, 245, 25, 55, 121, 112, 195, 172, 70, 154, 236, 108, 32, 19, 196, 20, 44, 251, 141, 156, 189, 56, 226, 86, 35, 77, 118, 54, 16, 138, 98, 10, 22, 254, 199, 78, 223, 28, 113, 43, 146, 167, 59, 27, 8, 69, 49, 5, 11, 127, 228, 39, 240, 14, 185, 150, 73, 212, 158, 142, 4, 163, 153, 131, 134, 192, 114, 148, 120, 7, 221, 75, 165, 106, 79, 71, 2, 210, 205, 194, 67, 96, 57, 74, 60, 132, 239, 166, 211, 53, 168, 164, 1], -[1, 106, 185, 78, 44, 38, 173, 91, 137, 130, 159, 149, 117, 66, 57, 131, 8, 77, 195, 110, 95, 47, 99, 214, 68, 12, 244, 164, 165, 14, 199, 20, 64, 102, 18, 109, 246, 119, 21, 170, 30, 96, 153, 27, 35, 112, 50, 160, 255, 45, 144, 101, 169, 181, 168, 75, 240, 254, 196, 216, 23, 125, 143, 252, 241, 103, 124, 37, 67, 163, 59, 86, 121, 233, 26, 186, 184, 229, 116, 217, 129, 53, 221, 39, 22, 19, 215, 174, 197, 65, 208, 203, 187, 33, 157, 194, 4, 167, 226, 55, 176, 152, 178, 107, 34, 6, 122, 82, 211, 7, 228, 10, 32, 51, 9, 183, 123, 188, 139, 85, 15, 48, 205, 142, 146, 56, 25, 80, 256, 151, 72, 179, 213, 219, 84, 166, 120, 127, 98, 108, 140, 191, 200, 126, 249, 180, 62, 147, 162, 210, 158, 43, 189, 245, 13, 93, 92, 243, 58, 237, 193, 155, 239, 148, 11, 138, 236, 87, 227, 161, 104, 230, 222, 145, 207, 97, 2, 212, 113, 156, 88, 76, 89, 182, 17, 3, 61, 41, 234, 132, 114, 5, 16, 154, 133, 220, 190, 94, 198, 171, 136, 24, 231, 71, 73, 28, 141, 40, 128, 204, 36, 218, 235, 238, 42, 83, 60, 192, 49, 54, 70, 224, 100, 63, 253, 90, 31, 202, 81, 105, 79, 150, 223, 251, 135, 175, 46, 250, 29, 247, 225, 206, 248, 74, 134, 69, 118, 172, 242, 209, 52, 115, 111, 201, 232, 177, 1], -[1, 107, 141, 181, 92, 78, 122, 204, 240, 237, 173, 7, 235, 216, 239, 130, 32, 83, 143, 138, 117, 183, 49, 103, 227, 131, 139, 224, 67, 230, 195, 48, 253, 86, 207, 47, 146, 202, 26, 212, 68, 80, 79, 229, 88, 164, 72, 251, 129, 182, 199, 219, 46, 39, 61, 102, 120, 247, 215, 132, 246, 108, 248, 65, 16, 170, 200, 69, 187, 220, 153, 180, 242, 194, 198, 112, 162, 115, 226, 24, 255, 43, 232, 152, 73, 101, 13, 106, 34, 40, 168, 243, 44, 82, 36, 254, 193, 91, 228, 238, 23, 148, 159, 51, 60, 252, 236, 66, 123, 54, 124, 161, 8, 85, 100, 163, 222, 110, 205, 90, 121, 97, 99, 56, 81, 186, 113, 12, 256, 150, 116, 76, 165, 179, 135, 53, 17, 20, 84, 250, 22, 41, 18, 127, 225, 174, 114, 119, 140, 74, 208, 154, 30, 126, 118, 33, 190, 27, 62, 209, 4, 171, 50, 210, 111, 55, 231, 45, 189, 177, 178, 28, 169, 93, 185, 6, 128, 75, 58, 38, 211, 218, 196, 155, 137, 10, 42, 125, 11, 149, 9, 192, 241, 87, 57, 188, 70, 37, 104, 77, 15, 63, 59, 145, 95, 142, 31, 233, 2, 214, 25, 105, 184, 156, 244, 151, 223, 217, 89, 14, 213, 175, 221, 3, 64, 166, 29, 19, 234, 109, 98, 206, 197, 5, 21, 191, 134, 203, 133, 96, 249, 172, 157, 94, 35, 147, 52, 167, 136, 160, 158, 201, 176, 71, 144, 245, 1], -[1, 108, 99, 155, 35, 182, 124, 28, 197, 202, 228, 209, 213, 131, 13, 119, 2, 216, 198, 53, 70, 107, 248, 56, 137, 147, 199, 161, 169, 5, 26, 238, 4, 175, 139, 106, 140, 214, 239, 112, 17, 37, 141, 65, 81, 10, 52, 219, 8, 93, 21, 212, 23, 171, 221, 224, 34, 74, 25, 130, 162, 20, 104, 181, 16, 186, 42, 167, 46, 85, 185, 191, 68, 148, 50, 3, 67, 40, 208, 105, 32, 115, 84, 77, 92, 170, 113, 125, 136, 39, 100, 6, 134, 80, 159, 210, 64, 230, 168, 154, 184, 83, 226, 250, 15, 78, 200, 12, 11, 160, 61, 163, 128, 203, 79, 51, 111, 166, 195, 243, 30, 156, 143, 24, 22, 63, 122, 69, 256, 149, 158, 102, 222, 75, 133, 229, 60, 55, 29, 48, 44, 126, 244, 138, 255, 41, 59, 204, 187, 150, 9, 201, 120, 110, 58, 96, 88, 252, 231, 19, 253, 82, 118, 151, 117, 43, 18, 145, 240, 220, 116, 192, 176, 247, 205, 38, 249, 164, 236, 45, 234, 86, 36, 33, 223, 183, 232, 127, 95, 237, 153, 76, 241, 71, 215, 90, 211, 172, 72, 66, 189, 109, 207, 254, 190, 217, 49, 152, 225, 142, 173, 180, 165, 87, 144, 132, 121, 218, 157, 251, 123, 177, 98, 47, 193, 27, 89, 103, 73, 174, 31, 7, 242, 179, 57, 245, 246, 97, 196, 94, 129, 54, 178, 206, 146, 91, 62, 14, 227, 101, 114, 233, 235, 194, 135, 188, 1], -[1, 109, 59, 6, 140, 97, 36, 69, 68, 216, 157, 151, 11, 171, 135, 66, 255, 39, 139, 245, 234, 63, 185, 119, 121, 82, 200, 212, 235, 172, 244, 125, 4, 179, 236, 24, 46, 131, 144, 19, 15, 93, 114, 90, 44, 170, 26, 7, 249, 156, 42, 209, 165, 252, 226, 219, 227, 71, 29, 77, 169, 174, 205, 243, 16, 202, 173, 96, 184, 10, 62, 76, 60, 115, 199, 103, 176, 166, 104, 28, 225, 110, 168, 65, 146, 237, 133, 105, 137, 27, 116, 51, 162, 182, 49, 201, 64, 37, 178, 127, 222, 40, 248, 47, 240, 203, 25, 155, 190, 150, 159, 112, 129, 183, 158, 3, 70, 177, 18, 163, 34, 108, 207, 204, 134, 214, 196, 33, 256, 148, 198, 251, 117, 160, 221, 188, 189, 41, 100, 106, 246, 86, 122, 191, 2, 218, 118, 12, 23, 194, 72, 138, 136, 175, 57, 45, 22, 85, 13, 132, 253, 78, 21, 233, 211, 126, 113, 238, 242, 164, 143, 167, 213, 87, 231, 250, 8, 101, 215, 48, 92, 5, 31, 38, 30, 186, 228, 180, 88, 83, 52, 14, 241, 55, 84, 161, 73, 247, 195, 181, 197, 142, 58, 154, 81, 91, 153, 229, 32, 147, 89, 192, 111, 20, 124, 152, 120, 230, 141, 206, 95, 75, 208, 56, 193, 220, 79, 130, 35, 217, 9, 210, 17, 54, 232, 102, 67, 107, 98, 145, 128, 74, 99, 254, 187, 80, 239, 94, 223, 149, 50, 53, 123, 43, 61, 224, 1], -[1, 110, 21, 254, 184, 194, 9, 219, 189, 230, 114, 204, 81, 172, 159, 14, 255, 37, 215, 6, 146, 126, 239, 76, 136, 54, 29, 106, 95, 170, 196, 229, 4, 183, 84, 245, 222, 5, 36, 105, 242, 149, 199, 45, 67, 174, 122, 56, 249, 148, 89, 24, 70, 247, 185, 47, 30, 216, 116, 167, 123, 166, 13, 145, 16, 218, 79, 209, 117, 20, 144, 163, 197, 82, 25, 180, 11, 182, 231, 224, 225, 78, 99, 96, 23, 217, 226, 188, 120, 93, 207, 154, 235, 150, 52, 66, 64, 101, 59, 65, 211, 80, 62, 138, 17, 71, 100, 206, 44, 214, 153, 125, 129, 55, 139, 127, 92, 97, 133, 238, 223, 115, 57, 102, 169, 86, 208, 7, 256, 147, 236, 3, 73, 63, 248, 38, 68, 27, 143, 53, 176, 85, 98, 243, 2, 220, 42, 251, 111, 131, 18, 181, 121, 203, 228, 151, 162, 87, 61, 28, 253, 74, 173, 12, 35, 252, 221, 152, 15, 108, 58, 212, 190, 83, 135, 201, 8, 109, 168, 233, 187, 10, 72, 210, 227, 41, 141, 90, 134, 91, 244, 112, 241, 39, 178, 48, 140, 237, 113, 94, 60, 175, 232, 77, 246, 75, 26, 33, 32, 179, 158, 161, 234, 40, 31, 69, 137, 164, 50, 103, 22, 107, 205, 191, 193, 156, 198, 192, 46, 177, 195, 119, 240, 186, 157, 51, 213, 43, 104, 132, 128, 202, 118, 130, 165, 160, 124, 19, 34, 142, 200, 155, 88, 171, 49, 250, 1], -[1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, 235, 128, 73, 136, 190, 16, 234, 17, 88, 2, 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, 213, 256, 146, 15, 123, 32, 211, 34, 176, 4, 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, 169, 255, 35, 30, 246, 64, 165, 68, 95, 8, 117, 137, 44, 1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, 235, 128, 73, 136, 190, 16, 234, 17, 88, 2, 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, 213, 256, 146, 15, 123, 32, 211, 34, 176, 4, 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, 169, 255, 35, 30, 246, 64, 165, 68, 95, 8, 117, 137, 44, 1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, 235, 128, 73, 136, 190, 16, 234, 17, 88, 2, 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, 213, 256, 146, 15, 123, 32, 211, 34, 176, 4, 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, 169, 255, 35, 30, 246, 64, 165, 68, 95, 8, 117, 137, 44, 1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, 235, 128, 73, 136, 190, 16, 234, 17, 88, 2, 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, 213, 256, 146, 15, 123, 32, 211, 34, 176, 4, 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, 169, 255, 35, 30, 246, 64, 165, 68, 95, 8, 117, 137, 44, 1], -[1, 112, 208, 166, 88, 90, 57, 216, 34, 210, 133, 247, 165, 233, 139, 148, 128, 201, 153, 174, 213, 212, 100, 149, 240, 152, 62, 5, 46, 12, 59, 183, 193, 28, 52, 170, 22, 151, 207, 54, 137, 181, 226, 126, 234, 251, 99, 37, 32, 243, 231, 172, 246, 53, 25, 230, 60, 38, 144, 194, 140, 3, 79, 110, 241, 7, 13, 171, 134, 102, 116, 142, 227, 238, 185, 160, 187, 127, 89, 202, 8, 125, 122, 43, 190, 206, 199, 186, 15, 138, 36, 177, 35, 65, 84, 156, 253, 66, 196, 107, 162, 154, 29, 164, 121, 188, 239, 40, 111, 96, 215, 179, 2, 224, 159, 75, 176, 180, 114, 175, 68, 163, 9, 237, 73, 209, 21, 39, 256, 145, 49, 91, 169, 167, 200, 41, 223, 47, 124, 10, 92, 24, 118, 109, 129, 56, 104, 83, 44, 45, 157, 108, 17, 105, 195, 252, 211, 245, 198, 74, 64, 229, 205, 87, 235, 106, 50, 203, 120, 76, 31, 131, 23, 6, 158, 220, 225, 14, 26, 85, 11, 204, 232, 27, 197, 219, 113, 63, 117, 254, 178, 147, 16, 250, 244, 86, 123, 155, 141, 115, 30, 19, 72, 97, 70, 130, 168, 55, 249, 132, 135, 214, 67, 51, 58, 71, 242, 119, 221, 80, 222, 192, 173, 101, 4, 191, 61, 150, 95, 103, 228, 93, 136, 69, 18, 217, 146, 161, 42, 78, 255, 33, 98, 182, 81, 77, 143, 82, 189, 94, 248, 20, 184, 48, 236, 218, 1], -[1, 113, 176, 99, 136, 205, 35, 100, 249, 124, 134, 236, 197, 159, 234, 228, 64, 36, 213, 168, 223, 13, 184, 232, 2, 226, 95, 198, 15, 153, 70, 200, 241, 248, 11, 215, 137, 61, 211, 199, 128, 72, 169, 79, 189, 26, 111, 207, 4, 195, 190, 139, 30, 49, 140, 143, 225, 239, 22, 173, 17, 122, 165, 141, 256, 144, 81, 158, 121, 52, 222, 157, 8, 133, 123, 21, 60, 98, 23, 29, 193, 221, 44, 89, 34, 244, 73, 25, 255, 31, 162, 59, 242, 104, 187, 57, 16, 9, 246, 42, 120, 196, 46, 58, 129, 185, 88, 178, 68, 231, 146, 50, 253, 62, 67, 118, 227, 208, 117, 114, 32, 18, 235, 84, 240, 135, 92, 116, 1, 113, 176, 99, 136, 205, 35, 100, 249, 124, 134, 236, 197, 159, 234, 228, 64, 36, 213, 168, 223, 13, 184, 232, 2, 226, 95, 198, 15, 153, 70, 200, 241, 248, 11, 215, 137, 61, 211, 199, 128, 72, 169, 79, 189, 26, 111, 207, 4, 195, 190, 139, 30, 49, 140, 143, 225, 239, 22, 173, 17, 122, 165, 141, 256, 144, 81, 158, 121, 52, 222, 157, 8, 133, 123, 21, 60, 98, 23, 29, 193, 221, 44, 89, 34, 244, 73, 25, 255, 31, 162, 59, 242, 104, 187, 57, 16, 9, 246, 42, 120, 196, 46, 58, 129, 185, 88, 178, 68, 231, 146, 50, 253, 62, 67, 118, 227, 208, 117, 114, 32, 18, 235, 84, 240, 135, 92, 116, 1], -[1, 114, 146, 196, 242, 89, 123, 144, 225, 207, 211, 153, 223, 236, 176, 18, 253, 58, 187, 244, 60, 158, 22, 195, 128, 200, 184, 159, 136, 84, 67, 185, 16, 25, 23, 52, 17, 139, 169, 248, 2, 228, 35, 135, 227, 178, 246, 31, 193, 157, 165, 49, 189, 215, 95, 36, 249, 116, 117, 231, 120, 59, 44, 133, 256, 143, 111, 61, 15, 168, 134, 113, 32, 50, 46, 104, 34, 21, 81, 239, 4, 199, 70, 13, 197, 99, 235, 62, 129, 57, 73, 98, 121, 173, 190, 72, 241, 232, 234, 205, 240, 118, 88, 9, 255, 29, 222, 122, 30, 79, 11, 226, 64, 100, 92, 208, 68, 42, 162, 221, 8, 141, 140, 26, 137, 198, 213, 124, 1, 114, 146, 196, 242, 89, 123, 144, 225, 207, 211, 153, 223, 236, 176, 18, 253, 58, 187, 244, 60, 158, 22, 195, 128, 200, 184, 159, 136, 84, 67, 185, 16, 25, 23, 52, 17, 139, 169, 248, 2, 228, 35, 135, 227, 178, 246, 31, 193, 157, 165, 49, 189, 215, 95, 36, 249, 116, 117, 231, 120, 59, 44, 133, 256, 143, 111, 61, 15, 168, 134, 113, 32, 50, 46, 104, 34, 21, 81, 239, 4, 199, 70, 13, 197, 99, 235, 62, 129, 57, 73, 98, 121, 173, 190, 72, 241, 232, 234, 205, 240, 118, 88, 9, 255, 29, 222, 122, 30, 79, 11, 226, 64, 100, 92, 208, 68, 42, 162, 221, 8, 141, 140, 26, 137, 198, 213, 124, 1], -[1, 115, 118, 206, 46, 150, 31, 224, 60, 218, 141, 24, 190, 5, 61, 76, 2, 230, 236, 155, 92, 43, 62, 191, 120, 179, 25, 48, 123, 10, 122, 152, 4, 203, 215, 53, 184, 86, 124, 125, 240, 101, 50, 96, 246, 20, 244, 47, 8, 149, 173, 106, 111, 172, 248, 250, 223, 202, 100, 192, 235, 40, 231, 94, 16, 41, 89, 212, 222, 87, 239, 243, 189, 147, 200, 127, 213, 80, 205, 188, 32, 82, 178, 167, 187, 174, 221, 229, 121, 37, 143, 254, 169, 160, 153, 119, 64, 164, 99, 77, 117, 91, 185, 201, 242, 74, 29, 251, 81, 63, 49, 238, 128, 71, 198, 154, 234, 182, 113, 145, 227, 148, 58, 245, 162, 126, 98, 219, 256, 142, 139, 51, 211, 107, 226, 33, 197, 39, 116, 233, 67, 252, 196, 181, 255, 27, 21, 102, 165, 214, 195, 66, 137, 78, 232, 209, 134, 247, 135, 105, 253, 54, 42, 204, 73, 171, 133, 132, 17, 156, 207, 161, 11, 237, 13, 210, 249, 108, 84, 151, 146, 85, 9, 7, 34, 55, 157, 65, 22, 217, 26, 163, 241, 216, 168, 45, 35, 170, 18, 14, 68, 110, 57, 130, 44, 177, 52, 69, 225, 175, 79, 90, 70, 83, 36, 28, 136, 220, 114, 3, 88, 97, 104, 138, 193, 93, 158, 180, 140, 166, 72, 56, 15, 183, 228, 6, 176, 194, 208, 19, 129, 186, 59, 103, 23, 75, 144, 112, 30, 109, 199, 12, 95, 131, 159, 38, 1], -[1, 116, 92, 135, 240, 84, 235, 18, 32, 114, 117, 208, 227, 118, 67, 62, 253, 50, 146, 231, 68, 178, 88, 185, 129, 58, 46, 196, 120, 42, 246, 9, 16, 57, 187, 104, 242, 59, 162, 31, 255, 25, 73, 244, 34, 89, 44, 221, 193, 29, 23, 98, 60, 21, 123, 133, 8, 157, 222, 52, 121, 158, 81, 144, 256, 141, 165, 122, 17, 173, 22, 239, 225, 143, 140, 49, 30, 139, 190, 195, 4, 207, 111, 26, 189, 79, 169, 72, 128, 199, 211, 61, 137, 215, 11, 248, 241, 200, 70, 153, 15, 198, 95, 226, 2, 232, 184, 13, 223, 168, 213, 36, 64, 228, 234, 159, 197, 236, 134, 124, 249, 100, 35, 205, 136, 99, 176, 113, 1, 116, 92, 135, 240, 84, 235, 18, 32, 114, 117, 208, 227, 118, 67, 62, 253, 50, 146, 231, 68, 178, 88, 185, 129, 58, 46, 196, 120, 42, 246, 9, 16, 57, 187, 104, 242, 59, 162, 31, 255, 25, 73, 244, 34, 89, 44, 221, 193, 29, 23, 98, 60, 21, 123, 133, 8, 157, 222, 52, 121, 158, 81, 144, 256, 141, 165, 122, 17, 173, 22, 239, 225, 143, 140, 49, 30, 139, 190, 195, 4, 207, 111, 26, 189, 79, 169, 72, 128, 199, 211, 61, 137, 215, 11, 248, 241, 200, 70, 153, 15, 198, 95, 226, 2, 232, 184, 13, 223, 168, 213, 36, 64, 228, 234, 159, 197, 236, 134, 124, 249, 100, 35, 205, 136, 99, 176, 113, 1], -[1, 117, 68, 246, 255, 23, 121, 22, 4, 211, 15, 213, 249, 92, 227, 88, 16, 73, 60, 81, 225, 111, 137, 95, 64, 35, 240, 67, 129, 187, 34, 123, 256, 140, 189, 11, 2, 234, 136, 235, 253, 46, 242, 44, 8, 165, 30, 169, 241, 184, 197, 176, 32, 146, 120, 162, 193, 222, 17, 190, 128, 70, 223, 134, 1, 117, 68, 246, 255, 23, 121, 22, 4, 211, 15, 213, 249, 92, 227, 88, 16, 73, 60, 81, 225, 111, 137, 95, 64, 35, 240, 67, 129, 187, 34, 123, 256, 140, 189, 11, 2, 234, 136, 235, 253, 46, 242, 44, 8, 165, 30, 169, 241, 184, 197, 176, 32, 146, 120, 162, 193, 222, 17, 190, 128, 70, 223, 134, 1, 117, 68, 246, 255, 23, 121, 22, 4, 211, 15, 213, 249, 92, 227, 88, 16, 73, 60, 81, 225, 111, 137, 95, 64, 35, 240, 67, 129, 187, 34, 123, 256, 140, 189, 11, 2, 234, 136, 235, 253, 46, 242, 44, 8, 165, 30, 169, 241, 184, 197, 176, 32, 146, 120, 162, 193, 222, 17, 190, 128, 70, 223, 134, 1, 117, 68, 246, 255, 23, 121, 22, 4, 211, 15, 213, 249, 92, 227, 88, 16, 73, 60, 81, 225, 111, 137, 95, 64, 35, 240, 67, 129, 187, 34, 123, 256, 140, 189, 11, 2, 234, 136, 235, 253, 46, 242, 44, 8, 165, 30, 169, 241, 184, 197, 176, 32, 146, 120, 162, 193, 222, 17, 190, 128, 70, 223, 134, 1], -[1, 118, 46, 31, 60, 141, 190, 61, 2, 236, 92, 62, 120, 25, 123, 122, 4, 215, 184, 124, 240, 50, 246, 244, 8, 173, 111, 248, 223, 100, 235, 231, 16, 89, 222, 239, 189, 200, 213, 205, 32, 178, 187, 221, 121, 143, 169, 153, 64, 99, 117, 185, 242, 29, 81, 49, 128, 198, 234, 113, 227, 58, 162, 98, 256, 139, 211, 226, 197, 116, 67, 196, 255, 21, 165, 195, 137, 232, 134, 135, 253, 42, 73, 133, 17, 207, 11, 13, 249, 84, 146, 9, 34, 157, 22, 26, 241, 168, 35, 18, 68, 57, 44, 52, 225, 79, 70, 36, 136, 114, 88, 104, 193, 158, 140, 72, 15, 228, 176, 208, 129, 59, 23, 144, 30, 199, 95, 159, 1, 118, 46, 31, 60, 141, 190, 61, 2, 236, 92, 62, 120, 25, 123, 122, 4, 215, 184, 124, 240, 50, 246, 244, 8, 173, 111, 248, 223, 100, 235, 231, 16, 89, 222, 239, 189, 200, 213, 205, 32, 178, 187, 221, 121, 143, 169, 153, 64, 99, 117, 185, 242, 29, 81, 49, 128, 198, 234, 113, 227, 58, 162, 98, 256, 139, 211, 226, 197, 116, 67, 196, 255, 21, 165, 195, 137, 232, 134, 135, 253, 42, 73, 133, 17, 207, 11, 13, 249, 84, 146, 9, 34, 157, 22, 26, 241, 168, 35, 18, 68, 57, 44, 52, 225, 79, 70, 36, 136, 114, 88, 104, 193, 158, 140, 72, 15, 228, 176, 208, 129, 59, 23, 144, 30, 199, 95, 159, 1], -[1, 119, 26, 10, 162, 3, 100, 78, 30, 229, 9, 43, 234, 90, 173, 27, 129, 188, 13, 5, 81, 130, 50, 39, 15, 243, 133, 150, 117, 45, 215, 142, 193, 94, 135, 131, 169, 65, 25, 148, 136, 250, 195, 75, 187, 151, 236, 71, 225, 47, 196, 194, 213, 161, 141, 74, 68, 125, 226, 166, 222, 204, 118, 164, 241, 152, 98, 97, 235, 209, 199, 37, 34, 191, 113, 83, 111, 102, 59, 82, 249, 76, 49, 177, 246, 233, 228, 147, 17, 224, 185, 170, 184, 51, 158, 41, 253, 38, 153, 217, 123, 245, 114, 202, 137, 112, 221, 85, 92, 154, 79, 149, 255, 19, 205, 237, 190, 251, 57, 101, 197, 56, 239, 171, 46, 77, 168, 203, 256, 138, 231, 247, 95, 254, 157, 179, 227, 28, 248, 214, 23, 167, 84, 230, 128, 69, 244, 252, 176, 127, 207, 218, 242, 14, 124, 107, 140, 212, 42, 115, 64, 163, 122, 126, 88, 192, 232, 109, 121, 7, 62, 182, 70, 106, 21, 186, 32, 210, 61, 63, 44, 96, 116, 183, 189, 132, 31, 91, 35, 53, 139, 93, 16, 105, 159, 160, 22, 48, 58, 220, 223, 66, 144, 174, 146, 155, 198, 175, 8, 181, 208, 80, 11, 24, 29, 110, 240, 33, 72, 87, 73, 206, 99, 216, 4, 219, 104, 40, 134, 12, 143, 55, 120, 145, 36, 172, 165, 103, 178, 108, 2, 238, 52, 20, 67, 6, 200, 156, 60, 201, 18, 86, 211, 180, 89, 54, 1], -[1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1], -[1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1], -[1, 122, 235, 143, 227, 195, 146, 79, 129, 61, 246, 200, 242, 226, 73, 168, 193, 159, 123, 100, 121, 113, 165, 84, 225, 208, 190, 50, 189, 185, 211, 42, 241, 104, 95, 25, 223, 221, 234, 21, 249, 52, 176, 141, 240, 239, 117, 139, 253, 26, 88, 199, 120, 248, 187, 198, 255, 13, 44, 228, 60, 124, 222, 99, 256, 135, 22, 114, 30, 62, 111, 178, 128, 196, 11, 57, 15, 31, 184, 89, 64, 98, 134, 157, 136, 144, 92, 173, 32, 49, 67, 207, 68, 72, 46, 215, 16, 153, 162, 232, 34, 36, 23, 236, 8, 205, 81, 116, 17, 18, 140, 118, 4, 231, 169, 58, 137, 9, 70, 59, 2, 244, 213, 29, 197, 133, 35, 158, 1, 122, 235, 143, 227, 195, 146, 79, 129, 61, 246, 200, 242, 226, 73, 168, 193, 159, 123, 100, 121, 113, 165, 84, 225, 208, 190, 50, 189, 185, 211, 42, 241, 104, 95, 25, 223, 221, 234, 21, 249, 52, 176, 141, 240, 239, 117, 139, 253, 26, 88, 199, 120, 248, 187, 198, 255, 13, 44, 228, 60, 124, 222, 99, 256, 135, 22, 114, 30, 62, 111, 178, 128, 196, 11, 57, 15, 31, 184, 89, 64, 98, 134, 157, 136, 144, 92, 173, 32, 49, 67, 207, 68, 72, 46, 215, 16, 153, 162, 232, 34, 36, 23, 236, 8, 205, 81, 116, 17, 18, 140, 118, 4, 231, 169, 58, 137, 9, 70, 59, 2, 244, 213, 29, 197, 133, 35, 158, 1], -[1, 123, 223, 187, 128, 67, 17, 35, 193, 95, 120, 111, 32, 81, 197, 73, 241, 88, 30, 92, 8, 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, 117, 256, 134, 34, 70, 129, 190, 240, 222, 64, 162, 137, 146, 225, 176, 60, 184, 16, 169, 227, 165, 249, 44, 15, 46, 4, 235, 121, 234, 255, 11, 68, 140, 1, 123, 223, 187, 128, 67, 17, 35, 193, 95, 120, 111, 32, 81, 197, 73, 241, 88, 30, 92, 8, 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, 117, 256, 134, 34, 70, 129, 190, 240, 222, 64, 162, 137, 146, 225, 176, 60, 184, 16, 169, 227, 165, 249, 44, 15, 46, 4, 235, 121, 234, 255, 11, 68, 140, 1, 123, 223, 187, 128, 67, 17, 35, 193, 95, 120, 111, 32, 81, 197, 73, 241, 88, 30, 92, 8, 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, 117, 256, 134, 34, 70, 129, 190, 240, 222, 64, 162, 137, 146, 225, 176, 60, 184, 16, 169, 227, 165, 249, 44, 15, 46, 4, 235, 121, 234, 255, 11, 68, 140, 1, 123, 223, 187, 128, 67, 17, 35, 193, 95, 120, 111, 32, 81, 197, 73, 241, 88, 30, 92, 8, 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, 117, 256, 134, 34, 70, 129, 190, 240, 222, 64, 162, 137, 146, 225, 176, 60, 184, 16, 169, 227, 165, 249, 44, 15, 46, 4, 235, 121, 234, 255, 11, 68, 140, 1], -[1, 124, 213, 198, 137, 26, 140, 141, 8, 221, 162, 42, 68, 208, 92, 100, 64, 226, 11, 79, 30, 122, 222, 29, 255, 9, 88, 118, 240, 205, 234, 232, 241, 72, 190, 173, 121, 98, 73, 57, 129, 62, 235, 99, 197, 13, 70, 199, 4, 239, 81, 21, 34, 104, 46, 50, 32, 113, 134, 168, 15, 61, 111, 143, 256, 133, 44, 59, 120, 231, 117, 116, 249, 36, 95, 215, 189, 49, 165, 157, 193, 31, 246, 178, 227, 135, 35, 228, 2, 248, 169, 139, 17, 52, 23, 25, 16, 185, 67, 84, 136, 159, 184, 200, 128, 195, 22, 158, 60, 244, 187, 58, 253, 18, 176, 236, 223, 153, 211, 207, 225, 144, 123, 89, 242, 196, 146, 114, 1, 124, 213, 198, 137, 26, 140, 141, 8, 221, 162, 42, 68, 208, 92, 100, 64, 226, 11, 79, 30, 122, 222, 29, 255, 9, 88, 118, 240, 205, 234, 232, 241, 72, 190, 173, 121, 98, 73, 57, 129, 62, 235, 99, 197, 13, 70, 199, 4, 239, 81, 21, 34, 104, 46, 50, 32, 113, 134, 168, 15, 61, 111, 143, 256, 133, 44, 59, 120, 231, 117, 116, 249, 36, 95, 215, 189, 49, 165, 157, 193, 31, 246, 178, 227, 135, 35, 228, 2, 248, 169, 139, 17, 52, 23, 25, 16, 185, 67, 84, 136, 159, 184, 200, 128, 195, 22, 158, 60, 244, 187, 58, 253, 18, 176, 236, 223, 153, 211, 207, 225, 144, 123, 89, 242, 196, 146, 114, 1], -[1, 125, 205, 182, 134, 45, 228, 230, 223, 119, 226, 237, 70, 12, 215, 147, 128, 66, 26, 166, 190, 106, 143, 142, 17, 69, 144, 10, 222, 251, 21, 55, 193, 224, 244, 174, 162, 204, 57, 186, 120, 94, 185, 252, 146, 3, 118, 101, 32, 145, 135, 170, 176, 155, 100, 164, 197, 210, 36, 131, 184, 127, 198, 78, 241, 56, 61, 172, 169, 51, 207, 175, 30, 152, 239, 63, 165, 65, 158, 218, 8, 229, 98, 171, 44, 103, 25, 41, 242, 181, 9, 97, 46, 96, 178, 148, 253, 14, 208, 43, 235, 77, 116, 108, 136, 38, 124, 80, 234, 209, 168, 183, 2, 250, 153, 107, 11, 90, 199, 203, 189, 238, 195, 217, 140, 24, 173, 37, 256, 132, 52, 75, 123, 212, 29, 27, 34, 138, 31, 20, 187, 245, 42, 110, 129, 191, 231, 91, 67, 151, 114, 115, 240, 188, 113, 247, 35, 6, 236, 202, 64, 33, 13, 83, 95, 53, 200, 71, 137, 163, 72, 5, 111, 254, 139, 156, 225, 112, 122, 87, 81, 102, 157, 93, 60, 47, 221, 126, 73, 130, 59, 179, 16, 201, 196, 85, 88, 206, 50, 82, 227, 105, 18, 194, 92, 192, 99, 39, 249, 28, 159, 86, 213, 154, 232, 216, 15, 76, 248, 160, 211, 161, 79, 109, 4, 243, 49, 214, 22, 180, 141, 149, 121, 219, 133, 177, 23, 48, 89, 74, 255, 7, 104, 150, 246, 167, 58, 54, 68, 19, 62, 40, 117, 233, 84, 220, 1], -[1, 126, 199, 145, 23, 71, 208, 251, 15, 91, 158, 119, 88, 37, 36, 167, 225, 80, 57, 243, 35, 41, 26, 192, 34, 172, 84, 47, 11, 101, 133, 53, 253, 10, 232, 191, 165, 230, 196, 24, 197, 150, 139, 38, 162, 109, 113, 103, 128, 194, 29, 56, 117, 93, 153, 3, 121, 83, 178, 69, 213, 110, 239, 45, 16, 217, 100, 7, 111, 108, 244, 161, 240, 171, 215, 105, 123, 78, 62, 102, 2, 252, 141, 33, 46, 142, 159, 245, 30, 182, 59, 238, 176, 74, 72, 77, 193, 160, 114, 229, 70, 82, 52, 127, 68, 87, 168, 94, 22, 202, 9, 106, 249, 20, 207, 125, 73, 203, 135, 48, 137, 43, 21, 76, 67, 218, 226, 206, 256, 131, 58, 112, 234, 186, 49, 6, 242, 166, 99, 138, 169, 220, 221, 90, 32, 177, 200, 14, 222, 216, 231, 65, 223, 85, 173, 210, 246, 156, 124, 204, 4, 247, 25, 66, 92, 27, 61, 233, 60, 107, 118, 219, 95, 148, 144, 154, 129, 63, 228, 201, 140, 164, 104, 254, 136, 174, 79, 188, 44, 147, 18, 212, 241, 40, 157, 250, 146, 149, 13, 96, 17, 86, 42, 152, 134, 179, 195, 155, 255, 5, 116, 224, 211, 115, 98, 12, 227, 75, 198, 19, 81, 183, 185, 180, 64, 97, 143, 28, 187, 175, 205, 130, 189, 170, 89, 163, 235, 55, 248, 151, 8, 237, 50, 132, 184, 54, 122, 209, 120, 214, 236, 181, 190, 39, 31, 51, 1], -[1, 127, 195, 93, 246, 145, 168, 5, 121, 204, 208, 202, 211, 69, 25, 91, 249, 12, 239, 27, 88, 125, 198, 217, 60, 167, 135, 183, 111, 219, 57, 43, 64, 161, 144, 41, 67, 28, 215, 63, 34, 206, 205, 78, 140, 47, 58, 170, 2, 254, 133, 186, 235, 33, 79, 10, 242, 151, 159, 147, 165, 138, 50, 182, 241, 24, 221, 54, 176, 250, 139, 177, 120, 77, 13, 109, 222, 181, 114, 86, 128, 65, 31, 82, 134, 56, 173, 126, 68, 155, 153, 156, 23, 94, 116, 83, 4, 251, 9, 115, 213, 66, 158, 20, 227, 45, 61, 37, 73, 19, 100, 107, 225, 48, 185, 108, 95, 243, 21, 97, 240, 154, 26, 218, 187, 105, 228, 172, 256, 130, 62, 164, 11, 112, 89, 252, 136, 53, 49, 55, 46, 188, 232, 166, 8, 245, 18, 230, 169, 132, 59, 40, 197, 90, 122, 74, 146, 38, 200, 214, 193, 96, 113, 216, 190, 229, 42, 194, 223, 51, 52, 179, 117, 210, 199, 87, 255, 3, 124, 71, 22, 224, 178, 247, 15, 106, 98, 110, 92, 119, 207, 75, 16, 233, 36, 203, 81, 7, 118, 80, 137, 180, 244, 148, 35, 76, 143, 171, 129, 192, 226, 175, 123, 201, 84, 131, 189, 102, 104, 101, 234, 163, 141, 174, 253, 6, 248, 142, 44, 191, 99, 237, 30, 212, 196, 220, 184, 238, 157, 150, 32, 209, 72, 149, 162, 14, 236, 160, 17, 103, 231, 39, 70, 152, 29, 85, 1], -[1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1], -[1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1], -[1, 130, 195, 164, 246, 112, 168, 252, 121, 53, 208, 55, 211, 188, 25, 166, 249, 245, 239, 230, 88, 132, 198, 40, 60, 90, 135, 74, 111, 38, 57, 214, 64, 96, 144, 216, 67, 229, 215, 194, 34, 51, 205, 179, 140, 210, 58, 87, 2, 3, 133, 71, 235, 224, 79, 247, 242, 106, 159, 110, 165, 119, 50, 75, 241, 233, 221, 203, 176, 7, 139, 80, 120, 180, 13, 148, 222, 76, 114, 171, 128, 192, 31, 175, 134, 201, 173, 131, 68, 102, 153, 101, 23, 163, 116, 174, 4, 6, 9, 142, 213, 191, 158, 237, 227, 212, 61, 220, 73, 238, 100, 150, 225, 209, 185, 149, 95, 14, 21, 160, 240, 103, 26, 39, 187, 152, 228, 85, 256, 127, 62, 93, 11, 145, 89, 5, 136, 204, 49, 202, 46, 69, 232, 91, 8, 12, 18, 27, 169, 125, 59, 217, 197, 167, 122, 183, 146, 219, 200, 43, 193, 161, 113, 41, 190, 28, 42, 63, 223, 206, 52, 78, 117, 47, 199, 170, 255, 254, 124, 186, 22, 33, 178, 10, 15, 151, 98, 147, 92, 138, 207, 182, 16, 24, 36, 54, 81, 250, 118, 177, 137, 77, 244, 109, 35, 181, 143, 86, 129, 65, 226, 82, 123, 56, 84, 126, 189, 155, 104, 156, 234, 94, 141, 83, 253, 251, 248, 115, 44, 66, 99, 20, 30, 45, 196, 37, 184, 19, 157, 107, 32, 48, 72, 108, 162, 243, 236, 97, 17, 154, 231, 218, 70, 105, 29, 172, 1], -[1, 131, 199, 112, 23, 186, 208, 6, 15, 166, 158, 138, 88, 220, 36, 90, 225, 177, 57, 14, 35, 216, 26, 65, 34, 85, 84, 210, 11, 156, 133, 204, 253, 247, 232, 66, 165, 27, 196, 233, 197, 107, 139, 219, 162, 148, 113, 154, 128, 63, 29, 201, 117, 164, 153, 254, 121, 174, 178, 188, 213, 147, 239, 212, 16, 40, 100, 250, 111, 149, 244, 96, 240, 86, 215, 152, 123, 179, 62, 155, 2, 5, 141, 224, 46, 115, 159, 12, 30, 75, 59, 19, 176, 183, 72, 180, 193, 97, 114, 28, 70, 175, 52, 130, 68, 170, 168, 163, 22, 55, 9, 151, 249, 237, 207, 132, 73, 54, 135, 209, 137, 214, 21, 181, 67, 39, 226, 51, 256, 126, 58, 145, 234, 71, 49, 251, 242, 91, 99, 119, 169, 37, 221, 167, 32, 80, 200, 243, 222, 41, 231, 192, 223, 172, 173, 47, 246, 101, 124, 53, 4, 10, 25, 191, 92, 230, 61, 24, 60, 150, 118, 38, 95, 109, 144, 103, 129, 194, 228, 56, 140, 93, 104, 3, 136, 83, 79, 69, 44, 110, 18, 45, 241, 217, 157, 7, 146, 108, 13, 161, 17, 171, 42, 105, 134, 78, 195, 102, 255, 252, 116, 33, 211, 142, 98, 245, 227, 182, 198, 238, 81, 74, 185, 77, 64, 160, 143, 229, 187, 82, 205, 127, 189, 87, 89, 94, 235, 202, 248, 106, 8, 20, 50, 125, 184, 203, 122, 48, 120, 43, 236, 76, 190, 218, 31, 206, 1], -[1, 132, 205, 75, 134, 212, 228, 27, 223, 138, 226, 20, 70, 245, 215, 110, 128, 191, 26, 91, 190, 151, 143, 115, 17, 188, 144, 247, 222, 6, 21, 202, 193, 33, 244, 83, 162, 53, 57, 71, 120, 163, 185, 5, 146, 254, 118, 156, 32, 112, 135, 87, 176, 102, 100, 93, 197, 47, 36, 126, 184, 130, 198, 179, 241, 201, 61, 85, 169, 206, 207, 82, 30, 105, 239, 194, 165, 192, 158, 39, 8, 28, 98, 86, 44, 154, 25, 216, 242, 76, 9, 160, 46, 161, 178, 109, 253, 243, 208, 214, 235, 180, 116, 149, 136, 219, 124, 177, 234, 48, 168, 74, 2, 7, 153, 150, 11, 167, 199, 54, 189, 19, 195, 40, 140, 233, 173, 220, 256, 125, 52, 182, 123, 45, 29, 230, 34, 119, 31, 237, 187, 12, 42, 147, 129, 66, 231, 166, 67, 106, 114, 142, 240, 69, 113, 10, 35, 251, 236, 55, 64, 224, 13, 174, 95, 204, 200, 186, 137, 94, 72, 252, 111, 3, 139, 101, 225, 145, 122, 170, 81, 155, 157, 164, 60, 210, 221, 131, 73, 127, 59, 78, 16, 56, 196, 172, 88, 51, 50, 175, 227, 152, 18, 63, 92, 65, 99, 218, 249, 229, 159, 171, 213, 103, 232, 41, 15, 181, 248, 97, 211, 96, 79, 148, 4, 14, 49, 43, 22, 77, 141, 108, 121, 38, 133, 80, 23, 209, 89, 183, 255, 250, 104, 107, 246, 90, 58, 203, 68, 238, 62, 217, 117, 24, 84, 37, 1], -[1, 133, 213, 59, 137, 231, 140, 116, 8, 36, 162, 215, 68, 49, 92, 157, 64, 31, 11, 178, 30, 135, 222, 228, 255, 248, 88, 139, 240, 52, 234, 25, 241, 185, 190, 84, 121, 159, 73, 200, 129, 195, 235, 158, 197, 244, 70, 58, 4, 18, 81, 236, 34, 153, 46, 207, 32, 144, 134, 89, 15, 196, 111, 114, 256, 124, 44, 198, 120, 26, 117, 141, 249, 221, 95, 42, 189, 208, 165, 100, 193, 226, 246, 79, 227, 122, 35, 29, 2, 9, 169, 118, 17, 205, 23, 232, 16, 72, 67, 173, 136, 98, 184, 57, 128, 62, 22, 99, 60, 13, 187, 199, 253, 239, 176, 21, 223, 104, 211, 50, 225, 113, 123, 168, 242, 61, 146, 143, 1, 133, 213, 59, 137, 231, 140, 116, 8, 36, 162, 215, 68, 49, 92, 157, 64, 31, 11, 178, 30, 135, 222, 228, 255, 248, 88, 139, 240, 52, 234, 25, 241, 185, 190, 84, 121, 159, 73, 200, 129, 195, 235, 158, 197, 244, 70, 58, 4, 18, 81, 236, 34, 153, 46, 207, 32, 144, 134, 89, 15, 196, 111, 114, 256, 124, 44, 198, 120, 26, 117, 141, 249, 221, 95, 42, 189, 208, 165, 100, 193, 226, 246, 79, 227, 122, 35, 29, 2, 9, 169, 118, 17, 205, 23, 232, 16, 72, 67, 173, 136, 98, 184, 57, 128, 62, 22, 99, 60, 13, 187, 199, 253, 239, 176, 21, 223, 104, 211, 50, 225, 113, 123, 168, 242, 61, 146, 143, 1], -[1, 134, 223, 70, 128, 190, 17, 222, 193, 162, 120, 146, 32, 176, 197, 184, 241, 169, 30, 165, 8, 44, 242, 46, 253, 235, 136, 234, 2, 11, 189, 140, 256, 123, 34, 187, 129, 67, 240, 35, 64, 95, 137, 111, 225, 81, 60, 73, 16, 88, 227, 92, 249, 213, 15, 211, 4, 22, 121, 23, 255, 246, 68, 117, 1, 134, 223, 70, 128, 190, 17, 222, 193, 162, 120, 146, 32, 176, 197, 184, 241, 169, 30, 165, 8, 44, 242, 46, 253, 235, 136, 234, 2, 11, 189, 140, 256, 123, 34, 187, 129, 67, 240, 35, 64, 95, 137, 111, 225, 81, 60, 73, 16, 88, 227, 92, 249, 213, 15, 211, 4, 22, 121, 23, 255, 246, 68, 117, 1, 134, 223, 70, 128, 190, 17, 222, 193, 162, 120, 146, 32, 176, 197, 184, 241, 169, 30, 165, 8, 44, 242, 46, 253, 235, 136, 234, 2, 11, 189, 140, 256, 123, 34, 187, 129, 67, 240, 35, 64, 95, 137, 111, 225, 81, 60, 73, 16, 88, 227, 92, 249, 213, 15, 211, 4, 22, 121, 23, 255, 246, 68, 117, 1, 134, 223, 70, 128, 190, 17, 222, 193, 162, 120, 146, 32, 176, 197, 184, 241, 169, 30, 165, 8, 44, 242, 46, 253, 235, 136, 234, 2, 11, 189, 140, 256, 123, 34, 187, 129, 67, 240, 35, 64, 95, 137, 111, 225, 81, 60, 73, 16, 88, 227, 92, 249, 213, 15, 211, 4, 22, 121, 23, 255, 246, 68, 117, 1], -[1, 135, 235, 114, 227, 62, 146, 178, 129, 196, 246, 57, 242, 31, 73, 89, 193, 98, 123, 157, 121, 144, 165, 173, 225, 49, 190, 207, 189, 72, 211, 215, 241, 153, 95, 232, 223, 36, 234, 236, 249, 205, 176, 116, 240, 18, 117, 118, 253, 231, 88, 58, 120, 9, 187, 59, 255, 244, 44, 29, 60, 133, 222, 158, 256, 122, 22, 143, 30, 195, 111, 79, 128, 61, 11, 200, 15, 226, 184, 168, 64, 159, 134, 100, 136, 113, 92, 84, 32, 208, 67, 50, 68, 185, 46, 42, 16, 104, 162, 25, 34, 221, 23, 21, 8, 52, 81, 141, 17, 239, 140, 139, 4, 26, 169, 199, 137, 248, 70, 198, 2, 13, 213, 228, 197, 124, 35, 99, 1, 135, 235, 114, 227, 62, 146, 178, 129, 196, 246, 57, 242, 31, 73, 89, 193, 98, 123, 157, 121, 144, 165, 173, 225, 49, 190, 207, 189, 72, 211, 215, 241, 153, 95, 232, 223, 36, 234, 236, 249, 205, 176, 116, 240, 18, 117, 118, 253, 231, 88, 58, 120, 9, 187, 59, 255, 244, 44, 29, 60, 133, 222, 158, 256, 122, 22, 143, 30, 195, 111, 79, 128, 61, 11, 200, 15, 226, 184, 168, 64, 159, 134, 100, 136, 113, 92, 84, 32, 208, 67, 50, 68, 185, 46, 42, 16, 104, 162, 25, 34, 221, 23, 21, 8, 52, 81, 141, 17, 239, 140, 139, 4, 26, 169, 199, 137, 248, 70, 198, 2, 13, 213, 228, 197, 124, 35, 99, 1], -[1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1], -[1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1], -[1, 138, 26, 247, 162, 254, 100, 179, 30, 28, 9, 214, 234, 167, 173, 230, 129, 69, 13, 252, 81, 127, 50, 218, 15, 14, 133, 107, 117, 212, 215, 115, 193, 163, 135, 126, 169, 192, 25, 109, 136, 7, 195, 182, 187, 106, 236, 186, 225, 210, 196, 63, 213, 96, 141, 183, 68, 132, 226, 91, 222, 53, 118, 93, 241, 105, 98, 160, 235, 48, 199, 220, 34, 66, 113, 174, 111, 155, 59, 175, 249, 181, 49, 80, 246, 24, 228, 110, 17, 33, 185, 87, 184, 206, 158, 216, 253, 219, 153, 40, 123, 12, 114, 55, 137, 145, 221, 172, 92, 103, 79, 108, 255, 238, 205, 20, 190, 6, 57, 156, 197, 201, 239, 86, 46, 180, 168, 54, 256, 119, 231, 10, 95, 3, 157, 78, 227, 229, 248, 43, 23, 90, 84, 27, 128, 188, 244, 5, 176, 130, 207, 39, 242, 243, 124, 150, 140, 45, 42, 142, 64, 94, 122, 131, 88, 65, 232, 148, 121, 250, 62, 75, 70, 151, 21, 71, 32, 47, 61, 194, 44, 161, 116, 74, 189, 125, 31, 166, 35, 204, 139, 164, 16, 152, 159, 97, 22, 209, 58, 37, 223, 191, 144, 83, 146, 102, 198, 82, 8, 76, 208, 177, 11, 233, 29, 147, 240, 224, 72, 170, 73, 51, 99, 41, 4, 38, 104, 217, 134, 245, 143, 202, 120, 112, 36, 85, 165, 154, 178, 149, 2, 19, 52, 237, 67, 251, 200, 101, 60, 56, 18, 171, 211, 77, 89, 203, 1], -[1, 139, 46, 226, 60, 116, 190, 196, 2, 21, 92, 195, 120, 232, 123, 135, 4, 42, 184, 133, 240, 207, 246, 13, 8, 84, 111, 9, 223, 157, 235, 26, 16, 168, 222, 18, 189, 57, 213, 52, 32, 79, 187, 36, 121, 114, 169, 104, 64, 158, 117, 72, 242, 228, 81, 208, 128, 59, 234, 144, 227, 199, 162, 159, 256, 118, 211, 31, 197, 141, 67, 61, 255, 236, 165, 62, 137, 25, 134, 122, 253, 215, 73, 124, 17, 50, 11, 244, 249, 173, 146, 248, 34, 100, 22, 231, 241, 89, 35, 239, 68, 200, 44, 205, 225, 178, 70, 221, 136, 143, 88, 153, 193, 99, 140, 185, 15, 29, 176, 49, 129, 198, 23, 113, 30, 58, 95, 98, 1, 139, 46, 226, 60, 116, 190, 196, 2, 21, 92, 195, 120, 232, 123, 135, 4, 42, 184, 133, 240, 207, 246, 13, 8, 84, 111, 9, 223, 157, 235, 26, 16, 168, 222, 18, 189, 57, 213, 52, 32, 79, 187, 36, 121, 114, 169, 104, 64, 158, 117, 72, 242, 228, 81, 208, 128, 59, 234, 144, 227, 199, 162, 159, 256, 118, 211, 31, 197, 141, 67, 61, 255, 236, 165, 62, 137, 25, 134, 122, 253, 215, 73, 124, 17, 50, 11, 244, 249, 173, 146, 248, 34, 100, 22, 231, 241, 89, 35, 239, 68, 200, 44, 205, 225, 178, 70, 221, 136, 143, 88, 153, 193, 99, 140, 185, 15, 29, 176, 49, 129, 198, 23, 113, 30, 58, 95, 98, 1], -[1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, 44, 249, 165, 227, 169, 16, 184, 60, 176, 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, 34, 134, 256, 117, 189, 246, 2, 23, 136, 22, 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, 197, 81, 32, 111, 120, 95, 193, 35, 17, 67, 128, 187, 223, 123, 1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, 44, 249, 165, 227, 169, 16, 184, 60, 176, 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, 34, 134, 256, 117, 189, 246, 2, 23, 136, 22, 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, 197, 81, 32, 111, 120, 95, 193, 35, 17, 67, 128, 187, 223, 123, 1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, 44, 249, 165, 227, 169, 16, 184, 60, 176, 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, 34, 134, 256, 117, 189, 246, 2, 23, 136, 22, 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, 197, 81, 32, 111, 120, 95, 193, 35, 17, 67, 128, 187, 223, 123, 1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, 44, 249, 165, 227, 169, 16, 184, 60, 176, 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, 34, 134, 256, 117, 189, 246, 2, 23, 136, 22, 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, 197, 81, 32, 111, 120, 95, 193, 35, 17, 67, 128, 187, 223, 123, 1], -[1, 141, 92, 122, 240, 173, 235, 239, 32, 143, 117, 49, 227, 139, 67, 195, 253, 207, 146, 26, 68, 79, 88, 72, 129, 199, 46, 61, 120, 215, 246, 248, 16, 200, 187, 153, 242, 198, 162, 226, 255, 232, 73, 13, 34, 168, 44, 36, 193, 228, 23, 159, 60, 236, 123, 124, 8, 100, 222, 205, 121, 99, 81, 113, 256, 116, 165, 135, 17, 84, 22, 18, 225, 114, 140, 208, 30, 118, 190, 62, 4, 50, 111, 231, 189, 178, 169, 185, 128, 58, 211, 196, 137, 42, 11, 9, 241, 57, 70, 104, 15, 59, 95, 31, 2, 25, 184, 244, 223, 89, 213, 221, 64, 29, 234, 98, 197, 21, 134, 133, 249, 157, 35, 52, 136, 158, 176, 144, 1, 141, 92, 122, 240, 173, 235, 239, 32, 143, 117, 49, 227, 139, 67, 195, 253, 207, 146, 26, 68, 79, 88, 72, 129, 199, 46, 61, 120, 215, 246, 248, 16, 200, 187, 153, 242, 198, 162, 226, 255, 232, 73, 13, 34, 168, 44, 36, 193, 228, 23, 159, 60, 236, 123, 124, 8, 100, 222, 205, 121, 99, 81, 113, 256, 116, 165, 135, 17, 84, 22, 18, 225, 114, 140, 208, 30, 118, 190, 62, 4, 50, 111, 231, 189, 178, 169, 185, 128, 58, 211, 196, 137, 42, 11, 9, 241, 57, 70, 104, 15, 59, 95, 31, 2, 25, 184, 244, 223, 89, 213, 221, 64, 29, 234, 98, 197, 21, 134, 133, 249, 157, 35, 52, 136, 158, 176, 144, 1], -[1, 142, 118, 51, 46, 107, 31, 33, 60, 39, 141, 233, 190, 252, 61, 181, 2, 27, 236, 102, 92, 214, 62, 66, 120, 78, 25, 209, 123, 247, 122, 105, 4, 54, 215, 204, 184, 171, 124, 132, 240, 156, 50, 161, 246, 237, 244, 210, 8, 108, 173, 151, 111, 85, 248, 7, 223, 55, 100, 65, 235, 217, 231, 163, 16, 216, 89, 45, 222, 170, 239, 14, 189, 110, 200, 130, 213, 177, 205, 69, 32, 175, 178, 90, 187, 83, 221, 28, 121, 220, 143, 3, 169, 97, 153, 138, 64, 93, 99, 180, 117, 166, 185, 56, 242, 183, 29, 6, 81, 194, 49, 19, 128, 186, 198, 103, 234, 75, 113, 112, 227, 109, 58, 12, 162, 131, 98, 38, 256, 115, 139, 206, 211, 150, 226, 224, 197, 218, 116, 24, 67, 5, 196, 76, 255, 230, 21, 155, 165, 43, 195, 191, 137, 179, 232, 48, 134, 10, 135, 152, 253, 203, 42, 53, 73, 86, 133, 125, 17, 101, 207, 96, 11, 20, 13, 47, 249, 149, 84, 106, 146, 172, 9, 250, 34, 202, 157, 192, 22, 40, 26, 94, 241, 41, 168, 212, 35, 87, 18, 243, 68, 147, 57, 127, 44, 80, 52, 188, 225, 82, 79, 167, 70, 174, 36, 229, 136, 37, 114, 254, 88, 160, 104, 119, 193, 164, 158, 77, 140, 91, 72, 201, 15, 74, 228, 251, 176, 63, 208, 238, 129, 71, 59, 154, 23, 182, 144, 145, 30, 148, 199, 245, 95, 126, 159, 219, 1], -[1, 143, 146, 61, 242, 168, 123, 113, 225, 50, 211, 104, 223, 21, 176, 239, 253, 199, 187, 13, 60, 99, 22, 62, 128, 57, 184, 98, 136, 173, 67, 72, 16, 232, 23, 205, 17, 118, 169, 9, 2, 29, 35, 122, 227, 79, 246, 226, 193, 100, 165, 208, 189, 42, 95, 221, 249, 141, 117, 26, 120, 198, 44, 124, 256, 114, 111, 196, 15, 89, 134, 144, 32, 207, 46, 153, 34, 236, 81, 18, 4, 58, 70, 244, 197, 158, 235, 195, 129, 200, 73, 159, 121, 84, 190, 185, 241, 25, 234, 52, 240, 139, 88, 248, 255, 228, 222, 135, 30, 178, 11, 31, 64, 157, 92, 49, 68, 215, 162, 36, 8, 116, 140, 231, 137, 59, 213, 133, 1, 143, 146, 61, 242, 168, 123, 113, 225, 50, 211, 104, 223, 21, 176, 239, 253, 199, 187, 13, 60, 99, 22, 62, 128, 57, 184, 98, 136, 173, 67, 72, 16, 232, 23, 205, 17, 118, 169, 9, 2, 29, 35, 122, 227, 79, 246, 226, 193, 100, 165, 208, 189, 42, 95, 221, 249, 141, 117, 26, 120, 198, 44, 124, 256, 114, 111, 196, 15, 89, 134, 144, 32, 207, 46, 153, 34, 236, 81, 18, 4, 58, 70, 244, 197, 158, 235, 195, 129, 200, 73, 159, 121, 84, 190, 185, 241, 25, 234, 52, 240, 139, 88, 248, 255, 228, 222, 135, 30, 178, 11, 31, 64, 157, 92, 49, 68, 215, 162, 36, 8, 116, 140, 231, 137, 59, 213, 133, 1], -[1, 144, 176, 158, 136, 52, 35, 157, 249, 133, 134, 21, 197, 98, 234, 29, 64, 221, 213, 89, 223, 244, 184, 25, 2, 31, 95, 59, 15, 104, 70, 57, 241, 9, 11, 42, 137, 196, 211, 58, 128, 185, 169, 178, 189, 231, 111, 50, 4, 62, 190, 118, 30, 208, 140, 114, 225, 18, 22, 84, 17, 135, 165, 116, 256, 113, 81, 99, 121, 205, 222, 100, 8, 124, 123, 236, 60, 159, 23, 228, 193, 36, 44, 168, 34, 13, 73, 232, 255, 226, 162, 198, 242, 153, 187, 200, 16, 248, 246, 215, 120, 61, 46, 199, 129, 72, 88, 79, 68, 26, 146, 207, 253, 195, 67, 139, 227, 49, 117, 143, 32, 239, 235, 173, 240, 122, 92, 141, 1, 144, 176, 158, 136, 52, 35, 157, 249, 133, 134, 21, 197, 98, 234, 29, 64, 221, 213, 89, 223, 244, 184, 25, 2, 31, 95, 59, 15, 104, 70, 57, 241, 9, 11, 42, 137, 196, 211, 58, 128, 185, 169, 178, 189, 231, 111, 50, 4, 62, 190, 118, 30, 208, 140, 114, 225, 18, 22, 84, 17, 135, 165, 116, 256, 113, 81, 99, 121, 205, 222, 100, 8, 124, 123, 236, 60, 159, 23, 228, 193, 36, 44, 168, 34, 13, 73, 232, 255, 226, 162, 198, 242, 153, 187, 200, 16, 248, 246, 215, 120, 61, 46, 199, 129, 72, 88, 79, 68, 26, 146, 207, 253, 195, 67, 139, 227, 49, 117, 143, 32, 239, 235, 173, 240, 122, 92, 141, 1], -[1, 145, 208, 91, 88, 167, 57, 41, 34, 47, 133, 10, 165, 24, 139, 109, 128, 56, 153, 83, 213, 45, 100, 108, 240, 105, 62, 252, 46, 245, 59, 74, 193, 229, 52, 87, 22, 106, 207, 203, 137, 76, 226, 131, 234, 6, 99, 220, 32, 14, 231, 85, 246, 204, 25, 27, 60, 219, 144, 63, 140, 254, 79, 147, 241, 250, 13, 86, 134, 155, 116, 115, 227, 19, 185, 97, 187, 130, 89, 55, 8, 132, 122, 214, 190, 51, 199, 71, 15, 119, 36, 80, 35, 192, 84, 101, 253, 191, 196, 150, 162, 103, 29, 93, 121, 69, 239, 217, 111, 161, 215, 78, 2, 33, 159, 182, 176, 77, 114, 82, 68, 94, 9, 20, 73, 48, 21, 218, 256, 112, 49, 166, 169, 90, 200, 216, 223, 210, 124, 247, 92, 233, 118, 148, 129, 201, 104, 174, 44, 212, 157, 149, 17, 152, 195, 5, 211, 12, 198, 183, 64, 28, 205, 170, 235, 151, 50, 54, 120, 181, 31, 126, 23, 251, 158, 37, 225, 243, 26, 172, 11, 53, 232, 230, 197, 38, 113, 194, 117, 3, 178, 110, 16, 7, 244, 171, 123, 102, 141, 142, 30, 238, 72, 160, 70, 127, 168, 202, 249, 125, 135, 43, 67, 206, 58, 186, 242, 138, 221, 177, 222, 65, 173, 156, 4, 66, 61, 107, 95, 154, 228, 164, 136, 188, 18, 40, 146, 96, 42, 179, 255, 224, 98, 75, 81, 180, 143, 175, 189, 163, 248, 237, 184, 209, 236, 39, 1], -[1, 146, 242, 123, 225, 211, 223, 176, 253, 187, 60, 22, 128, 184, 136, 67, 16, 23, 17, 169, 2, 35, 227, 246, 193, 165, 189, 95, 249, 117, 120, 44, 256, 111, 15, 134, 32, 46, 34, 81, 4, 70, 197, 235, 129, 73, 121, 190, 241, 234, 240, 88, 255, 222, 30, 11, 64, 92, 68, 162, 8, 140, 137, 213, 1, 146, 242, 123, 225, 211, 223, 176, 253, 187, 60, 22, 128, 184, 136, 67, 16, 23, 17, 169, 2, 35, 227, 246, 193, 165, 189, 95, 249, 117, 120, 44, 256, 111, 15, 134, 32, 46, 34, 81, 4, 70, 197, 235, 129, 73, 121, 190, 241, 234, 240, 88, 255, 222, 30, 11, 64, 92, 68, 162, 8, 140, 137, 213, 1, 146, 242, 123, 225, 211, 223, 176, 253, 187, 60, 22, 128, 184, 136, 67, 16, 23, 17, 169, 2, 35, 227, 246, 193, 165, 189, 95, 249, 117, 120, 44, 256, 111, 15, 134, 32, 46, 34, 81, 4, 70, 197, 235, 129, 73, 121, 190, 241, 234, 240, 88, 255, 222, 30, 11, 64, 92, 68, 162, 8, 140, 137, 213, 1, 146, 242, 123, 225, 211, 223, 176, 253, 187, 60, 22, 128, 184, 136, 67, 16, 23, 17, 169, 2, 35, 227, 246, 193, 165, 189, 95, 249, 117, 120, 44, 256, 111, 15, 134, 32, 46, 34, 81, 4, 70, 197, 235, 129, 73, 121, 190, 241, 234, 240, 88, 255, 222, 30, 11, 64, 92, 68, 162, 8, 140, 137, 213, 1], -[1, 147, 21, 3, 184, 63, 9, 38, 189, 27, 114, 53, 81, 85, 159, 243, 255, 220, 215, 251, 146, 131, 239, 181, 136, 203, 29, 151, 95, 87, 196, 28, 4, 74, 84, 12, 222, 252, 36, 152, 242, 108, 199, 212, 67, 83, 122, 201, 249, 109, 89, 233, 70, 10, 185, 210, 30, 41, 116, 90, 123, 91, 13, 112, 16, 39, 79, 48, 117, 237, 144, 94, 197, 175, 25, 77, 11, 75, 231, 33, 225, 179, 99, 161, 23, 40, 226, 69, 120, 164, 207, 103, 235, 107, 52, 191, 64, 156, 59, 192, 211, 177, 62, 119, 17, 186, 100, 51, 44, 43, 153, 132, 129, 202, 139, 130, 92, 160, 133, 19, 223, 142, 57, 155, 169, 171, 208, 250, 256, 110, 236, 254, 73, 194, 248, 219, 68, 230, 143, 204, 176, 172, 98, 14, 2, 37, 42, 6, 111, 126, 18, 76, 121, 54, 228, 106, 162, 170, 61, 229, 253, 183, 173, 245, 35, 5, 221, 105, 15, 149, 58, 45, 190, 174, 135, 56, 8, 148, 168, 24, 187, 247, 72, 47, 227, 216, 141, 167, 134, 166, 244, 145, 241, 218, 178, 209, 140, 20, 113, 163, 60, 82, 232, 180, 246, 182, 26, 224, 32, 78, 158, 96, 234, 217, 31, 188, 137, 93, 50, 154, 22, 150, 205, 66, 193, 101, 198, 65, 46, 80, 195, 138, 240, 71, 157, 206, 213, 214, 104, 125, 128, 55, 118, 127, 165, 97, 124, 238, 34, 115, 200, 102, 88, 86, 49, 7, 1], -[1, 148, 59, 251, 140, 160, 36, 188, 68, 41, 157, 106, 11, 86, 135, 191, 255, 218, 139, 12, 234, 194, 185, 138, 121, 175, 200, 45, 235, 85, 244, 132, 4, 78, 236, 233, 46, 126, 144, 238, 15, 164, 114, 167, 44, 87, 26, 250, 249, 101, 42, 48, 165, 5, 226, 38, 227, 186, 29, 180, 169, 83, 205, 14, 16, 55, 173, 161, 184, 247, 62, 181, 60, 142, 199, 154, 176, 91, 104, 229, 225, 147, 168, 192, 146, 20, 133, 152, 137, 230, 116, 206, 162, 75, 49, 56, 64, 220, 178, 130, 222, 217, 248, 210, 240, 54, 25, 102, 190, 107, 159, 145, 129, 74, 158, 254, 70, 80, 18, 94, 34, 149, 207, 53, 134, 43, 196, 224, 256, 109, 198, 6, 117, 97, 221, 69, 189, 216, 100, 151, 246, 171, 122, 66, 2, 39, 118, 245, 23, 63, 72, 119, 136, 82, 57, 212, 22, 172, 13, 125, 253, 179, 21, 24, 211, 131, 113, 19, 242, 93, 143, 90, 213, 170, 231, 7, 8, 156, 215, 209, 92, 252, 31, 219, 30, 71, 228, 77, 88, 174, 52, 243, 241, 202, 84, 96, 73, 10, 195, 76, 197, 115, 58, 103, 81, 166, 153, 28, 32, 110, 89, 65, 111, 237, 124, 105, 120, 27, 141, 51, 95, 182, 208, 201, 193, 37, 79, 127, 35, 40, 9, 47, 17, 203, 232, 155, 67, 150, 98, 112, 128, 183, 99, 3, 187, 177, 239, 163, 223, 108, 50, 204, 123, 214, 61, 33, 1], -[1, 149, 99, 102, 35, 75, 124, 229, 197, 55, 228, 48, 213, 126, 13, 138, 2, 41, 198, 204, 70, 150, 248, 201, 137, 110, 199, 96, 169, 252, 26, 19, 4, 82, 139, 151, 140, 43, 239, 145, 17, 220, 141, 192, 81, 247, 52, 38, 8, 164, 21, 45, 23, 86, 221, 33, 34, 183, 25, 127, 162, 237, 104, 76, 16, 71, 42, 90, 46, 172, 185, 66, 68, 109, 50, 254, 67, 217, 208, 152, 32, 142, 84, 180, 92, 87, 113, 132, 136, 218, 100, 251, 134, 177, 159, 47, 64, 27, 168, 103, 184, 174, 226, 7, 15, 179, 200, 245, 11, 97, 61, 94, 128, 54, 79, 206, 111, 91, 195, 14, 30, 101, 143, 233, 22, 194, 122, 188, 256, 108, 158, 155, 222, 182, 133, 28, 60, 202, 29, 209, 44, 131, 244, 119, 255, 216, 59, 53, 187, 107, 9, 56, 120, 147, 58, 161, 88, 5, 231, 238, 253, 175, 118, 106, 117, 214, 18, 112, 240, 37, 116, 65, 176, 10, 205, 219, 249, 93, 236, 212, 234, 171, 36, 224, 223, 74, 232, 130, 95, 20, 153, 181, 241, 186, 215, 167, 211, 85, 72, 191, 189, 148, 207, 3, 190, 40, 49, 105, 225, 115, 173, 77, 165, 170, 144, 125, 121, 39, 157, 6, 123, 80, 98, 210, 193, 230, 89, 154, 73, 83, 31, 250, 242, 78, 57, 12, 246, 160, 196, 163, 129, 203, 178, 51, 146, 166, 62, 243, 227, 156, 114, 24, 235, 63, 135, 69, 1], -[1, 150, 141, 76, 92, 179, 122, 53, 240, 20, 173, 250, 235, 41, 239, 127, 32, 174, 143, 119, 117, 74, 49, 154, 227, 126, 139, 33, 67, 27, 195, 209, 253, 171, 207, 210, 146, 55, 26, 45, 68, 177, 79, 28, 88, 93, 72, 6, 129, 75, 199, 38, 46, 218, 61, 155, 120, 10, 215, 125, 246, 149, 248, 192, 16, 87, 200, 188, 187, 37, 153, 77, 242, 63, 198, 145, 162, 142, 226, 233, 255, 214, 232, 105, 73, 156, 13, 151, 34, 217, 168, 14, 44, 175, 36, 3, 193, 166, 228, 19, 23, 109, 159, 206, 60, 5, 236, 191, 123, 203, 124, 96, 8, 172, 100, 94, 222, 147, 205, 167, 121, 160, 99, 201, 81, 71, 113, 245, 256, 107, 116, 181, 165, 78, 135, 204, 17, 237, 84, 7, 22, 216, 18, 130, 225, 83, 114, 138, 140, 183, 208, 103, 30, 131, 118, 224, 190, 230, 62, 48, 4, 86, 50, 47, 111, 202, 231, 212, 189, 80, 178, 229, 169, 164, 185, 251, 128, 182, 58, 219, 211, 39, 196, 102, 137, 247, 42, 132, 11, 108, 9, 65, 241, 170, 57, 69, 70, 220, 104, 180, 15, 194, 59, 112, 95, 115, 31, 24, 2, 43, 25, 152, 184, 101, 244, 106, 223, 40, 89, 243, 213, 82, 221, 254, 64, 91, 29, 238, 234, 148, 98, 51, 197, 252, 21, 66, 134, 54, 133, 161, 249, 85, 157, 163, 35, 110, 52, 90, 136, 97, 158, 56, 176, 186, 144, 12, 1], -[1, 151, 185, 179, 44, 219, 173, 166, 137, 127, 159, 108, 117, 191, 57, 126, 8, 180, 195, 147, 95, 210, 99, 43, 68, 245, 244, 93, 165, 243, 199, 237, 64, 155, 18, 148, 246, 138, 21, 87, 30, 161, 153, 230, 35, 145, 50, 97, 255, 212, 144, 156, 169, 76, 168, 182, 240, 3, 196, 41, 23, 132, 143, 5, 241, 154, 124, 220, 67, 94, 59, 171, 121, 24, 26, 71, 184, 28, 116, 40, 129, 204, 221, 218, 22, 238, 215, 83, 197, 192, 208, 54, 187, 224, 157, 63, 4, 90, 226, 202, 176, 105, 178, 150, 34, 251, 122, 175, 211, 250, 228, 247, 32, 206, 9, 74, 123, 69, 139, 172, 15, 209, 205, 115, 146, 201, 25, 177, 256, 106, 72, 78, 213, 38, 84, 91, 120, 130, 98, 149, 140, 66, 200, 131, 249, 77, 62, 110, 162, 47, 158, 214, 189, 12, 13, 164, 92, 14, 58, 20, 193, 102, 239, 109, 11, 119, 236, 170, 227, 96, 104, 27, 222, 112, 207, 160, 2, 45, 113, 101, 88, 181, 89, 75, 17, 254, 61, 216, 234, 125, 114, 252, 16, 103, 133, 37, 190, 163, 198, 86, 136, 233, 231, 186, 73, 229, 141, 217, 128, 53, 36, 39, 235, 19, 42, 174, 60, 65, 49, 203, 70, 33, 100, 194, 253, 167, 31, 55, 81, 152, 79, 107, 223, 6, 135, 82, 46, 7, 29, 10, 225, 51, 248, 183, 134, 188, 118, 85, 242, 48, 52, 142, 111, 56, 232, 80, 1], -[1, 152, 231, 160, 162, 209, 157, 220, 30, 191, 248, 174, 234, 102, 84, 175, 129, 76, 244, 80, 81, 233, 207, 110, 15, 224, 124, 87, 117, 51, 42, 216, 193, 38, 122, 40, 169, 245, 232, 55, 136, 112, 62, 172, 187, 154, 21, 108, 225, 19, 61, 20, 213, 251, 116, 156, 68, 56, 31, 86, 222, 77, 139, 54, 241, 138, 159, 10, 235, 254, 58, 78, 34, 28, 144, 43, 111, 167, 198, 27, 249, 69, 208, 5, 246, 127, 29, 39, 17, 14, 72, 150, 184, 212, 99, 142, 253, 163, 104, 131, 123, 192, 143, 148, 137, 7, 36, 75, 92, 106, 178, 71, 255, 210, 52, 194, 190, 96, 200, 74, 197, 132, 18, 166, 46, 53, 89, 164, 256, 105, 26, 97, 95, 48, 100, 37, 227, 66, 9, 83, 23, 155, 173, 82, 128, 181, 13, 177, 176, 24, 50, 147, 242, 33, 133, 170, 140, 206, 215, 41, 64, 219, 135, 217, 88, 12, 25, 202, 121, 145, 195, 85, 70, 103, 236, 149, 32, 238, 196, 237, 44, 6, 141, 101, 189, 201, 226, 171, 35, 180, 118, 203, 16, 119, 98, 247, 22, 3, 199, 179, 223, 229, 113, 214, 146, 90, 59, 230, 8, 188, 49, 252, 11, 130, 228, 218, 240, 243, 185, 107, 73, 45, 158, 115, 4, 94, 153, 126, 134, 65, 114, 109, 120, 250, 221, 182, 165, 151, 79, 186, 2, 47, 205, 63, 67, 161, 57, 183, 60, 125, 239, 91, 211, 204, 168, 93, 1], -[1, 153, 22, 25, 227, 36, 111, 21, 129, 205, 11, 141, 242, 18, 184, 139, 193, 231, 134, 199, 121, 9, 92, 198, 225, 244, 67, 228, 189, 133, 46, 99, 241, 122, 162, 114, 223, 195, 23, 178, 249, 61, 81, 57, 240, 226, 140, 89, 253, 159, 169, 157, 120, 113, 70, 173, 255, 208, 213, 207, 60, 185, 35, 215, 256, 104, 235, 232, 30, 221, 146, 236, 128, 52, 246, 116, 15, 239, 73, 118, 64, 26, 123, 58, 136, 248, 165, 59, 32, 13, 190, 29, 68, 124, 211, 158, 16, 135, 95, 143, 34, 62, 234, 79, 8, 196, 176, 200, 17, 31, 117, 168, 4, 98, 88, 100, 137, 144, 187, 84, 2, 49, 44, 50, 197, 72, 222, 42, 1, 153, 22, 25, 227, 36, 111, 21, 129, 205, 11, 141, 242, 18, 184, 139, 193, 231, 134, 199, 121, 9, 92, 198, 225, 244, 67, 228, 189, 133, 46, 99, 241, 122, 162, 114, 223, 195, 23, 178, 249, 61, 81, 57, 240, 226, 140, 89, 253, 159, 169, 157, 120, 113, 70, 173, 255, 208, 213, 207, 60, 185, 35, 215, 256, 104, 235, 232, 30, 221, 146, 236, 128, 52, 246, 116, 15, 239, 73, 118, 64, 26, 123, 58, 136, 248, 165, 59, 32, 13, 190, 29, 68, 124, 211, 158, 16, 135, 95, 143, 34, 62, 234, 79, 8, 196, 176, 200, 17, 31, 117, 168, 4, 98, 88, 100, 137, 144, 187, 84, 2, 49, 44, 50, 197, 72, 222, 42, 1], -[1, 154, 72, 37, 44, 94, 84, 86, 137, 24, 98, 186, 117, 28, 200, 217, 8, 204, 62, 39, 95, 238, 158, 174, 68, 192, 13, 203, 165, 224, 58, 194, 64, 90, 239, 55, 246, 105, 236, 107, 30, 251, 104, 82, 35, 250, 207, 10, 255, 206, 113, 183, 169, 69, 89, 85, 240, 209, 61, 142, 23, 201, 114, 80, 241, 106, 133, 179, 67, 38, 198, 166, 121, 130, 231, 108, 184, 66, 141, 126, 129, 77, 36, 147, 22, 47, 42, 43, 197, 12, 49, 93, 187, 14, 100, 237, 4, 102, 31, 148, 176, 119, 79, 87, 34, 96, 135, 230, 211, 112, 29, 97, 32, 45, 248, 156, 123, 181, 118, 182, 15, 254, 52, 41, 146, 125, 232, 5, 256, 103, 185, 220, 213, 163, 173, 171, 120, 233, 159, 71, 140, 229, 57, 40, 249, 53, 195, 218, 162, 19, 99, 83, 189, 65, 244, 54, 92, 33, 199, 63, 193, 167, 18, 202, 11, 152, 21, 150, 227, 6, 153, 175, 222, 7, 50, 247, 2, 51, 144, 74, 88, 188, 168, 172, 17, 48, 196, 115, 234, 56, 143, 177, 16, 151, 124, 78, 190, 219, 59, 91, 136, 127, 26, 149, 73, 191, 116, 131, 128, 180, 221, 110, 235, 210, 215, 214, 60, 245, 208, 164, 70, 243, 157, 20, 253, 155, 226, 109, 81, 138, 178, 170, 223, 161, 122, 27, 46, 145, 228, 160, 225, 212, 9, 101, 134, 76, 139, 75, 242, 3, 205, 216, 111, 132, 25, 252, 1], -[1, 155, 124, 202, 213, 119, 198, 107, 137, 161, 26, 175, 140, 112, 141, 10, 8, 212, 221, 74, 162, 181, 42, 85, 68, 3, 208, 115, 92, 125, 100, 80, 64, 154, 226, 78, 11, 163, 79, 166, 30, 24, 122, 149, 222, 229, 29, 126, 255, 204, 9, 110, 88, 19, 118, 43, 240, 192, 205, 164, 234, 33, 232, 237, 241, 90, 72, 109, 190, 152, 173, 87, 121, 251, 98, 27, 73, 7, 57, 97, 129, 206, 62, 101, 235, 188, 99, 182, 197, 209, 13, 216, 70, 56, 199, 5, 4, 106, 239, 37, 81, 219, 21, 171, 34, 130, 104, 186, 46, 191, 50, 40, 32, 77, 113, 39, 134, 210, 168, 83, 15, 12, 61, 203, 111, 243, 143, 63, 256, 102, 133, 55, 44, 138, 59, 150, 120, 96, 231, 82, 117, 145, 116, 247, 249, 45, 36, 183, 95, 76, 215, 172, 189, 254, 49, 142, 165, 132, 157, 177, 193, 103, 31, 179, 246, 94, 178, 91, 227, 233, 135, 108, 35, 28, 228, 131, 2, 53, 248, 147, 169, 238, 139, 214, 17, 65, 52, 93, 23, 224, 25, 20, 16, 167, 185, 148, 67, 105, 84, 170, 136, 6, 159, 230, 184, 250, 200, 160, 128, 51, 195, 156, 22, 69, 158, 75, 60, 48, 244, 41, 187, 201, 58, 252, 253, 151, 18, 220, 176, 38, 236, 86, 223, 127, 153, 71, 211, 66, 207, 217, 225, 180, 144, 218, 123, 47, 89, 174, 242, 245, 196, 54, 146, 14, 114, 194, 1], -[1, 156, 178, 12, 73, 80, 144, 105, 189, 186, 232, 212, 176, 214, 231, 56, 255, 202, 158, 233, 111, 97, 226, 47, 136, 142, 50, 90, 162, 86, 52, 145, 4, 110, 198, 48, 35, 63, 62, 163, 242, 230, 157, 77, 190, 85, 153, 224, 249, 37, 118, 161, 187, 131, 133, 188, 30, 54, 200, 103, 134, 87, 208, 66, 16, 183, 21, 192, 140, 252, 248, 138, 197, 149, 114, 51, 246, 83, 98, 125, 225, 148, 215, 130, 234, 10, 18, 238, 120, 216, 29, 155, 22, 91, 61, 7, 64, 218, 84, 254, 46, 237, 221, 38, 17, 82, 199, 204, 213, 75, 135, 243, 129, 78, 89, 6, 165, 40, 72, 181, 223, 93, 116, 106, 88, 107, 244, 28, 256, 101, 79, 245, 184, 177, 113, 152, 68, 71, 25, 45, 81, 43, 26, 201, 2, 55, 99, 24, 146, 160, 31, 210, 121, 115, 207, 167, 95, 171, 205, 112, 253, 147, 59, 209, 222, 194, 195, 94, 15, 27, 100, 180, 67, 172, 104, 33, 8, 220, 139, 96, 70, 126, 124, 69, 227, 203, 57, 154, 123, 170, 49, 191, 241, 74, 236, 65, 117, 5, 9, 119, 60, 108, 143, 206, 11, 174, 159, 132, 32, 109, 42, 127, 23, 247, 239, 19, 137, 41, 228, 102, 235, 166, 196, 250, 193, 39, 173, 3, 211, 20, 36, 219, 240, 175, 58, 53, 44, 182, 122, 14, 128, 179, 168, 251, 92, 217, 185, 76, 34, 164, 141, 151, 169, 150, 13, 229, 1], -[1, 157, 234, 244, 15, 42, 169, 62, 225, 116, 222, 159, 34, 198, 246, 72, 253, 143, 92, 52, 197, 89, 95, 9, 128, 50, 140, 135, 121, 236, 44, 226, 16, 199, 146, 49, 240, 158, 134, 221, 2, 57, 211, 231, 30, 84, 81, 124, 193, 232, 187, 61, 68, 139, 235, 144, 249, 29, 184, 104, 137, 178, 190, 18, 256, 100, 23, 13, 242, 215, 88, 195, 32, 141, 35, 98, 223, 59, 11, 185, 4, 114, 165, 205, 60, 168, 162, 248, 129, 207, 117, 122, 136, 21, 213, 31, 241, 58, 111, 208, 17, 99, 123, 36, 255, 200, 46, 26, 227, 173, 176, 133, 64, 25, 70, 196, 189, 118, 22, 113, 8, 228, 73, 153, 120, 79, 67, 239, 1, 157, 234, 244, 15, 42, 169, 62, 225, 116, 222, 159, 34, 198, 246, 72, 253, 143, 92, 52, 197, 89, 95, 9, 128, 50, 140, 135, 121, 236, 44, 226, 16, 199, 146, 49, 240, 158, 134, 221, 2, 57, 211, 231, 30, 84, 81, 124, 193, 232, 187, 61, 68, 139, 235, 144, 249, 29, 184, 104, 137, 178, 190, 18, 256, 100, 23, 13, 242, 215, 88, 195, 32, 141, 35, 98, 223, 59, 11, 185, 4, 114, 165, 205, 60, 168, 162, 248, 129, 207, 117, 122, 136, 21, 213, 31, 241, 58, 111, 208, 17, 99, 123, 36, 255, 200, 46, 26, 227, 173, 176, 133, 64, 25, 70, 196, 189, 118, 22, 113, 8, 228, 73, 153, 120, 79, 67, 239, 1], -[1, 158, 35, 133, 197, 29, 213, 244, 2, 59, 70, 9, 137, 58, 169, 231, 4, 118, 140, 18, 17, 116, 81, 205, 8, 236, 23, 36, 34, 232, 162, 153, 16, 215, 46, 72, 68, 207, 67, 49, 32, 173, 92, 144, 136, 157, 134, 98, 64, 89, 184, 31, 15, 57, 11, 196, 128, 178, 111, 62, 30, 114, 22, 135, 256, 99, 222, 124, 60, 228, 44, 13, 255, 198, 187, 248, 120, 199, 88, 26, 253, 139, 117, 239, 240, 141, 176, 52, 249, 21, 234, 221, 223, 25, 95, 104, 241, 42, 211, 185, 189, 50, 190, 208, 225, 84, 165, 113, 121, 100, 123, 159, 193, 168, 73, 226, 242, 200, 246, 61, 129, 79, 146, 195, 227, 143, 235, 122, 1, 158, 35, 133, 197, 29, 213, 244, 2, 59, 70, 9, 137, 58, 169, 231, 4, 118, 140, 18, 17, 116, 81, 205, 8, 236, 23, 36, 34, 232, 162, 153, 16, 215, 46, 72, 68, 207, 67, 49, 32, 173, 92, 144, 136, 157, 134, 98, 64, 89, 184, 31, 15, 57, 11, 196, 128, 178, 111, 62, 30, 114, 22, 135, 256, 99, 222, 124, 60, 228, 44, 13, 255, 198, 187, 248, 120, 199, 88, 26, 253, 139, 117, 239, 240, 141, 176, 52, 249, 21, 234, 221, 223, 25, 95, 104, 241, 42, 211, 185, 189, 50, 190, 208, 225, 84, 165, 113, 121, 100, 123, 159, 193, 168, 73, 226, 242, 200, 246, 61, 129, 79, 146, 195, 227, 143, 235, 122, 1], -[1, 159, 95, 199, 30, 144, 23, 59, 129, 208, 176, 228, 15, 72, 140, 158, 193, 104, 88, 114, 136, 36, 70, 79, 225, 52, 44, 57, 68, 18, 35, 168, 241, 26, 22, 157, 34, 9, 146, 84, 249, 13, 11, 207, 17, 133, 73, 42, 253, 135, 134, 232, 137, 195, 165, 21, 255, 196, 67, 116, 197, 226, 211, 139, 256, 98, 162, 58, 227, 113, 234, 198, 128, 49, 81, 29, 242, 185, 117, 99, 64, 153, 169, 143, 121, 221, 187, 178, 32, 205, 213, 200, 189, 239, 222, 89, 16, 231, 235, 100, 223, 248, 111, 173, 8, 244, 246, 50, 240, 124, 184, 215, 4, 122, 123, 25, 120, 62, 92, 236, 2, 61, 190, 141, 60, 31, 46, 118, 1, 159, 95, 199, 30, 144, 23, 59, 129, 208, 176, 228, 15, 72, 140, 158, 193, 104, 88, 114, 136, 36, 70, 79, 225, 52, 44, 57, 68, 18, 35, 168, 241, 26, 22, 157, 34, 9, 146, 84, 249, 13, 11, 207, 17, 133, 73, 42, 253, 135, 134, 232, 137, 195, 165, 21, 255, 196, 67, 116, 197, 226, 211, 139, 256, 98, 162, 58, 227, 113, 234, 198, 128, 49, 81, 29, 242, 185, 117, 99, 64, 153, 169, 143, 121, 221, 187, 178, 32, 205, 213, 200, 189, 239, 222, 89, 16, 231, 235, 100, 223, 248, 111, 173, 8, 244, 246, 50, 240, 124, 184, 215, 4, 122, 123, 25, 120, 62, 92, 236, 2, 61, 190, 141, 60, 31, 46, 118, 1], -[1, 160, 157, 191, 234, 175, 244, 233, 15, 87, 42, 38, 169, 55, 62, 154, 225, 20, 116, 56, 222, 54, 159, 254, 34, 43, 198, 69, 246, 39, 72, 212, 253, 131, 143, 7, 92, 71, 52, 96, 197, 166, 89, 105, 95, 37, 9, 155, 128, 177, 50, 33, 140, 41, 135, 12, 121, 85, 236, 238, 44, 101, 226, 180, 16, 247, 199, 229, 146, 230, 49, 130, 240, 107, 158, 94, 134, 109, 221, 151, 2, 63, 57, 125, 211, 93, 231, 209, 30, 174, 84, 76, 81, 110, 124, 51, 193, 40, 232, 112, 187, 108, 61, 251, 68, 86, 139, 138, 235, 78, 144, 167, 249, 5, 29, 14, 184, 142, 104, 192, 137, 75, 178, 210, 190, 74, 18, 53, 256, 97, 100, 66, 23, 82, 13, 24, 242, 170, 215, 219, 88, 202, 195, 103, 32, 237, 141, 201, 35, 203, 98, 3, 223, 214, 59, 188, 11, 218, 185, 45, 4, 126, 114, 250, 165, 186, 205, 161, 60, 91, 168, 152, 162, 220, 248, 102, 129, 80, 207, 224, 117, 216, 122, 245, 136, 172, 21, 19, 213, 156, 31, 77, 241, 10, 58, 28, 111, 27, 208, 127, 17, 150, 99, 163, 123, 148, 36, 106, 255, 194, 200, 132, 46, 164, 26, 48, 227, 83, 173, 181, 176, 147, 133, 206, 64, 217, 25, 145, 70, 149, 196, 6, 189, 171, 118, 119, 22, 179, 113, 90, 8, 252, 228, 243, 73, 115, 153, 65, 120, 182, 79, 47, 67, 183, 239, 204, 1], -[1, 161, 221, 115, 11, 229, 118, 237, 121, 206, 13, 37, 46, 210, 143, 150, 249, 254, 31, 108, 169, 224, 84, 160, 60, 151, 153, 218, 146, 119, 141, 85, 64, 24, 9, 164, 190, 7, 99, 5, 34, 77, 61, 55, 117, 76, 157, 91, 2, 65, 185, 230, 22, 201, 236, 217, 242, 155, 26, 74, 92, 163, 29, 43, 241, 251, 62, 216, 81, 191, 168, 63, 120, 45, 49, 179, 35, 238, 25, 170, 128, 48, 18, 71, 123, 14, 198, 10, 68, 154, 122, 110, 234, 152, 57, 182, 4, 130, 113, 203, 44, 145, 215, 177, 227, 53, 52, 148, 184, 69, 58, 86, 225, 245, 124, 175, 162, 125, 79, 126, 240, 90, 98, 101, 70, 219, 50, 83, 256, 96, 36, 142, 246, 28, 139, 20, 136, 51, 244, 220, 211, 47, 114, 107, 8, 3, 226, 149, 88, 33, 173, 97, 197, 106, 104, 39, 111, 138, 116, 172, 193, 233, 248, 93, 67, 250, 158, 252, 223, 180, 196, 202, 140, 181, 100, 166, 255, 192, 72, 27, 235, 56, 21, 40, 15, 102, 231, 183, 165, 94, 228, 214, 16, 6, 195, 41, 176, 66, 89, 194, 137, 212, 208, 78, 222, 19, 232, 87, 129, 209, 239, 186, 134, 243, 59, 247, 189, 103, 135, 147, 23, 105, 200, 75, 253, 127, 144, 54, 213, 112, 42, 80, 30, 204, 205, 109, 73, 188, 199, 171, 32, 12, 133, 82, 95, 132, 178, 131, 17, 167, 159, 156, 187, 38, 207, 174, 1], -[1, 162, 30, 234, 129, 81, 15, 117, 193, 169, 136, 187, 225, 213, 68, 222, 241, 235, 34, 111, 249, 246, 17, 184, 253, 123, 137, 92, 255, 190, 197, 46, 256, 95, 227, 23, 128, 176, 242, 140, 64, 88, 121, 70, 32, 44, 189, 35, 16, 22, 223, 146, 8, 11, 240, 73, 4, 134, 120, 165, 2, 67, 60, 211, 1, 162, 30, 234, 129, 81, 15, 117, 193, 169, 136, 187, 225, 213, 68, 222, 241, 235, 34, 111, 249, 246, 17, 184, 253, 123, 137, 92, 255, 190, 197, 46, 256, 95, 227, 23, 128, 176, 242, 140, 64, 88, 121, 70, 32, 44, 189, 35, 16, 22, 223, 146, 8, 11, 240, 73, 4, 134, 120, 165, 2, 67, 60, 211, 1, 162, 30, 234, 129, 81, 15, 117, 193, 169, 136, 187, 225, 213, 68, 222, 241, 235, 34, 111, 249, 246, 17, 184, 253, 123, 137, 92, 255, 190, 197, 46, 256, 95, 227, 23, 128, 176, 242, 140, 64, 88, 121, 70, 32, 44, 189, 35, 16, 22, 223, 146, 8, 11, 240, 73, 4, 134, 120, 165, 2, 67, 60, 211, 1, 162, 30, 234, 129, 81, 15, 117, 193, 169, 136, 187, 225, 213, 68, 222, 241, 235, 34, 111, 249, 246, 17, 184, 253, 123, 137, 92, 255, 190, 197, 46, 256, 95, 227, 23, 128, 176, 242, 140, 64, 88, 121, 70, 32, 44, 189, 35, 16, 22, 223, 146, 8, 11, 240, 73, 4, 134, 120, 165, 2, 67, 60, 211, 1], -[1, 163, 98, 40, 95, 65, 58, 202, 30, 7, 113, 172, 23, 151, 198, 149, 129, 210, 49, 20, 176, 161, 29, 101, 15, 132, 185, 86, 140, 204, 99, 203, 193, 105, 153, 10, 88, 209, 143, 179, 136, 66, 221, 43, 70, 102, 178, 230, 225, 181, 205, 5, 44, 233, 200, 218, 68, 33, 239, 150, 35, 51, 89, 115, 241, 219, 231, 131, 22, 245, 100, 109, 34, 145, 248, 75, 146, 154, 173, 186, 249, 238, 244, 194, 11, 251, 50, 183, 17, 201, 124, 166, 73, 77, 215, 93, 253, 119, 122, 97, 134, 254, 25, 220, 137, 229, 62, 83, 165, 167, 236, 175, 255, 188, 61, 177, 67, 127, 141, 110, 197, 243, 31, 170, 211, 212, 118, 216, 256, 94, 159, 217, 162, 192, 199, 55, 227, 250, 144, 85, 234, 106, 59, 108, 128, 47, 208, 237, 81, 96, 228, 156, 242, 125, 72, 171, 117, 53, 158, 54, 64, 152, 104, 247, 169, 48, 114, 78, 121, 191, 36, 214, 187, 155, 79, 27, 32, 76, 52, 252, 213, 24, 57, 39, 189, 224, 18, 107, 222, 206, 168, 142, 16, 38, 26, 126, 235, 12, 157, 148, 223, 112, 9, 182, 111, 103, 84, 71, 8, 19, 13, 63, 246, 6, 207, 74, 240, 56, 133, 91, 184, 180, 42, 164, 4, 138, 135, 160, 123, 3, 232, 37, 120, 28, 195, 174, 92, 90, 21, 82, 2, 69, 196, 80, 190, 130, 116, 147, 60, 14, 226, 87, 46, 45, 139, 41, 1], -[1, 164, 168, 53, 211, 166, 239, 132, 60, 74, 57, 96, 67, 194, 205, 210, 2, 71, 79, 106, 165, 75, 221, 7, 120, 148, 114, 192, 134, 131, 153, 163, 4, 142, 158, 212, 73, 150, 185, 14, 240, 39, 228, 127, 11, 5, 49, 69, 8, 27, 59, 167, 146, 43, 113, 28, 223, 78, 199, 254, 22, 10, 98, 138, 16, 54, 118, 77, 35, 86, 226, 56, 189, 156, 141, 251, 44, 20, 196, 19, 32, 108, 236, 154, 70, 172, 195, 112, 121, 55, 25, 245, 88, 40, 135, 38, 64, 216, 215, 51, 140, 87, 133, 224, 242, 110, 50, 233, 176, 80, 13, 76, 128, 175, 173, 102, 23, 174, 9, 191, 227, 220, 100, 209, 95, 160, 26, 152, 256, 93, 89, 204, 46, 91, 18, 125, 197, 183, 200, 161, 190, 63, 52, 47, 255, 186, 178, 151, 92, 182, 36, 250, 137, 109, 143, 65, 123, 126, 104, 94, 253, 115, 99, 45, 184, 107, 72, 243, 17, 218, 29, 130, 246, 252, 208, 188, 249, 230, 198, 90, 111, 214, 144, 229, 34, 179, 58, 3, 235, 247, 159, 119, 241, 203, 139, 180, 222, 171, 31, 201, 68, 101, 116, 6, 213, 237, 61, 238, 225, 149, 21, 103, 187, 85, 62, 145, 136, 202, 232, 12, 169, 217, 122, 219, 193, 41, 42, 206, 117, 170, 124, 33, 15, 147, 207, 24, 81, 177, 244, 181, 129, 82, 84, 155, 234, 83, 248, 66, 30, 37, 157, 48, 162, 97, 231, 105, 1], -[1, 165, 240, 22, 32, 140, 227, 190, 253, 111, 68, 169, 129, 211, 120, 11, 16, 70, 242, 95, 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, 121, 176, 256, 92, 17, 235, 225, 117, 30, 67, 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, 15, 162, 2, 73, 223, 44, 64, 23, 197, 123, 249, 222, 136, 81, 1, 165, 240, 22, 32, 140, 227, 190, 253, 111, 68, 169, 129, 211, 120, 11, 16, 70, 242, 95, 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, 121, 176, 256, 92, 17, 235, 225, 117, 30, 67, 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, 15, 162, 2, 73, 223, 44, 64, 23, 197, 123, 249, 222, 136, 81, 1, 165, 240, 22, 32, 140, 227, 190, 253, 111, 68, 169, 129, 211, 120, 11, 16, 70, 242, 95, 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, 121, 176, 256, 92, 17, 235, 225, 117, 30, 67, 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, 15, 162, 2, 73, 223, 44, 64, 23, 197, 123, 249, 222, 136, 81, 1, 165, 240, 22, 32, 140, 227, 190, 253, 111, 68, 169, 129, 211, 120, 11, 16, 70, 242, 95, 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, 121, 176, 256, 92, 17, 235, 225, 117, 30, 67, 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, 15, 162, 2, 73, 223, 44, 64, 23, 197, 123, 249, 222, 136, 81, 1], -[1, 166, 57, 210, 165, 148, 153, 212, 240, 5, 59, 28, 22, 54, 226, 251, 32, 172, 25, 38, 140, 110, 13, 102, 227, 160, 89, 125, 190, 186, 36, 65, 253, 107, 29, 188, 111, 179, 159, 180, 68, 237, 21, 145, 169, 41, 124, 24, 129, 83, 157, 105, 211, 74, 205, 106, 120, 131, 158, 14, 11, 27, 113, 254, 16, 86, 141, 19, 70, 55, 135, 51, 242, 80, 173, 191, 95, 93, 18, 161, 255, 182, 143, 94, 184, 218, 208, 90, 34, 247, 139, 201, 213, 149, 62, 12, 193, 170, 207, 181, 234, 37, 231, 53, 60, 194, 79, 7, 134, 142, 185, 127, 8, 43, 199, 138, 35, 156, 196, 154, 121, 40, 215, 224, 176, 175, 9, 209, 256, 91, 200, 47, 92, 109, 104, 45, 17, 252, 198, 229, 235, 203, 31, 6, 225, 85, 232, 219, 117, 147, 244, 155, 30, 97, 168, 132, 67, 71, 221, 192, 4, 150, 228, 69, 146, 78, 98, 77, 189, 20, 236, 112, 88, 216, 133, 233, 128, 174, 100, 152, 46, 183, 52, 151, 137, 126, 99, 243, 246, 230, 144, 3, 241, 171, 116, 238, 187, 202, 122, 206, 15, 177, 84, 66, 162, 164, 239, 96, 2, 75, 114, 163, 73, 39, 49, 167, 223, 10, 118, 56, 44, 108, 195, 245, 64, 87, 50, 76, 23, 220, 26, 204, 197, 63, 178, 250, 123, 115, 72, 130, 249, 214, 58, 119, 222, 101, 61, 103, 136, 217, 42, 33, 81, 82, 248, 48, 1], -[1, 167, 133, 109, 213, 105, 59, 87, 137, 6, 231, 27, 140, 250, 116, 97, 8, 51, 36, 101, 162, 69, 215, 182, 68, 48, 49, 216, 92, 201, 157, 5, 64, 151, 31, 37, 11, 38, 178, 171, 30, 127, 135, 186, 222, 66, 228, 40, 255, 180, 248, 39, 88, 47, 139, 83, 240, 245, 52, 203, 234, 14, 25, 63, 241, 155, 185, 55, 190, 119, 84, 150, 121, 161, 159, 82, 73, 112, 200, 247, 129, 212, 195, 183, 235, 181, 158, 172, 197, 3, 244, 142, 70, 125, 58, 177, 4, 154, 18, 179, 81, 163, 236, 91, 34, 24, 153, 108, 46, 229, 207, 131, 32, 204, 144, 147, 134, 19, 89, 214, 15, 192, 196, 93, 111, 33, 114, 20, 256, 90, 124, 148, 44, 152, 198, 170, 120, 251, 26, 230, 117, 7, 141, 160, 249, 206, 221, 156, 95, 188, 42, 75, 189, 209, 208, 41, 165, 56, 100, 252, 193, 106, 226, 220, 246, 219, 79, 86, 227, 130, 122, 71, 35, 191, 29, 217, 2, 77, 9, 218, 169, 210, 118, 174, 17, 12, 205, 54, 23, 243, 232, 194, 16, 102, 72, 202, 67, 138, 173, 107, 136, 96, 98, 175, 184, 145, 57, 10, 128, 45, 62, 74, 22, 76, 99, 85, 60, 254, 13, 115, 187, 132, 199, 80, 253, 103, 239, 78, 176, 94, 21, 166, 223, 233, 104, 149, 211, 28, 50, 126, 225, 53, 113, 110, 123, 238, 168, 43, 242, 65, 61, 164, 146, 224, 143, 237, 1], -[1, 168, 211, 239, 60, 57, 67, 205, 2, 79, 165, 221, 120, 114, 134, 153, 4, 158, 73, 185, 240, 228, 11, 49, 8, 59, 146, 113, 223, 199, 22, 98, 16, 118, 35, 226, 189, 141, 44, 196, 32, 236, 70, 195, 121, 25, 88, 135, 64, 215, 140, 133, 242, 50, 176, 13, 128, 173, 23, 9, 227, 100, 95, 26, 256, 89, 46, 18, 197, 200, 190, 52, 255, 178, 92, 36, 137, 143, 123, 104, 253, 99, 184, 72, 17, 29, 246, 208, 249, 198, 111, 144, 34, 58, 235, 159, 241, 139, 222, 31, 68, 116, 213, 61, 225, 21, 187, 62, 136, 232, 169, 122, 193, 42, 117, 124, 15, 207, 81, 244, 129, 84, 234, 248, 30, 157, 162, 231, 1, 168, 211, 239, 60, 57, 67, 205, 2, 79, 165, 221, 120, 114, 134, 153, 4, 158, 73, 185, 240, 228, 11, 49, 8, 59, 146, 113, 223, 199, 22, 98, 16, 118, 35, 226, 189, 141, 44, 196, 32, 236, 70, 195, 121, 25, 88, 135, 64, 215, 140, 133, 242, 50, 176, 13, 128, 173, 23, 9, 227, 100, 95, 26, 256, 89, 46, 18, 197, 200, 190, 52, 255, 178, 92, 36, 137, 143, 123, 104, 253, 99, 184, 72, 17, 29, 246, 208, 249, 198, 111, 144, 34, 58, 235, 159, 241, 139, 222, 31, 68, 116, 213, 61, 225, 21, 187, 62, 136, 232, 169, 122, 193, 42, 117, 124, 15, 207, 81, 244, 129, 84, 234, 248, 30, 157, 162, 231, 1], -[1, 169, 34, 92, 128, 44, 240, 211, 193, 235, 137, 23, 32, 11, 60, 117, 241, 123, 227, 70, 8, 67, 15, 222, 253, 95, 121, 146, 2, 81, 68, 184, 256, 88, 223, 165, 129, 213, 17, 46, 64, 22, 120, 234, 225, 246, 197, 140, 16, 134, 30, 187, 249, 190, 242, 35, 4, 162, 136, 111, 255, 176, 189, 73, 1, 169, 34, 92, 128, 44, 240, 211, 193, 235, 137, 23, 32, 11, 60, 117, 241, 123, 227, 70, 8, 67, 15, 222, 253, 95, 121, 146, 2, 81, 68, 184, 256, 88, 223, 165, 129, 213, 17, 46, 64, 22, 120, 234, 225, 246, 197, 140, 16, 134, 30, 187, 249, 190, 242, 35, 4, 162, 136, 111, 255, 176, 189, 73, 1, 169, 34, 92, 128, 44, 240, 211, 193, 235, 137, 23, 32, 11, 60, 117, 241, 123, 227, 70, 8, 67, 15, 222, 253, 95, 121, 146, 2, 81, 68, 184, 256, 88, 223, 165, 129, 213, 17, 46, 64, 22, 120, 234, 225, 246, 197, 140, 16, 134, 30, 187, 249, 190, 242, 35, 4, 162, 136, 111, 255, 176, 189, 73, 1, 169, 34, 92, 128, 44, 240, 211, 193, 235, 137, 23, 32, 11, 60, 117, 241, 123, 227, 70, 8, 67, 15, 222, 253, 95, 121, 146, 2, 81, 68, 184, 256, 88, 223, 165, 129, 213, 17, 46, 64, 22, 120, 234, 225, 246, 197, 140, 16, 134, 30, 187, 249, 190, 242, 35, 4, 162, 136, 111, 255, 176, 189, 73, 1], -[1, 170, 116, 188, 92, 220, 135, 77, 240, 194, 84, 145, 235, 115, 18, 233, 32, 43, 114, 105, 117, 101, 208, 151, 227, 40, 118, 14, 67, 82, 62, 3, 253, 91, 50, 19, 146, 148, 231, 206, 68, 252, 178, 191, 88, 54, 185, 96, 129, 85, 58, 94, 46, 110, 196, 167, 120, 97, 42, 201, 246, 186, 9, 245, 16, 150, 57, 181, 187, 179, 104, 204, 242, 20, 59, 7, 162, 41, 31, 130, 255, 174, 25, 138, 73, 74, 244, 103, 34, 126, 89, 224, 44, 27, 221, 48, 193, 171, 29, 47, 23, 55, 98, 212, 60, 177, 21, 229, 123, 93, 133, 251, 8, 75, 157, 219, 222, 218, 52, 102, 121, 10, 158, 132, 81, 149, 144, 65, 256, 87, 141, 69, 165, 37, 122, 180, 17, 63, 173, 112, 22, 142, 239, 24, 225, 214, 143, 152, 140, 156, 49, 106, 30, 217, 139, 243, 190, 175, 195, 254, 4, 166, 207, 238, 111, 109, 26, 51, 189, 5, 79, 66, 169, 203, 72, 161, 128, 172, 199, 163, 211, 147, 61, 90, 137, 160, 215, 56, 11, 71, 248, 12, 241, 107, 200, 76, 70, 78, 153, 53, 15, 237, 198, 250, 95, 216, 226, 127, 2, 83, 232, 119, 184, 183, 13, 154, 223, 131, 168, 33, 213, 230, 36, 209, 64, 86, 228, 210, 234, 202, 159, 45, 197, 80, 236, 28, 134, 164, 124, 6, 249, 182, 100, 38, 35, 39, 205, 155, 136, 247, 99, 125, 176, 108, 113, 192, 1], -[1, 171, 200, 19, 165, 202, 104, 51, 240, 177, 198, 191, 22, 164, 31, 161, 32, 75, 232, 94, 140, 39, 244, 90, 227, 10, 168, 201, 190, 108, 221, 12, 253, 87, 228, 181, 111, 220, 98, 53, 68, 63, 236, 7, 169, 115, 133, 127, 129, 214, 100, 138, 211, 101, 52, 154, 120, 217, 99, 224, 11, 82, 144, 209, 16, 166, 116, 47, 70, 148, 122, 45, 242, 5, 84, 229, 95, 54, 239, 6, 255, 172, 114, 219, 184, 110, 49, 155, 34, 160, 118, 132, 213, 186, 195, 192, 193, 107, 50, 69, 234, 179, 26, 77, 60, 237, 178, 112, 134, 41, 72, 233, 8, 83, 58, 152, 35, 74, 61, 151, 121, 131, 42, 243, 176, 27, 248, 3, 256, 86, 57, 238, 92, 55, 153, 206, 17, 80, 59, 66, 235, 93, 226, 96, 225, 182, 25, 163, 117, 218, 13, 167, 30, 247, 89, 56, 67, 149, 36, 245, 4, 170, 29, 76, 146, 37, 159, 204, 189, 194, 21, 250, 88, 142, 124, 130, 128, 43, 157, 119, 46, 156, 205, 103, 137, 40, 158, 33, 246, 175, 113, 48, 241, 91, 141, 210, 187, 109, 135, 212, 15, 252, 173, 28, 162, 203, 18, 251, 2, 85, 143, 38, 73, 147, 208, 102, 223, 97, 139, 125, 44, 71, 62, 65, 64, 150, 207, 188, 23, 78, 231, 180, 197, 20, 79, 145, 123, 216, 185, 24, 249, 174, 199, 105, 222, 183, 196, 106, 136, 126, 215, 14, 81, 230, 9, 254, 1], -[1, 172, 29, 105, 70, 218, 231, 154, 17, 97, 236, 243, 162, 108, 72, 48, 32, 107, 157, 19, 184, 37, 196, 45, 30, 20, 99, 66, 44, 115, 248, 251, 253, 83, 141, 94, 234, 156, 104, 155, 189, 126, 84, 56, 123, 82, 226, 65, 129, 86, 143, 181, 35, 109, 244, 77, 137, 177, 118, 250, 81, 54, 36, 24, 16, 182, 207, 138, 92, 147, 98, 151, 15, 10, 178, 33, 22, 186, 124, 254, 255, 170, 199, 47, 117, 78, 52, 206, 223, 63, 42, 28, 190, 41, 113, 161, 193, 43, 200, 219, 146, 183, 122, 167, 197, 217, 59, 125, 169, 27, 18, 12, 8, 91, 232, 69, 46, 202, 49, 204, 136, 5, 89, 145, 11, 93, 62, 127, 256, 85, 228, 152, 187, 39, 26, 103, 240, 160, 21, 14, 95, 149, 185, 209, 225, 150, 100, 238, 73, 220, 61, 212, 227, 237, 158, 191, 213, 142, 9, 6, 4, 174, 116, 163, 23, 101, 153, 102, 68, 131, 173, 201, 134, 175, 31, 192, 128, 171, 114, 76, 222, 148, 13, 180, 120, 80, 139, 7, 176, 203, 221, 233, 241, 75, 50, 119, 165, 110, 159, 106, 242, 247, 79, 224, 235, 71, 133, 3, 2, 87, 58, 210, 140, 179, 205, 51, 34, 194, 215, 229, 67, 216, 144, 96, 64, 214, 57, 38, 111, 74, 135, 90, 60, 40, 198, 132, 88, 230, 239, 245, 249, 166, 25, 188, 211, 55, 208, 53, 121, 252, 168, 112, 246, 164, 195, 130, 1], -[1, 173, 117, 195, 68, 199, 246, 153, 255, 168, 23, 124, 121, 116, 22, 208, 4, 178, 211, 9, 15, 25, 213, 98, 249, 158, 92, 239, 227, 207, 88, 61, 16, 198, 73, 36, 60, 100, 81, 135, 225, 118, 111, 185, 137, 57, 95, 244, 64, 21, 35, 144, 240, 143, 67, 26, 129, 215, 187, 226, 34, 228, 123, 205, 256, 84, 140, 62, 189, 58, 11, 104, 2, 89, 234, 133, 136, 141, 235, 49, 253, 79, 46, 248, 242, 232, 44, 159, 8, 99, 165, 18, 30, 50, 169, 196, 241, 59, 184, 221, 197, 157, 176, 122, 32, 139, 146, 72, 120, 200, 162, 13, 193, 236, 222, 113, 17, 114, 190, 231, 128, 42, 70, 31, 223, 29, 134, 52, 1, 173, 117, 195, 68, 199, 246, 153, 255, 168, 23, 124, 121, 116, 22, 208, 4, 178, 211, 9, 15, 25, 213, 98, 249, 158, 92, 239, 227, 207, 88, 61, 16, 198, 73, 36, 60, 100, 81, 135, 225, 118, 111, 185, 137, 57, 95, 244, 64, 21, 35, 144, 240, 143, 67, 26, 129, 215, 187, 226, 34, 228, 123, 205, 256, 84, 140, 62, 189, 58, 11, 104, 2, 89, 234, 133, 136, 141, 235, 49, 253, 79, 46, 248, 242, 232, 44, 159, 8, 99, 165, 18, 30, 50, 169, 196, 241, 59, 184, 221, 197, 157, 176, 122, 32, 139, 146, 72, 120, 200, 162, 13, 193, 236, 222, 113, 17, 114, 190, 231, 128, 42, 70, 31, 223, 29, 134, 52, 1], -[1, 174, 207, 38, 187, 156, 159, 167, 17, 131, 178, 132, 95, 82, 133, 12, 32, 171, 199, 188, 73, 109, 205, 204, 30, 80, 42, 112, 213, 54, 144, 127, 253, 75, 200, 105, 23, 147, 135, 103, 189, 247, 59, 243, 134, 186, 239, 209, 129, 87, 232, 19, 222, 78, 208, 212, 137, 194, 89, 66, 176, 41, 195, 6, 16, 214, 228, 94, 165, 183, 231, 102, 15, 40, 21, 56, 235, 27, 72, 192, 255, 166, 100, 181, 140, 202, 196, 180, 223, 252, 158, 250, 67, 93, 248, 233, 193, 172, 116, 138, 111, 39, 104, 106, 197, 97, 173, 33, 88, 149, 226, 3, 8, 107, 114, 47, 211, 220, 244, 51, 136, 20, 139, 28, 246, 142, 36, 96, 256, 83, 50, 219, 70, 101, 98, 90, 240, 126, 79, 125, 162, 175, 124, 245, 225, 86, 58, 69, 184, 148, 52, 53, 227, 177, 215, 145, 44, 203, 113, 130, 4, 182, 57, 152, 234, 110, 122, 154, 68, 10, 198, 14, 123, 71, 18, 48, 128, 170, 25, 238, 35, 179, 49, 45, 120, 63, 168, 191, 81, 216, 62, 251, 241, 43, 29, 163, 92, 74, 26, 155, 242, 217, 236, 201, 22, 230, 185, 65, 2, 91, 157, 76, 117, 55, 61, 77, 34, 5, 99, 7, 190, 164, 9, 24, 64, 85, 141, 119, 146, 218, 153, 151, 60, 160, 84, 224, 169, 108, 31, 254, 249, 150, 143, 210, 46, 37, 13, 206, 121, 237, 118, 229, 11, 115, 221, 161, 1], -[1, 175, 42, 154, 222, 43, 72, 7, 197, 37, 50, 12, 44, 247, 49, 94, 2, 93, 84, 51, 187, 86, 144, 14, 137, 74, 100, 24, 88, 237, 98, 188, 4, 186, 168, 102, 117, 172, 31, 28, 17, 148, 200, 48, 176, 217, 196, 119, 8, 115, 79, 204, 234, 87, 62, 56, 34, 39, 143, 96, 95, 177, 135, 238, 16, 230, 158, 151, 211, 174, 124, 112, 68, 78, 29, 192, 190, 97, 13, 219, 32, 203, 59, 45, 165, 91, 248, 224, 136, 156, 58, 127, 123, 194, 26, 181, 64, 149, 118, 90, 73, 182, 239, 191, 15, 55, 116, 254, 246, 131, 52, 105, 128, 41, 236, 180, 146, 107, 221, 125, 30, 110, 232, 251, 235, 5, 104, 210, 256, 82, 215, 103, 35, 214, 185, 250, 60, 220, 207, 245, 213, 10, 208, 163, 255, 164, 173, 206, 70, 171, 113, 243, 120, 183, 157, 233, 169, 20, 159, 69, 253, 71, 89, 155, 140, 85, 226, 229, 240, 109, 57, 209, 81, 40, 61, 138, 249, 142, 178, 53, 23, 170, 195, 201, 223, 218, 114, 161, 162, 80, 122, 19, 241, 27, 99, 106, 46, 83, 133, 145, 189, 179, 228, 65, 67, 160, 244, 38, 225, 54, 198, 212, 92, 166, 9, 33, 121, 101, 199, 130, 134, 63, 231, 76, 193, 108, 139, 167, 184, 75, 18, 66, 242, 202, 141, 3, 11, 126, 205, 152, 129, 216, 21, 77, 111, 150, 36, 132, 227, 147, 25, 6, 22, 252, 153, 47, 1], -[1, 176, 136, 35, 249, 134, 197, 234, 64, 213, 223, 184, 2, 95, 15, 70, 241, 11, 137, 211, 128, 169, 189, 111, 4, 190, 30, 140, 225, 22, 17, 165, 256, 81, 121, 222, 8, 123, 60, 23, 193, 44, 34, 73, 255, 162, 242, 187, 16, 246, 120, 46, 129, 88, 68, 146, 253, 67, 227, 117, 32, 235, 240, 92, 1, 176, 136, 35, 249, 134, 197, 234, 64, 213, 223, 184, 2, 95, 15, 70, 241, 11, 137, 211, 128, 169, 189, 111, 4, 190, 30, 140, 225, 22, 17, 165, 256, 81, 121, 222, 8, 123, 60, 23, 193, 44, 34, 73, 255, 162, 242, 187, 16, 246, 120, 46, 129, 88, 68, 146, 253, 67, 227, 117, 32, 235, 240, 92, 1, 176, 136, 35, 249, 134, 197, 234, 64, 213, 223, 184, 2, 95, 15, 70, 241, 11, 137, 211, 128, 169, 189, 111, 4, 190, 30, 140, 225, 22, 17, 165, 256, 81, 121, 222, 8, 123, 60, 23, 193, 44, 34, 73, 255, 162, 242, 187, 16, 246, 120, 46, 129, 88, 68, 146, 253, 67, 227, 117, 32, 235, 240, 92, 1, 176, 136, 35, 249, 134, 197, 234, 64, 213, 223, 184, 2, 95, 15, 70, 241, 11, 137, 211, 128, 169, 189, 111, 4, 190, 30, 140, 225, 22, 17, 165, 256, 81, 121, 222, 8, 123, 60, 23, 193, 44, 34, 73, 255, 162, 242, 187, 16, 246, 120, 46, 129, 88, 68, 146, 253, 67, 227, 117, 32, 235, 240, 92, 1], -[1, 177, 232, 201, 111, 115, 52, 209, 242, 172, 118, 69, 134, 74, 248, 206, 225, 247, 29, 250, 46, 175, 135, 251, 223, 150, 79, 105, 81, 202, 31, 90, 253, 63, 100, 224, 70, 54, 49, 192, 60, 83, 42, 238, 235, 218, 36, 204, 128, 40, 141, 28, 73, 71, 231, 24, 136, 171, 198, 94, 190, 220, 133, 154, 16, 5, 114, 132, 234, 41, 61, 3, 17, 182, 89, 76, 88, 156, 113, 212, 2, 97, 207, 145, 222, 230, 104, 161, 227, 87, 236, 138, 11, 148, 239, 155, 193, 237, 58, 243, 92, 93, 13, 245, 189, 43, 158, 210, 162, 147, 62, 180, 249, 126, 200, 191, 140, 108, 98, 127, 120, 166, 84, 219, 213, 179, 72, 151, 256, 80, 25, 56, 146, 142, 205, 48, 15, 85, 139, 188, 123, 183, 9, 51, 32, 10, 228, 7, 211, 82, 122, 6, 34, 107, 178, 152, 176, 55, 226, 167, 4, 194, 157, 33, 187, 203, 208, 65, 197, 174, 215, 19, 22, 39, 221, 53, 129, 217, 116, 229, 184, 186, 26, 233, 121, 86, 59, 163, 67, 37, 124, 103, 241, 252, 143, 125, 23, 216, 196, 254, 240, 75, 168, 181, 169, 101, 144, 45, 255, 160, 50, 112, 35, 27, 153, 96, 30, 170, 21, 119, 246, 109, 18, 102, 64, 20, 199, 14, 165, 164, 244, 12, 68, 214, 99, 47, 95, 110, 195, 77, 8, 131, 57, 66, 117, 149, 159, 130, 137, 91, 173, 38, 44, 78, 185, 106, 1], -[1, 178, 73, 144, 189, 232, 176, 231, 255, 158, 111, 226, 136, 50, 162, 52, 4, 198, 35, 62, 242, 157, 190, 153, 249, 118, 187, 133, 30, 200, 134, 208, 16, 21, 140, 248, 197, 114, 246, 98, 225, 215, 234, 18, 120, 29, 22, 61, 64, 84, 46, 221, 17, 199, 213, 135, 129, 89, 165, 72, 223, 116, 88, 244, 256, 79, 184, 113, 68, 25, 81, 26, 2, 99, 146, 31, 121, 207, 95, 205, 253, 59, 222, 195, 15, 100, 67, 104, 8, 139, 70, 124, 227, 57, 123, 49, 241, 236, 117, 9, 60, 143, 11, 159, 32, 42, 23, 239, 137, 228, 235, 196, 193, 173, 211, 36, 240, 58, 44, 122, 128, 168, 92, 185, 34, 141, 169, 13, 1, 178, 73, 144, 189, 232, 176, 231, 255, 158, 111, 226, 136, 50, 162, 52, 4, 198, 35, 62, 242, 157, 190, 153, 249, 118, 187, 133, 30, 200, 134, 208, 16, 21, 140, 248, 197, 114, 246, 98, 225, 215, 234, 18, 120, 29, 22, 61, 64, 84, 46, 221, 17, 199, 213, 135, 129, 89, 165, 72, 223, 116, 88, 244, 256, 79, 184, 113, 68, 25, 81, 26, 2, 99, 146, 31, 121, 207, 95, 205, 253, 59, 222, 195, 15, 100, 67, 104, 8, 139, 70, 124, 227, 57, 123, 49, 241, 236, 117, 9, 60, 143, 11, 159, 32, 42, 23, 239, 137, 228, 235, 196, 193, 173, 211, 36, 240, 58, 44, 122, 128, 168, 92, 185, 34, 141, 169, 13, 1], -[1, 179, 173, 127, 117, 126, 195, 210, 68, 93, 199, 155, 246, 87, 153, 145, 255, 156, 168, 3, 23, 5, 124, 94, 121, 71, 116, 204, 22, 83, 208, 224, 4, 202, 178, 251, 211, 247, 9, 69, 15, 115, 25, 106, 213, 91, 98, 66, 249, 110, 158, 12, 92, 20, 239, 119, 227, 27, 207, 45, 88, 75, 61, 125, 16, 37, 198, 233, 73, 217, 36, 19, 60, 203, 100, 167, 81, 107, 135, 7, 225, 183, 118, 48, 111, 80, 185, 219, 137, 108, 57, 180, 95, 43, 244, 243, 64, 148, 21, 161, 35, 97, 144, 76, 240, 41, 143, 154, 67, 171, 26, 28, 129, 218, 215, 192, 187, 63, 226, 105, 34, 175, 228, 206, 123, 172, 205, 201, 256, 78, 84, 130, 140, 131, 62, 47, 189, 164, 58, 102, 11, 170, 104, 112, 2, 101, 89, 254, 234, 252, 133, 163, 136, 186, 141, 53, 235, 174, 49, 33, 253, 55, 79, 6, 46, 10, 248, 188, 242, 142, 232, 151, 44, 166, 159, 191, 8, 147, 99, 245, 165, 237, 18, 138, 30, 230, 50, 212, 169, 182, 196, 132, 241, 220, 59, 24, 184, 40, 221, 238, 197, 54, 157, 90, 176, 150, 122, 250, 32, 74, 139, 209, 146, 177, 72, 38, 120, 149, 200, 77, 162, 214, 13, 14, 193, 109, 236, 96, 222, 160, 113, 181, 17, 216, 114, 103, 190, 86, 231, 229, 128, 39, 42, 65, 70, 194, 31, 152, 223, 82, 29, 51, 134, 85, 52, 56, 1], -[1, 180, 18, 156, 67, 238, 178, 172, 120, 12, 104, 216, 73, 33, 29, 80, 8, 155, 144, 220, 22, 105, 139, 91, 189, 96, 61, 186, 70, 7, 232, 126, 64, 212, 124, 218, 176, 69, 84, 214, 227, 254, 231, 203, 46, 56, 57, 237, 255, 154, 221, 202, 123, 38, 158, 170, 17, 233, 49, 82, 111, 191, 199, 97, 241, 204, 226, 74, 213, 47, 236, 75, 136, 65, 135, 142, 117, 243, 50, 5, 129, 90, 9, 78, 162, 119, 89, 86, 60, 6, 52, 108, 165, 145, 143, 40, 4, 206, 72, 110, 11, 181, 198, 174, 223, 48, 159, 93, 35, 132, 116, 63, 32, 106, 62, 109, 88, 163, 42, 107, 242, 127, 244, 230, 23, 28, 157, 247, 256, 77, 239, 101, 190, 19, 79, 85, 137, 245, 153, 41, 184, 224, 228, 177, 249, 102, 113, 37, 235, 152, 118, 166, 68, 161, 196, 71, 187, 250, 25, 131, 193, 45, 133, 39, 81, 188, 173, 43, 30, 3, 26, 54, 211, 201, 200, 20, 2, 103, 36, 55, 134, 219, 99, 87, 240, 24, 208, 175, 146, 66, 58, 160, 16, 53, 31, 183, 44, 210, 21, 182, 121, 192, 122, 115, 140, 14, 207, 252, 128, 167, 248, 179, 95, 138, 168, 171, 197, 251, 205, 149, 92, 112, 114, 217, 253, 51, 185, 147, 246, 76, 59, 83, 34, 209, 98, 164, 222, 125, 141, 194, 225, 151, 195, 148, 169, 94, 215, 150, 15, 130, 13, 27, 234, 229, 100, 10, 1], -[1, 181, 122, 237, 235, 130, 143, 183, 227, 224, 195, 86, 146, 212, 79, 164, 129, 219, 61, 247, 246, 65, 200, 220, 242, 112, 226, 43, 73, 106, 168, 82, 193, 238, 159, 252, 123, 161, 100, 110, 121, 56, 113, 150, 165, 53, 84, 41, 225, 119, 208, 126, 190, 209, 50, 55, 189, 28, 185, 75, 211, 155, 42, 149, 241, 188, 104, 63, 95, 233, 25, 156, 223, 14, 221, 166, 234, 206, 21, 203, 249, 94, 52, 160, 176, 245, 141, 78, 240, 7, 239, 83, 117, 103, 139, 230, 253, 47, 26, 80, 88, 251, 199, 39, 120, 132, 248, 170, 187, 180, 198, 115, 255, 152, 13, 40, 44, 254, 228, 148, 60, 66, 124, 85, 222, 90, 99, 186, 256, 76, 135, 20, 22, 127, 114, 74, 30, 33, 62, 171, 111, 45, 178, 93, 128, 38, 196, 10, 11, 192, 57, 37, 15, 145, 31, 214, 184, 151, 89, 175, 64, 19, 98, 5, 134, 96, 157, 147, 136, 201, 144, 107, 92, 204, 173, 216, 32, 138, 49, 131, 67, 48, 207, 202, 68, 229, 72, 182, 46, 102, 215, 108, 16, 69, 153, 194, 162, 24, 232, 101, 34, 243, 36, 91, 23, 51, 236, 54, 8, 163, 205, 97, 81, 12, 116, 179, 17, 250, 18, 174, 140, 154, 118, 27, 4, 210, 231, 177, 169, 6, 58, 218, 137, 125, 9, 87, 70, 77, 59, 142, 2, 105, 244, 217, 213, 3, 29, 109, 197, 191, 133, 172, 35, 167, 158, 71, 1], -[1, 182, 228, 119, 70, 147, 26, 106, 17, 10, 21, 224, 162, 186, 185, 3, 32, 170, 100, 210, 184, 78, 61, 51, 30, 63, 158, 229, 44, 41, 9, 96, 253, 43, 116, 38, 234, 183, 153, 90, 189, 217, 173, 132, 123, 27, 31, 245, 129, 91, 114, 188, 35, 202, 13, 53, 137, 5, 139, 112, 81, 93, 221, 130, 16, 85, 50, 105, 92, 39, 159, 154, 15, 160, 79, 243, 22, 149, 133, 48, 255, 150, 58, 19, 117, 220, 205, 45, 223, 237, 215, 66, 190, 142, 144, 251, 193, 174, 57, 94, 146, 101, 135, 155, 197, 131, 198, 56, 169, 175, 239, 65, 8, 171, 25, 181, 46, 148, 208, 77, 136, 80, 168, 250, 11, 203, 195, 24, 256, 75, 29, 138, 187, 110, 231, 151, 240, 247, 236, 33, 95, 71, 72, 254, 225, 87, 157, 47, 73, 179, 196, 206, 227, 194, 99, 28, 213, 216, 248, 161, 4, 214, 141, 219, 23, 74, 104, 167, 68, 40, 84, 125, 134, 230, 226, 12, 128, 166, 143, 69, 222, 55, 244, 204, 120, 252, 118, 145, 176, 164, 36, 127, 241, 172, 207, 152, 165, 218, 98, 103, 242, 97, 178, 14, 235, 108, 124, 209, 2, 107, 199, 238, 140, 37, 52, 212, 34, 20, 42, 191, 67, 115, 113, 6, 64, 83, 200, 163, 111, 156, 122, 102, 60, 126, 59, 201, 88, 82, 18, 192, 249, 86, 232, 76, 211, 109, 49, 180, 121, 177, 89, 7, 246, 54, 62, 233, 1], -[1, 183, 79, 65, 73, 252, 113, 119, 189, 149, 25, 206, 176, 83, 26, 132, 255, 148, 99, 127, 111, 10, 31, 19, 136, 216, 207, 102, 162, 91, 205, 250, 4, 218, 59, 3, 35, 237, 195, 219, 242, 82, 100, 53, 190, 75, 104, 14, 249, 78, 139, 251, 187, 40, 124, 76, 30, 93, 57, 151, 134, 107, 49, 229, 16, 101, 236, 12, 140, 177, 9, 105, 197, 71, 143, 212, 246, 43, 159, 56, 225, 55, 42, 233, 234, 160, 239, 47, 120, 115, 228, 90, 22, 171, 196, 145, 64, 147, 173, 48, 46, 194, 36, 163, 17, 27, 58, 77, 213, 172, 122, 224, 129, 220, 168, 161, 165, 126, 185, 188, 223, 203, 141, 103, 88, 170, 13, 66, 256, 74, 178, 192, 184, 5, 144, 138, 68, 108, 232, 51, 81, 174, 231, 125, 2, 109, 158, 130, 146, 247, 226, 238, 121, 41, 50, 155, 95, 166, 52, 7, 253, 39, 198, 254, 222, 20, 62, 38, 15, 175, 157, 204, 67, 182, 153, 243, 8, 179, 118, 6, 70, 217, 133, 181, 227, 164, 200, 106, 123, 150, 208, 28, 241, 156, 21, 245, 117, 80, 248, 152, 60, 186, 114, 45, 11, 214, 98, 201, 32, 202, 215, 24, 23, 97, 18, 210, 137, 142, 29, 167, 235, 86, 61, 112, 193, 110, 84, 209, 211, 63, 221, 94, 240, 230, 199, 180, 44, 85, 135, 33, 128, 37, 89, 96, 92, 131, 72, 69, 34, 54, 116, 154, 169, 87, 244, 191, 1], -[1, 184, 189, 81, 255, 146, 136, 95, 4, 222, 242, 67, 249, 70, 30, 123, 16, 117, 197, 11, 225, 23, 120, 235, 64, 211, 17, 44, 129, 92, 223, 169, 256, 73, 68, 176, 2, 111, 121, 162, 253, 35, 15, 190, 8, 187, 227, 134, 241, 140, 60, 246, 32, 234, 137, 22, 193, 46, 240, 213, 128, 165, 34, 88, 1, 184, 189, 81, 255, 146, 136, 95, 4, 222, 242, 67, 249, 70, 30, 123, 16, 117, 197, 11, 225, 23, 120, 235, 64, 211, 17, 44, 129, 92, 223, 169, 256, 73, 68, 176, 2, 111, 121, 162, 253, 35, 15, 190, 8, 187, 227, 134, 241, 140, 60, 246, 32, 234, 137, 22, 193, 46, 240, 213, 128, 165, 34, 88, 1, 184, 189, 81, 255, 146, 136, 95, 4, 222, 242, 67, 249, 70, 30, 123, 16, 117, 197, 11, 225, 23, 120, 235, 64, 211, 17, 44, 129, 92, 223, 169, 256, 73, 68, 176, 2, 111, 121, 162, 253, 35, 15, 190, 8, 187, 227, 134, 241, 140, 60, 246, 32, 234, 137, 22, 193, 46, 240, 213, 128, 165, 34, 88, 1, 184, 189, 81, 255, 146, 136, 95, 4, 222, 242, 67, 249, 70, 30, 123, 16, 117, 197, 11, 225, 23, 120, 235, 64, 211, 17, 44, 129, 92, 223, 169, 256, 73, 68, 176, 2, 111, 121, 162, 253, 35, 15, 190, 8, 187, 227, 134, 241, 140, 60, 246, 32, 234, 137, 22, 193, 46, 240, 213, 128, 165, 34, 88, 1], -[1, 185, 44, 173, 137, 159, 117, 57, 8, 195, 95, 99, 68, 244, 165, 199, 64, 18, 246, 21, 30, 153, 35, 50, 255, 144, 169, 168, 240, 196, 23, 143, 241, 124, 67, 59, 121, 26, 184, 116, 129, 221, 22, 215, 197, 208, 187, 157, 4, 226, 176, 178, 34, 122, 211, 228, 32, 9, 123, 139, 15, 205, 146, 25, 256, 72, 213, 84, 120, 98, 140, 200, 249, 62, 162, 158, 189, 13, 92, 58, 193, 239, 11, 236, 227, 104, 222, 207, 2, 113, 88, 89, 17, 61, 234, 114, 16, 133, 190, 198, 136, 231, 73, 141, 128, 36, 235, 42, 60, 49, 70, 100, 253, 31, 81, 79, 223, 135, 46, 29, 225, 248, 134, 118, 242, 52, 111, 232, 1, 185, 44, 173, 137, 159, 117, 57, 8, 195, 95, 99, 68, 244, 165, 199, 64, 18, 246, 21, 30, 153, 35, 50, 255, 144, 169, 168, 240, 196, 23, 143, 241, 124, 67, 59, 121, 26, 184, 116, 129, 221, 22, 215, 197, 208, 187, 157, 4, 226, 176, 178, 34, 122, 211, 228, 32, 9, 123, 139, 15, 205, 146, 25, 256, 72, 213, 84, 120, 98, 140, 200, 249, 62, 162, 158, 189, 13, 92, 58, 193, 239, 11, 236, 227, 104, 222, 207, 2, 113, 88, 89, 17, 61, 234, 114, 16, 133, 190, 198, 136, 231, 73, 141, 128, 36, 235, 42, 60, 49, 70, 100, 253, 31, 81, 79, 223, 135, 46, 29, 225, 248, 134, 118, 242, 52, 111, 232, 1], -[1, 186, 158, 90, 35, 85, 133, 66, 197, 148, 29, 254, 213, 40, 244, 152, 2, 115, 59, 180, 70, 170, 9, 132, 137, 39, 58, 251, 169, 80, 231, 47, 4, 230, 118, 103, 140, 83, 18, 7, 17, 78, 116, 245, 81, 160, 205, 94, 8, 203, 236, 206, 23, 166, 36, 14, 34, 156, 232, 233, 162, 63, 153, 188, 16, 149, 215, 155, 46, 75, 72, 28, 68, 55, 207, 209, 67, 126, 49, 119, 32, 41, 173, 53, 92, 150, 144, 56, 136, 110, 157, 161, 134, 252, 98, 238, 64, 82, 89, 106, 184, 43, 31, 112, 15, 220, 57, 65, 11, 247, 196, 219, 128, 164, 178, 212, 111, 86, 62, 224, 30, 183, 114, 130, 22, 237, 135, 181, 256, 71, 99, 167, 222, 172, 124, 191, 60, 109, 228, 3, 44, 217, 13, 105, 255, 142, 198, 77, 187, 87, 248, 125, 120, 218, 199, 6, 88, 177, 26, 210, 253, 27, 139, 154, 117, 174, 239, 250, 240, 179, 141, 12, 176, 97, 52, 163, 249, 54, 21, 51, 234, 91, 221, 243, 223, 101, 25, 24, 95, 194, 104, 69, 241, 108, 42, 102, 211, 182, 185, 229, 189, 202, 50, 48, 190, 131, 208, 138, 225, 216, 84, 204, 165, 107, 113, 201, 121, 147, 100, 96, 123, 5, 159, 19, 193, 175, 168, 151, 73, 214, 226, 145, 242, 37, 200, 192, 246, 10, 61, 38, 129, 93, 79, 45, 146, 171, 195, 33, 227, 74, 143, 127, 235, 20, 122, 76, 1], -[1, 187, 17, 95, 32, 73, 30, 213, 253, 23, 189, 134, 129, 222, 137, 176, 16, 165, 15, 235, 255, 140, 223, 67, 193, 111, 197, 88, 8, 211, 136, 246, 256, 70, 240, 162, 225, 184, 227, 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, 92, 242, 22, 2, 117, 34, 190, 64, 146, 60, 169, 249, 46, 121, 11, 1, 187, 17, 95, 32, 73, 30, 213, 253, 23, 189, 134, 129, 222, 137, 176, 16, 165, 15, 235, 255, 140, 223, 67, 193, 111, 197, 88, 8, 211, 136, 246, 256, 70, 240, 162, 225, 184, 227, 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, 92, 242, 22, 2, 117, 34, 190, 64, 146, 60, 169, 249, 46, 121, 11, 1, 187, 17, 95, 32, 73, 30, 213, 253, 23, 189, 134, 129, 222, 137, 176, 16, 165, 15, 235, 255, 140, 223, 67, 193, 111, 197, 88, 8, 211, 136, 246, 256, 70, 240, 162, 225, 184, 227, 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, 92, 242, 22, 2, 117, 34, 190, 64, 146, 60, 169, 249, 46, 121, 11, 1, 187, 17, 95, 32, 73, 30, 213, 253, 23, 189, 134, 129, 222, 137, 176, 16, 165, 15, 235, 255, 140, 223, 67, 193, 111, 197, 88, 8, 211, 136, 246, 256, 70, 240, 162, 225, 184, 227, 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, 92, 242, 22, 2, 117, 34, 190, 64, 146, 60, 169, 249, 46, 121, 11, 1], -[1, 188, 135, 194, 235, 233, 114, 101, 227, 14, 62, 91, 146, 206, 178, 54, 129, 94, 196, 97, 246, 245, 57, 179, 242, 7, 31, 174, 73, 103, 89, 27, 193, 47, 98, 177, 123, 251, 157, 218, 121, 132, 144, 87, 165, 180, 173, 142, 225, 152, 49, 217, 190, 254, 207, 109, 189, 66, 72, 172, 211, 90, 215, 71, 241, 76, 153, 237, 95, 127, 232, 183, 223, 33, 36, 86, 234, 45, 236, 164, 249, 38, 205, 247, 176, 192, 116, 220, 240, 145, 18, 43, 117, 151, 118, 82, 253, 19, 231, 252, 88, 96, 58, 110, 120, 201, 9, 150, 187, 204, 59, 41, 255, 138, 244, 126, 44, 48, 29, 55, 60, 229, 133, 75, 222, 102, 158, 149, 256, 69, 122, 63, 22, 24, 143, 156, 30, 243, 195, 166, 111, 51, 79, 203, 128, 163, 61, 160, 11, 12, 200, 78, 15, 250, 226, 83, 184, 154, 168, 230, 64, 210, 159, 80, 134, 6, 100, 39, 136, 125, 113, 170, 92, 77, 84, 115, 32, 105, 208, 40, 67, 3, 50, 148, 68, 191, 185, 85, 46, 167, 42, 186, 16, 181, 104, 20, 162, 130, 25, 74, 34, 224, 221, 171, 23, 212, 21, 93, 8, 219, 52, 10, 81, 65, 141, 37, 17, 112, 239, 214, 140, 106, 139, 175, 4, 238, 26, 5, 169, 161, 199, 147, 137, 56, 248, 107, 70, 53, 198, 216, 2, 119, 13, 131, 213, 209, 228, 202, 197, 28, 124, 182, 35, 155, 99, 108, 1], -[1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1], -[1, 190, 120, 184, 8, 235, 189, 187, 64, 81, 227, 211, 255, 134, 17, 146, 241, 44, 136, 140, 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, 242, 234, 256, 67, 137, 73, 249, 22, 68, 70, 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, 121, 117, 128, 162, 197, 165, 253, 11, 34, 35, 225, 88, 15, 23, 1, 190, 120, 184, 8, 235, 189, 187, 64, 81, 227, 211, 255, 134, 17, 146, 241, 44, 136, 140, 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, 242, 234, 256, 67, 137, 73, 249, 22, 68, 70, 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, 121, 117, 128, 162, 197, 165, 253, 11, 34, 35, 225, 88, 15, 23, 1, 190, 120, 184, 8, 235, 189, 187, 64, 81, 227, 211, 255, 134, 17, 146, 241, 44, 136, 140, 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, 242, 234, 256, 67, 137, 73, 249, 22, 68, 70, 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, 121, 117, 128, 162, 197, 165, 253, 11, 34, 35, 225, 88, 15, 23, 1, 190, 120, 184, 8, 235, 189, 187, 64, 81, 227, 211, 255, 134, 17, 146, 241, 44, 136, 140, 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, 242, 234, 256, 67, 137, 73, 249, 22, 68, 70, 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, 121, 117, 128, 162, 197, 165, 253, 11, 34, 35, 225, 88, 15, 23, 1], -[1, 191, 244, 87, 169, 154, 116, 54, 34, 69, 72, 131, 92, 96, 89, 37, 128, 33, 135, 85, 44, 180, 199, 230, 240, 94, 221, 63, 211, 209, 84, 110, 193, 112, 61, 86, 235, 167, 29, 142, 137, 210, 18, 97, 23, 24, 215, 202, 32, 201, 98, 214, 11, 45, 114, 186, 60, 152, 248, 80, 117, 245, 21, 156, 241, 28, 208, 150, 123, 106, 200, 164, 227, 181, 133, 217, 70, 6, 118, 179, 8, 243, 153, 182, 67, 204, 157, 175, 15, 38, 62, 20, 222, 254, 198, 39, 253, 7, 52, 166, 95, 155, 50, 41, 121, 238, 226, 247, 146, 130, 158, 109, 2, 125, 231, 174, 81, 51, 232, 108, 68, 138, 144, 5, 184, 192, 178, 74, 256, 66, 13, 170, 88, 103, 141, 203, 223, 188, 185, 126, 165, 161, 168, 220, 129, 224, 122, 172, 213, 77, 58, 27, 17, 163, 36, 194, 46, 48, 173, 147, 64, 145, 196, 171, 22, 90, 228, 115, 120, 47, 239, 160, 234, 233, 42, 55, 225, 56, 159, 43, 246, 212, 143, 71, 197, 105, 9, 177, 140, 12, 236, 101, 16, 229, 49, 107, 134, 151, 57, 93, 30, 76, 124, 40, 187, 251, 139, 78, 249, 14, 104, 75, 190, 53, 100, 82, 242, 219, 195, 237, 35, 3, 59, 218, 4, 250, 205, 91, 162, 102, 207, 216, 136, 19, 31, 10, 111, 127, 99, 148, 255, 132, 26, 83, 176, 206, 25, 149, 189, 119, 113, 252, 73, 65, 79, 183, 1], -[1, 192, 113, 108, 176, 125, 99, 247, 136, 155, 205, 39, 35, 38, 100, 182, 249, 6, 124, 164, 134, 28, 236, 80, 197, 45, 159, 202, 234, 210, 228, 86, 64, 209, 36, 230, 213, 33, 168, 131, 223, 154, 13, 183, 184, 119, 232, 83, 2, 127, 226, 216, 95, 250, 198, 237, 15, 53, 153, 78, 70, 76, 200, 107, 241, 12, 248, 71, 11, 56, 215, 160, 137, 90, 61, 147, 211, 163, 199, 172, 128, 161, 72, 203, 169, 66, 79, 5, 189, 51, 26, 109, 111, 238, 207, 166, 4, 254, 195, 175, 190, 243, 139, 217, 30, 106, 49, 156, 140, 152, 143, 214, 225, 24, 239, 142, 22, 112, 173, 63, 17, 180, 122, 37, 165, 69, 141, 87, 256, 65, 144, 149, 81, 132, 158, 10, 121, 102, 52, 218, 222, 219, 157, 75, 8, 251, 133, 93, 123, 229, 21, 177, 60, 212, 98, 55, 23, 47, 29, 171, 193, 48, 221, 27, 44, 224, 89, 126, 34, 103, 244, 74, 73, 138, 25, 174, 255, 130, 31, 41, 162, 7, 59, 20, 242, 204, 104, 179, 187, 181, 57, 150, 16, 245, 9, 186, 246, 201, 42, 97, 120, 167, 196, 110, 46, 94, 58, 85, 129, 96, 185, 54, 88, 191, 178, 252, 68, 206, 231, 148, 146, 19, 50, 91, 253, 3, 62, 82, 67, 14, 118, 40, 227, 151, 208, 101, 117, 105, 114, 43, 32, 233, 18, 115, 235, 145, 84, 194, 240, 77, 135, 220, 92, 188, 116, 170, 1], -[1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1], -[1, 194, 114, 14, 146, 54, 196, 245, 242, 174, 89, 47, 123, 218, 144, 180, 225, 217, 207, 66, 211, 71, 153, 127, 223, 86, 236, 38, 176, 220, 18, 151, 253, 252, 58, 201, 187, 41, 244, 48, 60, 75, 158, 69, 22, 156, 195, 51, 128, 160, 200, 250, 184, 230, 159, 6, 136, 170, 84, 105, 67, 148, 185, 167, 16, 20, 25, 224, 23, 93, 52, 65, 17, 214, 139, 238, 169, 147, 248, 53, 2, 131, 228, 28, 35, 108, 135, 233, 227, 91, 178, 94, 246, 179, 31, 103, 193, 177, 157, 132, 165, 142, 49, 254, 189, 172, 215, 76, 95, 183, 36, 45, 249, 247, 116, 145, 117, 82, 231, 96, 120, 150, 59, 138, 44, 55, 133, 102, 256, 63, 143, 243, 111, 203, 61, 12, 15, 83, 168, 210, 134, 39, 113, 77, 32, 40, 50, 191, 46, 186, 104, 130, 34, 171, 21, 219, 81, 37, 239, 106, 4, 5, 199, 56, 70, 216, 13, 209, 197, 182, 99, 188, 235, 101, 62, 206, 129, 97, 57, 7, 73, 27, 98, 251, 121, 87, 173, 152, 190, 109, 72, 90, 241, 237, 232, 33, 234, 164, 205, 192, 240, 43, 118, 19, 88, 110, 9, 204, 255, 126, 29, 229, 222, 149, 122, 24, 30, 166, 79, 163, 11, 78, 226, 154, 64, 80, 100, 125, 92, 115, 208, 3, 68, 85, 42, 181, 162, 74, 221, 212, 8, 10, 141, 112, 140, 175, 26, 161, 137, 107, 198, 119, 213, 202, 124, 155, 1], -[1, 195, 246, 168, 121, 208, 211, 25, 249, 239, 88, 198, 60, 135, 111, 57, 64, 144, 67, 215, 34, 205, 140, 58, 2, 133, 235, 79, 242, 159, 165, 50, 241, 221, 176, 139, 120, 13, 222, 114, 128, 31, 134, 173, 68, 153, 23, 116, 4, 9, 213, 158, 227, 61, 73, 100, 225, 185, 95, 21, 240, 26, 187, 228, 256, 62, 11, 89, 136, 49, 46, 232, 8, 18, 169, 59, 197, 122, 146, 200, 193, 113, 190, 42, 223, 52, 117, 199, 255, 124, 22, 178, 15, 98, 92, 207, 16, 36, 81, 118, 137, 244, 35, 143, 129, 226, 123, 84, 189, 104, 234, 141, 253, 248, 44, 99, 30, 196, 184, 157, 32, 72, 162, 236, 17, 231, 70, 29, 1, 195, 246, 168, 121, 208, 211, 25, 249, 239, 88, 198, 60, 135, 111, 57, 64, 144, 67, 215, 34, 205, 140, 58, 2, 133, 235, 79, 242, 159, 165, 50, 241, 221, 176, 139, 120, 13, 222, 114, 128, 31, 134, 173, 68, 153, 23, 116, 4, 9, 213, 158, 227, 61, 73, 100, 225, 185, 95, 21, 240, 26, 187, 228, 256, 62, 11, 89, 136, 49, 46, 232, 8, 18, 169, 59, 197, 122, 146, 200, 193, 113, 190, 42, 223, 52, 117, 199, 255, 124, 22, 178, 15, 98, 92, 207, 16, 36, 81, 118, 137, 244, 35, 143, 129, 226, 123, 84, 189, 104, 234, 141, 253, 248, 44, 99, 30, 196, 184, 157, 32, 72, 162, 236, 17, 231, 70, 29, 1], -[1, 196, 123, 207, 223, 18, 187, 158, 128, 159, 67, 25, 17, 248, 35, 178, 193, 49, 95, 116, 120, 133, 111, 168, 32, 104, 81, 199, 197, 62, 73, 173, 241, 205, 88, 29, 30, 226, 92, 42, 8, 26, 213, 114, 242, 144, 211, 236, 253, 244, 22, 200, 136, 185, 23, 139, 2, 135, 246, 157, 189, 36, 117, 59, 256, 61, 134, 50, 34, 239, 70, 99, 129, 98, 190, 232, 240, 9, 222, 79, 64, 208, 162, 141, 137, 124, 146, 89, 225, 153, 176, 58, 60, 195, 184, 84, 16, 52, 169, 228, 227, 31, 165, 215, 249, 231, 44, 143, 15, 113, 46, 21, 4, 13, 235, 57, 121, 72, 234, 118, 255, 122, 11, 100, 68, 221, 140, 198, 1, 196, 123, 207, 223, 18, 187, 158, 128, 159, 67, 25, 17, 248, 35, 178, 193, 49, 95, 116, 120, 133, 111, 168, 32, 104, 81, 199, 197, 62, 73, 173, 241, 205, 88, 29, 30, 226, 92, 42, 8, 26, 213, 114, 242, 144, 211, 236, 253, 244, 22, 200, 136, 185, 23, 139, 2, 135, 246, 157, 189, 36, 117, 59, 256, 61, 134, 50, 34, 239, 70, 99, 129, 98, 190, 232, 240, 9, 222, 79, 64, 208, 162, 141, 137, 124, 146, 89, 225, 153, 176, 58, 60, 195, 184, 84, 16, 52, 169, 228, 227, 31, 165, 215, 249, 231, 44, 143, 15, 113, 46, 21, 4, 13, 235, 57, 121, 72, 234, 118, 255, 122, 11, 100, 68, 221, 140, 198, 1], -[1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1], -[1, 198, 140, 221, 68, 100, 11, 122, 255, 118, 234, 72, 121, 57, 235, 13, 4, 21, 46, 113, 15, 143, 44, 231, 249, 215, 165, 31, 227, 228, 169, 52, 16, 84, 184, 195, 60, 58, 176, 153, 225, 89, 146, 124, 137, 141, 162, 208, 64, 79, 222, 9, 240, 232, 190, 98, 129, 99, 70, 239, 34, 50, 134, 61, 256, 59, 117, 36, 189, 157, 246, 135, 2, 139, 23, 185, 136, 200, 22, 244, 253, 236, 211, 144, 242, 114, 213, 26, 8, 42, 92, 226, 30, 29, 88, 205, 241, 173, 73, 62, 197, 199, 81, 104, 32, 168, 111, 133, 120, 116, 95, 49, 193, 178, 35, 248, 17, 25, 67, 159, 128, 158, 187, 18, 223, 207, 123, 196, 1, 198, 140, 221, 68, 100, 11, 122, 255, 118, 234, 72, 121, 57, 235, 13, 4, 21, 46, 113, 15, 143, 44, 231, 249, 215, 165, 31, 227, 228, 169, 52, 16, 84, 184, 195, 60, 58, 176, 153, 225, 89, 146, 124, 137, 141, 162, 208, 64, 79, 222, 9, 240, 232, 190, 98, 129, 99, 70, 239, 34, 50, 134, 61, 256, 59, 117, 36, 189, 157, 246, 135, 2, 139, 23, 185, 136, 200, 22, 244, 253, 236, 211, 144, 242, 114, 213, 26, 8, 42, 92, 226, 30, 29, 88, 205, 241, 173, 73, 62, 197, 199, 81, 104, 32, 168, 111, 133, 120, 116, 95, 49, 193, 178, 35, 248, 17, 25, 67, 159, 128, 158, 187, 18, 223, 207, 123, 196, 1], -[1, 199, 23, 208, 15, 158, 88, 36, 225, 57, 35, 26, 34, 84, 11, 133, 253, 232, 165, 196, 197, 139, 162, 113, 128, 29, 117, 153, 121, 178, 213, 239, 16, 100, 111, 244, 240, 215, 123, 62, 2, 141, 46, 159, 30, 59, 176, 72, 193, 114, 70, 52, 68, 168, 22, 9, 249, 207, 73, 135, 137, 21, 67, 226, 256, 58, 234, 49, 242, 99, 169, 221, 32, 200, 222, 231, 223, 173, 246, 124, 4, 25, 92, 61, 60, 118, 95, 144, 129, 228, 140, 104, 136, 79, 44, 18, 241, 157, 146, 13, 17, 42, 134, 195, 255, 116, 211, 98, 227, 198, 81, 185, 64, 143, 187, 205, 189, 89, 235, 248, 8, 50, 184, 122, 120, 236, 190, 31, 1, 199, 23, 208, 15, 158, 88, 36, 225, 57, 35, 26, 34, 84, 11, 133, 253, 232, 165, 196, 197, 139, 162, 113, 128, 29, 117, 153, 121, 178, 213, 239, 16, 100, 111, 244, 240, 215, 123, 62, 2, 141, 46, 159, 30, 59, 176, 72, 193, 114, 70, 52, 68, 168, 22, 9, 249, 207, 73, 135, 137, 21, 67, 226, 256, 58, 234, 49, 242, 99, 169, 221, 32, 200, 222, 231, 223, 173, 246, 124, 4, 25, 92, 61, 60, 118, 95, 144, 129, 228, 140, 104, 136, 79, 44, 18, 241, 157, 146, 13, 17, 42, 134, 195, 255, 116, 211, 98, 227, 198, 81, 185, 64, 143, 187, 205, 189, 89, 235, 248, 8, 50, 184, 122, 120, 236, 190, 31, 1], -[1, 200, 165, 104, 240, 198, 22, 31, 32, 232, 140, 244, 227, 168, 190, 221, 253, 228, 111, 98, 68, 236, 169, 133, 129, 100, 211, 52, 120, 99, 11, 144, 16, 116, 70, 122, 242, 84, 95, 239, 255, 114, 184, 49, 34, 118, 213, 195, 193, 50, 234, 26, 60, 178, 134, 72, 8, 58, 35, 61, 121, 42, 176, 248, 256, 57, 92, 153, 17, 59, 235, 226, 225, 25, 117, 13, 30, 89, 67, 36, 4, 29, 146, 159, 189, 21, 88, 124, 128, 157, 46, 205, 137, 158, 246, 113, 241, 141, 187, 135, 15, 173, 162, 18, 2, 143, 73, 208, 223, 139, 44, 62, 64, 207, 23, 231, 197, 79, 123, 185, 249, 199, 222, 196, 136, 215, 81, 9, 1, 200, 165, 104, 240, 198, 22, 31, 32, 232, 140, 244, 227, 168, 190, 221, 253, 228, 111, 98, 68, 236, 169, 133, 129, 100, 211, 52, 120, 99, 11, 144, 16, 116, 70, 122, 242, 84, 95, 239, 255, 114, 184, 49, 34, 118, 213, 195, 193, 50, 234, 26, 60, 178, 134, 72, 8, 58, 35, 61, 121, 42, 176, 248, 256, 57, 92, 153, 17, 59, 235, 226, 225, 25, 117, 13, 30, 89, 67, 36, 4, 29, 146, 159, 189, 21, 88, 124, 128, 157, 46, 205, 137, 158, 246, 113, 241, 141, 187, 135, 15, 173, 162, 18, 2, 143, 73, 208, 223, 139, 44, 62, 64, 207, 23, 231, 197, 79, 123, 185, 249, 199, 222, 196, 136, 215, 81, 9, 1], -[1, 201, 52, 172, 134, 206, 29, 175, 223, 105, 31, 63, 70, 192, 42, 218, 128, 28, 231, 171, 190, 154, 114, 41, 17, 76, 113, 97, 222, 161, 236, 148, 193, 243, 13, 43, 162, 180, 200, 108, 120, 219, 72, 80, 146, 48, 139, 183, 32, 7, 122, 107, 176, 167, 157, 203, 197, 19, 221, 217, 184, 233, 59, 37, 241, 125, 196, 75, 169, 45, 50, 27, 30, 119, 18, 20, 165, 12, 99, 110, 8, 66, 159, 91, 44, 106, 232, 115, 242, 69, 248, 247, 46, 251, 79, 202, 253, 224, 49, 83, 235, 204, 141, 71, 136, 94, 133, 5, 234, 3, 89, 156, 2, 145, 104, 87, 11, 155, 58, 93, 189, 210, 62, 126, 140, 127, 84, 179, 256, 56, 205, 85, 123, 51, 228, 82, 34, 152, 226, 194, 187, 65, 215, 39, 129, 229, 26, 86, 67, 103, 143, 216, 240, 181, 144, 160, 35, 96, 21, 109, 64, 14, 244, 214, 95, 77, 57, 149, 137, 38, 185, 177, 111, 209, 118, 74, 225, 250, 135, 150, 81, 90, 100, 54, 60, 238, 36, 40, 73, 24, 198, 220, 16, 132, 61, 182, 88, 212, 207, 230, 227, 138, 239, 237, 92, 245, 158, 147, 249, 191, 98, 166, 213, 151, 25, 142, 15, 188, 9, 10, 211, 6, 178, 55, 4, 33, 208, 174, 22, 53, 116, 186, 121, 163, 124, 252, 23, 254, 168, 101, 255, 112, 153, 170, 246, 102, 199, 164, 68, 47, 195, 131, 117, 130, 173, 78, 1], -[1, 202, 198, 161, 140, 10, 221, 181, 68, 115, 100, 154, 11, 166, 122, 229, 255, 110, 118, 192, 234, 237, 72, 152, 121, 27, 57, 206, 235, 182, 13, 56, 4, 37, 21, 130, 46, 40, 113, 210, 15, 203, 143, 102, 44, 150, 231, 145, 249, 183, 215, 254, 165, 177, 31, 94, 227, 108, 228, 53, 169, 214, 52, 224, 16, 148, 84, 6, 184, 160, 195, 69, 60, 41, 58, 151, 176, 86, 153, 66, 225, 218, 89, 245, 146, 194, 124, 119, 137, 175, 141, 212, 162, 85, 208, 125, 64, 78, 79, 24, 222, 126, 9, 19, 240, 164, 232, 90, 190, 87, 98, 7, 129, 101, 99, 209, 70, 5, 239, 219, 34, 186, 50, 77, 134, 83, 61, 243, 256, 55, 59, 96, 117, 247, 36, 76, 189, 142, 157, 103, 246, 91, 135, 28, 2, 147, 139, 65, 23, 20, 185, 105, 136, 230, 200, 51, 22, 75, 244, 201, 253, 220, 236, 127, 211, 217, 144, 47, 242, 54, 114, 155, 213, 107, 26, 112, 8, 74, 42, 3, 92, 80, 226, 163, 30, 149, 29, 204, 88, 43, 205, 33, 241, 109, 173, 251, 73, 97, 62, 188, 197, 216, 199, 106, 81, 171, 104, 191, 32, 39, 168, 12, 111, 63, 133, 138, 120, 82, 116, 45, 95, 172, 49, 132, 193, 179, 178, 233, 35, 131, 248, 238, 17, 93, 25, 167, 67, 170, 159, 250, 128, 156, 158, 48, 187, 252, 18, 38, 223, 71, 207, 180, 123, 174, 196, 14, 1], -[1, 203, 89, 77, 211, 171, 18, 56, 60, 101, 200, 251, 67, 237, 52, 19, 2, 149, 178, 154, 165, 85, 36, 112, 120, 202, 143, 245, 134, 217, 104, 38, 4, 41, 99, 51, 73, 170, 72, 224, 240, 147, 29, 233, 11, 177, 208, 76, 8, 82, 198, 102, 146, 83, 144, 191, 223, 37, 58, 209, 22, 97, 159, 152, 16, 164, 139, 204, 35, 166, 31, 125, 189, 74, 116, 161, 44, 194, 61, 47, 32, 71, 21, 151, 70, 75, 62, 250, 121, 148, 232, 65, 88, 131, 122, 94, 64, 142, 42, 45, 140, 150, 124, 243, 242, 39, 207, 130, 176, 5, 244, 188, 128, 27, 84, 90, 23, 43, 248, 229, 227, 78, 157, 3, 95, 10, 231, 119, 256, 54, 168, 180, 46, 86, 239, 201, 197, 156, 57, 6, 190, 20, 205, 238, 255, 108, 79, 103, 92, 172, 221, 145, 137, 55, 114, 12, 123, 40, 153, 219, 253, 216, 158, 206, 184, 87, 185, 33, 17, 110, 228, 24, 246, 80, 49, 181, 249, 175, 59, 155, 111, 174, 113, 66, 34, 220, 199, 48, 235, 160, 98, 105, 241, 93, 118, 53, 222, 91, 226, 132, 68, 183, 141, 96, 213, 63, 196, 210, 225, 186, 236, 106, 187, 182, 195, 7, 136, 109, 25, 192, 169, 126, 135, 163, 193, 115, 215, 212, 117, 107, 133, 14, 15, 218, 50, 127, 81, 252, 13, 69, 129, 230, 173, 167, 234, 214, 9, 28, 30, 179, 100, 254, 162, 247, 26, 138, 1], -[1, 204, 239, 183, 67, 47, 79, 182, 120, 65, 153, 115, 73, 243, 228, 252, 8, 90, 113, 179, 22, 119, 118, 171, 189, 6, 196, 149, 70, 145, 25, 217, 64, 206, 133, 147, 176, 181, 173, 83, 227, 48, 26, 164, 46, 132, 200, 194, 255, 106, 36, 148, 123, 163, 99, 150, 17, 127, 208, 27, 111, 28, 58, 10, 241, 77, 31, 156, 213, 19, 21, 172, 136, 245, 122, 216, 117, 224, 207, 80, 129, 102, 248, 220, 162, 152, 168, 91, 60, 161, 205, 186, 165, 250, 114, 126, 4, 45, 185, 218, 11, 188, 59, 214, 223, 3, 98, 203, 35, 201, 141, 237, 32, 103, 195, 202, 88, 219, 215, 170, 242, 24, 13, 82, 23, 66, 100, 97, 256, 53, 18, 74, 190, 210, 178, 75, 137, 192, 104, 142, 184, 14, 29, 5, 249, 167, 144, 78, 235, 138, 139, 86, 68, 251, 61, 108, 187, 112, 232, 40, 193, 51, 124, 110, 81, 76, 84, 174, 30, 209, 231, 93, 211, 125, 57, 63, 2, 151, 221, 109, 134, 94, 158, 107, 240, 130, 49, 230, 146, 229, 199, 247, 16, 180, 226, 101, 44, 238, 236, 85, 121, 12, 135, 41, 140, 33, 50, 177, 128, 155, 9, 37, 95, 105, 89, 166, 197, 96, 52, 71, 92, 7, 143, 131, 253, 212, 72, 39, 246, 69, 198, 43, 34, 254, 159, 54, 222, 56, 116, 20, 225, 154, 62, 55, 169, 38, 42, 87, 15, 233, 244, 175, 234, 191, 157, 160, 1], -[1, 205, 134, 228, 223, 226, 70, 215, 128, 26, 190, 143, 17, 144, 222, 21, 193, 244, 162, 57, 120, 185, 146, 118, 32, 135, 176, 100, 197, 36, 184, 198, 241, 61, 169, 207, 30, 239, 165, 158, 8, 98, 44, 25, 242, 9, 46, 178, 253, 208, 235, 116, 136, 124, 234, 168, 2, 153, 11, 199, 189, 195, 140, 173, 256, 52, 123, 29, 34, 31, 187, 42, 129, 231, 67, 114, 240, 113, 35, 236, 64, 13, 95, 200, 137, 72, 111, 139, 225, 122, 81, 157, 60, 221, 73, 59, 16, 196, 88, 50, 227, 18, 92, 99, 249, 159, 213, 232, 15, 248, 211, 79, 4, 49, 22, 141, 121, 133, 23, 89, 255, 104, 246, 58, 68, 62, 117, 84, 1, 205, 134, 228, 223, 226, 70, 215, 128, 26, 190, 143, 17, 144, 222, 21, 193, 244, 162, 57, 120, 185, 146, 118, 32, 135, 176, 100, 197, 36, 184, 198, 241, 61, 169, 207, 30, 239, 165, 158, 8, 98, 44, 25, 242, 9, 46, 178, 253, 208, 235, 116, 136, 124, 234, 168, 2, 153, 11, 199, 189, 195, 140, 173, 256, 52, 123, 29, 34, 31, 187, 42, 129, 231, 67, 114, 240, 113, 35, 236, 64, 13, 95, 200, 137, 72, 111, 139, 225, 122, 81, 157, 60, 221, 73, 59, 16, 196, 88, 50, 227, 18, 92, 99, 249, 159, 213, 232, 15, 248, 211, 79, 4, 49, 22, 141, 121, 133, 23, 89, 255, 104, 246, 58, 68, 62, 117, 84, 1], -[1, 206, 31, 218, 190, 76, 236, 43, 120, 48, 122, 203, 184, 125, 50, 20, 8, 106, 248, 202, 235, 94, 89, 87, 189, 127, 205, 82, 187, 229, 143, 160, 64, 77, 185, 74, 81, 238, 198, 182, 227, 245, 98, 142, 211, 33, 116, 252, 255, 102, 195, 78, 134, 105, 42, 171, 17, 161, 13, 108, 146, 7, 157, 217, 241, 45, 18, 110, 44, 69, 79, 83, 136, 3, 104, 93, 140, 56, 228, 194, 129, 103, 144, 109, 95, 38, 118, 150, 60, 24, 61, 230, 92, 191, 25, 10, 4, 53, 124, 101, 246, 47, 173, 172, 223, 192, 231, 41, 222, 243, 200, 80, 32, 167, 221, 37, 169, 119, 99, 91, 242, 251, 49, 71, 234, 145, 58, 126, 256, 51, 226, 39, 67, 181, 21, 214, 137, 209, 135, 54, 73, 132, 207, 237, 249, 151, 9, 55, 22, 163, 168, 170, 68, 130, 52, 175, 70, 28, 114, 97, 193, 180, 72, 183, 176, 19, 59, 75, 30, 12, 159, 115, 46, 224, 141, 5, 2, 155, 62, 179, 123, 152, 215, 86, 240, 96, 244, 149, 111, 250, 100, 40, 16, 212, 239, 147, 213, 188, 178, 174, 121, 254, 153, 164, 117, 201, 29, 63, 128, 154, 113, 148, 162, 219, 139, 107, 197, 233, 196, 27, 165, 66, 232, 247, 253, 204, 133, 156, 11, 210, 84, 85, 34, 65, 26, 216, 35, 14, 57, 177, 225, 90, 36, 220, 88, 138, 158, 166, 15, 6, 208, 186, 23, 112, 199, 131, 1], -[1, 207, 187, 159, 17, 178, 95, 133, 32, 199, 73, 205, 30, 42, 213, 144, 253, 200, 23, 135, 189, 59, 134, 239, 129, 232, 222, 208, 137, 89, 176, 195, 16, 228, 165, 231, 15, 21, 235, 72, 255, 100, 140, 196, 223, 158, 67, 248, 193, 116, 111, 104, 197, 173, 88, 226, 8, 114, 211, 244, 136, 139, 246, 36, 256, 50, 70, 98, 240, 79, 162, 124, 225, 58, 184, 52, 227, 215, 44, 113, 4, 57, 234, 122, 68, 198, 123, 18, 128, 25, 35, 49, 120, 168, 81, 62, 241, 29, 92, 26, 242, 236, 22, 185, 2, 157, 117, 61, 34, 99, 190, 9, 64, 141, 146, 153, 60, 84, 169, 31, 249, 143, 46, 13, 121, 118, 11, 221, 1, 207, 187, 159, 17, 178, 95, 133, 32, 199, 73, 205, 30, 42, 213, 144, 253, 200, 23, 135, 189, 59, 134, 239, 129, 232, 222, 208, 137, 89, 176, 195, 16, 228, 165, 231, 15, 21, 235, 72, 255, 100, 140, 196, 223, 158, 67, 248, 193, 116, 111, 104, 197, 173, 88, 226, 8, 114, 211, 244, 136, 139, 246, 36, 256, 50, 70, 98, 240, 79, 162, 124, 225, 58, 184, 52, 227, 215, 44, 113, 4, 57, 234, 122, 68, 198, 123, 18, 128, 25, 35, 49, 120, 168, 81, 62, 241, 29, 92, 26, 242, 236, 22, 185, 2, 157, 117, 61, 34, 99, 190, 9, 64, 141, 146, 153, 60, 84, 169, 31, 249, 143, 46, 13, 121, 118, 11, 221, 1], -[1, 208, 88, 57, 34, 133, 165, 139, 128, 153, 213, 100, 240, 62, 46, 59, 193, 52, 22, 207, 137, 226, 234, 99, 32, 231, 246, 25, 60, 144, 140, 79, 241, 13, 134, 116, 227, 185, 187, 89, 8, 122, 190, 199, 15, 36, 35, 84, 253, 196, 162, 29, 121, 239, 111, 215, 2, 159, 176, 114, 68, 9, 73, 21, 256, 49, 169, 200, 223, 124, 92, 118, 129, 104, 44, 157, 17, 195, 211, 198, 64, 205, 235, 50, 120, 31, 23, 158, 225, 26, 11, 232, 197, 113, 117, 178, 16, 244, 123, 141, 30, 72, 70, 168, 249, 135, 67, 58, 242, 221, 222, 173, 4, 61, 95, 228, 136, 18, 146, 42, 255, 98, 81, 143, 189, 248, 184, 236, 1, 208, 88, 57, 34, 133, 165, 139, 128, 153, 213, 100, 240, 62, 46, 59, 193, 52, 22, 207, 137, 226, 234, 99, 32, 231, 246, 25, 60, 144, 140, 79, 241, 13, 134, 116, 227, 185, 187, 89, 8, 122, 190, 199, 15, 36, 35, 84, 253, 196, 162, 29, 121, 239, 111, 215, 2, 159, 176, 114, 68, 9, 73, 21, 256, 49, 169, 200, 223, 124, 92, 118, 129, 104, 44, 157, 17, 195, 211, 198, 64, 205, 235, 50, 120, 31, 23, 158, 225, 26, 11, 232, 197, 113, 117, 178, 16, 244, 123, 141, 30, 72, 70, 168, 249, 135, 67, 58, 242, 221, 222, 173, 4, 61, 95, 228, 136, 18, 146, 42, 255, 98, 81, 143, 189, 248, 184, 236, 1], -[1, 209, 248, 175, 81, 224, 42, 40, 136, 154, 61, 156, 222, 138, 58, 43, 249, 127, 72, 142, 123, 7, 178, 194, 197, 53, 26, 37, 23, 181, 50, 170, 64, 12, 195, 149, 44, 201, 118, 247, 223, 90, 49, 218, 73, 94, 114, 182, 2, 161, 239, 93, 162, 191, 84, 80, 15, 51, 122, 55, 187, 19, 116, 86, 241, 254, 144, 27, 246, 14, 99, 131, 137, 106, 52, 74, 46, 105, 100, 83, 128, 24, 133, 41, 88, 145, 236, 237, 189, 180, 98, 179, 146, 188, 228, 107, 4, 65, 221, 186, 67, 125, 168, 160, 30, 102, 244, 110, 117, 38, 232, 172, 225, 251, 31, 54, 235, 28, 198, 5, 17, 212, 104, 148, 92, 210, 200, 166, 256, 48, 9, 82, 176, 33, 215, 217, 121, 103, 196, 101, 35, 119, 199, 214, 8, 130, 185, 115, 134, 250, 79, 63, 60, 204, 231, 220, 234, 76, 207, 87, 193, 245, 62, 108, 213, 56, 139, 10, 34, 167, 208, 39, 184, 163, 143, 75, 255, 96, 18, 164, 95, 66, 173, 177, 242, 206, 135, 202, 70, 238, 141, 171, 16, 3, 113, 230, 11, 243, 158, 126, 120, 151, 205, 183, 211, 152, 157, 174, 129, 233, 124, 216, 169, 112, 21, 20, 68, 77, 159, 78, 111, 69, 29, 150, 253, 192, 36, 71, 190, 132, 89, 97, 227, 155, 13, 147, 140, 219, 25, 85, 32, 6, 226, 203, 22, 229, 59, 252, 240, 45, 153, 109, 165, 47, 57, 91, 1], -[1, 210, 153, 5, 22, 251, 25, 110, 227, 125, 36, 107, 111, 180, 21, 41, 129, 105, 205, 131, 11, 254, 141, 55, 242, 191, 18, 182, 184, 90, 139, 149, 193, 181, 231, 194, 134, 127, 199, 156, 121, 224, 9, 91, 92, 45, 198, 203, 225, 219, 244, 97, 67, 192, 228, 78, 189, 112, 133, 174, 46, 151, 99, 230, 241, 238, 122, 177, 162, 96, 114, 39, 223, 56, 195, 87, 23, 204, 178, 115, 249, 119, 61, 217, 81, 48, 57, 148, 240, 28, 226, 172, 140, 102, 89, 186, 253, 188, 159, 237, 169, 24, 157, 74, 120, 14, 113, 86, 70, 51, 173, 93, 255, 94, 208, 247, 213, 12, 207, 37, 60, 7, 185, 43, 35, 154, 215, 175, 256, 47, 104, 252, 235, 6, 232, 147, 30, 132, 221, 150, 146, 77, 236, 216, 128, 152, 52, 126, 246, 3, 116, 202, 15, 66, 239, 75, 73, 167, 118, 108, 64, 76, 26, 63, 123, 130, 58, 101, 136, 33, 248, 166, 165, 212, 59, 54, 32, 38, 13, 160, 190, 65, 29, 179, 68, 145, 124, 83, 211, 106, 158, 27, 16, 19, 135, 80, 95, 161, 143, 218, 34, 201, 62, 170, 234, 53, 79, 142, 8, 138, 196, 40, 176, 209, 200, 109, 17, 229, 31, 85, 117, 155, 168, 71, 4, 69, 98, 20, 88, 233, 100, 183, 137, 243, 144, 171, 187, 206, 84, 164, 2, 163, 49, 10, 44, 245, 50, 220, 197, 250, 72, 214, 222, 103, 42, 82, 1], -[1, 211, 60, 67, 2, 165, 120, 134, 4, 73, 240, 11, 8, 146, 223, 22, 16, 35, 189, 44, 32, 70, 121, 88, 64, 140, 242, 176, 128, 23, 227, 95, 256, 46, 197, 190, 255, 92, 137, 123, 253, 184, 17, 246, 249, 111, 34, 235, 241, 222, 68, 213, 225, 187, 136, 169, 193, 117, 15, 81, 129, 234, 30, 162, 1, 211, 60, 67, 2, 165, 120, 134, 4, 73, 240, 11, 8, 146, 223, 22, 16, 35, 189, 44, 32, 70, 121, 88, 64, 140, 242, 176, 128, 23, 227, 95, 256, 46, 197, 190, 255, 92, 137, 123, 253, 184, 17, 246, 249, 111, 34, 235, 241, 222, 68, 213, 225, 187, 136, 169, 193, 117, 15, 81, 129, 234, 30, 162, 1, 211, 60, 67, 2, 165, 120, 134, 4, 73, 240, 11, 8, 146, 223, 22, 16, 35, 189, 44, 32, 70, 121, 88, 64, 140, 242, 176, 128, 23, 227, 95, 256, 46, 197, 190, 255, 92, 137, 123, 253, 184, 17, 246, 249, 111, 34, 235, 241, 222, 68, 213, 225, 187, 136, 169, 193, 117, 15, 81, 129, 234, 30, 162, 1, 211, 60, 67, 2, 165, 120, 134, 4, 73, 240, 11, 8, 146, 223, 22, 16, 35, 189, 44, 32, 70, 121, 88, 64, 140, 242, 176, 128, 23, 227, 95, 256, 46, 197, 190, 255, 92, 137, 123, 253, 184, 17, 246, 249, 111, 34, 235, 241, 222, 68, 213, 225, 187, 136, 169, 193, 117, 15, 81, 129, 234, 30, 162, 1], -[1, 212, 226, 110, 190, 188, 21, 83, 120, 254, 135, 93, 184, 201, 207, 194, 8, 154, 9, 109, 235, 219, 168, 150, 189, 233, 52, 230, 187, 66, 114, 10, 64, 204, 72, 101, 81, 210, 59, 172, 227, 65, 159, 41, 211, 14, 141, 80, 255, 90, 62, 37, 134, 138, 215, 91, 17, 6, 244, 71, 146, 112, 100, 126, 241, 206, 239, 39, 44, 76, 178, 214, 136, 48, 153, 54, 140, 125, 29, 237, 129, 106, 113, 55, 95, 94, 139, 170, 60, 127, 196, 175, 92, 229, 232, 97, 4, 77, 133, 183, 246, 238, 84, 75, 223, 245, 26, 115, 222, 33, 57, 5, 32, 102, 36, 179, 169, 105, 158, 86, 242, 161, 208, 149, 234, 7, 199, 40, 256, 45, 31, 147, 67, 69, 236, 174, 137, 3, 122, 164, 73, 56, 50, 63, 249, 103, 248, 148, 22, 38, 89, 107, 68, 24, 205, 27, 70, 191, 143, 247, 193, 53, 185, 156, 176, 47, 198, 85, 30, 192, 98, 216, 46, 243, 116, 177, 2, 167, 195, 220, 123, 119, 42, 166, 240, 251, 13, 186, 111, 145, 157, 131, 16, 51, 18, 218, 213, 181, 79, 43, 121, 209, 104, 203, 117, 132, 228, 20, 128, 151, 144, 202, 162, 163, 118, 87, 197, 130, 61, 82, 165, 28, 25, 160, 253, 180, 124, 74, 11, 19, 173, 182, 34, 12, 231, 142, 35, 224, 200, 252, 225, 155, 221, 78, 88, 152, 99, 171, 15, 96, 49, 108, 23, 250, 58, 217, 1], -[1, 213, 137, 140, 8, 162, 68, 92, 64, 11, 30, 222, 255, 88, 240, 234, 241, 190, 121, 73, 129, 235, 197, 70, 4, 81, 34, 46, 32, 134, 15, 111, 256, 44, 120, 117, 249, 95, 189, 165, 193, 246, 227, 35, 2, 169, 17, 23, 16, 67, 136, 184, 128, 22, 60, 187, 253, 176, 223, 211, 225, 123, 242, 146, 1, 213, 137, 140, 8, 162, 68, 92, 64, 11, 30, 222, 255, 88, 240, 234, 241, 190, 121, 73, 129, 235, 197, 70, 4, 81, 34, 46, 32, 134, 15, 111, 256, 44, 120, 117, 249, 95, 189, 165, 193, 246, 227, 35, 2, 169, 17, 23, 16, 67, 136, 184, 128, 22, 60, 187, 253, 176, 223, 211, 225, 123, 242, 146, 1, 213, 137, 140, 8, 162, 68, 92, 64, 11, 30, 222, 255, 88, 240, 234, 241, 190, 121, 73, 129, 235, 197, 70, 4, 81, 34, 46, 32, 134, 15, 111, 256, 44, 120, 117, 249, 95, 189, 165, 193, 246, 227, 35, 2, 169, 17, 23, 16, 67, 136, 184, 128, 22, 60, 187, 253, 176, 223, 211, 225, 123, 242, 146, 1, 213, 137, 140, 8, 162, 68, 92, 64, 11, 30, 222, 255, 88, 240, 234, 241, 190, 121, 73, 129, 235, 197, 70, 4, 81, 34, 46, 32, 134, 15, 111, 256, 44, 120, 117, 249, 95, 189, 165, 193, 246, 227, 35, 2, 169, 17, 23, 16, 67, 136, 184, 128, 22, 60, 187, 253, 176, 223, 211, 225, 123, 242, 146, 1], -[1, 214, 50, 163, 187, 183, 98, 155, 17, 40, 79, 201, 95, 27, 124, 65, 32, 166, 58, 76, 73, 202, 52, 77, 30, 252, 215, 7, 213, 93, 113, 24, 253, 172, 57, 119, 23, 39, 122, 151, 189, 97, 198, 224, 134, 149, 18, 254, 129, 107, 25, 210, 222, 220, 49, 206, 137, 20, 168, 229, 176, 142, 62, 161, 16, 83, 29, 38, 165, 101, 26, 167, 15, 126, 236, 132, 235, 175, 185, 12, 255, 86, 157, 188, 140, 148, 61, 204, 223, 177, 99, 112, 67, 203, 9, 127, 193, 182, 141, 105, 111, 110, 153, 103, 197, 10, 84, 243, 88, 71, 31, 209, 8, 170, 143, 19, 211, 179, 13, 212, 136, 63, 118, 66, 246, 216, 221, 6, 256, 43, 207, 94, 70, 74, 159, 102, 240, 217, 178, 56, 162, 230, 133, 192, 225, 91, 199, 181, 184, 55, 205, 180, 227, 5, 42, 250, 44, 164, 144, 233, 4, 85, 200, 138, 234, 218, 135, 106, 68, 160, 59, 33, 123, 108, 239, 3, 128, 150, 232, 47, 35, 37, 208, 51, 120, 237, 89, 28, 81, 115, 195, 96, 241, 174, 228, 219, 92, 156, 231, 90, 242, 131, 21, 125, 22, 82, 72, 245, 2, 171, 100, 69, 117, 109, 196, 53, 34, 80, 158, 145, 190, 54, 248, 130, 64, 75, 116, 152, 146, 147, 104, 154, 60, 247, 173, 14, 169, 186, 226, 48, 249, 87, 114, 238, 46, 78, 244, 45, 121, 194, 139, 191, 11, 41, 36, 251, 1], -[1, 215, 222, 185, 197, 207, 44, 208, 2, 173, 187, 113, 137, 157, 88, 159, 4, 89, 117, 226, 17, 57, 176, 61, 8, 178, 234, 195, 34, 114, 95, 122, 16, 99, 211, 133, 68, 228, 190, 244, 32, 198, 165, 9, 136, 199, 123, 231, 64, 139, 73, 18, 15, 141, 246, 205, 128, 21, 146, 36, 30, 25, 235, 153, 256, 42, 35, 72, 60, 50, 213, 49, 255, 84, 70, 144, 120, 100, 169, 98, 253, 168, 140, 31, 240, 200, 81, 196, 249, 79, 23, 62, 223, 143, 162, 135, 241, 158, 46, 124, 189, 29, 67, 13, 225, 59, 92, 248, 121, 58, 134, 26, 193, 118, 184, 239, 242, 116, 11, 52, 129, 236, 111, 221, 227, 232, 22, 104, 1, 215, 222, 185, 197, 207, 44, 208, 2, 173, 187, 113, 137, 157, 88, 159, 4, 89, 117, 226, 17, 57, 176, 61, 8, 178, 234, 195, 34, 114, 95, 122, 16, 99, 211, 133, 68, 228, 190, 244, 32, 198, 165, 9, 136, 199, 123, 231, 64, 139, 73, 18, 15, 141, 246, 205, 128, 21, 146, 36, 30, 25, 235, 153, 256, 42, 35, 72, 60, 50, 213, 49, 255, 84, 70, 144, 120, 100, 169, 98, 253, 168, 140, 31, 240, 200, 81, 196, 249, 79, 23, 62, 223, 143, 162, 135, 241, 158, 46, 124, 189, 29, 67, 13, 225, 59, 92, 248, 121, 58, 134, 26, 193, 118, 184, 239, 242, 116, 11, 52, 129, 236, 111, 221, 227, 232, 22, 104, 1], -[1, 216, 139, 212, 46, 170, 226, 243, 60, 110, 116, 127, 190, 177, 196, 188, 2, 175, 21, 167, 92, 83, 195, 229, 120, 220, 232, 254, 123, 97, 135, 119, 4, 93, 42, 77, 184, 166, 133, 201, 240, 183, 207, 251, 246, 194, 13, 238, 8, 186, 84, 154, 111, 75, 9, 145, 223, 109, 157, 245, 235, 131, 26, 219, 16, 115, 168, 51, 222, 150, 18, 33, 189, 218, 57, 233, 213, 5, 52, 181, 32, 230, 79, 102, 187, 43, 36, 66, 121, 179, 114, 209, 169, 10, 104, 105, 64, 203, 158, 204, 117, 86, 72, 132, 242, 101, 228, 161, 81, 20, 208, 210, 128, 149, 59, 151, 234, 172, 144, 7, 227, 202, 199, 65, 162, 40, 159, 163, 256, 41, 118, 45, 211, 87, 31, 14, 197, 147, 141, 130, 67, 80, 61, 69, 255, 82, 236, 90, 165, 174, 62, 28, 137, 37, 25, 3, 134, 160, 122, 138, 253, 164, 215, 180, 73, 91, 124, 56, 17, 74, 50, 6, 11, 63, 244, 19, 249, 71, 173, 103, 146, 182, 248, 112, 34, 148, 100, 12, 22, 126, 231, 38, 241, 142, 89, 206, 35, 107, 239, 224, 68, 39, 200, 24, 44, 252, 205, 76, 225, 27, 178, 155, 70, 214, 221, 191, 136, 78, 143, 48, 88, 247, 153, 152, 193, 54, 99, 53, 140, 171, 185, 125, 15, 156, 29, 96, 176, 237, 49, 47, 129, 108, 198, 106, 23, 85, 113, 250, 30, 55, 58, 192, 95, 217, 98, 94, 1], -[1, 217, 58, 250, 23, 108, 49, 96, 15, 171, 99, 152, 88, 78, 221, 155, 225, 252, 200, 224, 35, 142, 231, 12, 34, 182, 173, 19, 11, 74, 124, 180, 253, 160, 25, 28, 165, 82, 61, 130, 197, 87, 118, 163, 162, 202, 144, 151, 128, 20, 228, 132, 117, 203, 104, 209, 121, 43, 79, 181, 213, 218, 18, 51, 16, 131, 157, 145, 111, 186, 13, 251, 240, 166, 42, 119, 123, 220, 195, 167, 2, 177, 116, 243, 46, 216, 98, 192, 30, 85, 198, 47, 176, 156, 185, 53, 193, 247, 143, 191, 70, 27, 205, 24, 68, 107, 89, 38, 22, 148, 248, 103, 249, 63, 50, 56, 73, 164, 122, 3, 137, 174, 236, 69, 67, 147, 31, 45, 256, 40, 199, 7, 234, 149, 208, 161, 242, 86, 158, 105, 169, 179, 36, 102, 32, 5, 57, 33, 222, 115, 26, 245, 223, 75, 84, 238, 246, 183, 133, 77, 4, 97, 232, 229, 92, 175, 196, 127, 60, 170, 139, 94, 95, 55, 113, 106, 129, 237, 29, 125, 140, 54, 153, 48, 136, 214, 178, 76, 44, 39, 239, 206, 241, 126, 100, 112, 146, 71, 244, 6, 17, 91, 215, 138, 134, 37, 62, 90, 255, 80, 141, 14, 211, 41, 159, 65, 227, 172, 59, 210, 81, 101, 72, 204, 64, 10, 114, 66, 187, 230, 52, 233, 189, 150, 168, 219, 235, 109, 9, 154, 8, 194, 207, 201, 184, 93, 135, 254, 120, 83, 21, 188, 190, 110, 226, 212, 1], -[1, 218, 236, 48, 184, 20, 248, 94, 189, 82, 143, 77, 81, 182, 98, 33, 255, 78, 42, 161, 146, 217, 18, 69, 136, 93, 228, 103, 95, 150, 61, 191, 4, 101, 173, 192, 222, 80, 221, 119, 242, 71, 58, 51, 67, 214, 135, 132, 249, 55, 168, 130, 70, 97, 72, 19, 30, 115, 141, 155, 123, 86, 244, 250, 16, 147, 178, 254, 117, 63, 113, 219, 197, 27, 232, 204, 11, 85, 26, 14, 225, 220, 158, 6, 23, 131, 31, 76, 120, 203, 50, 106, 235, 87, 205, 229, 64, 74, 198, 245, 211, 252, 195, 105, 17, 108, 157, 45, 44, 83, 104, 56, 129, 109, 118, 24, 92, 10, 124, 47, 223, 41, 200, 167, 169, 91, 49, 145, 256, 39, 21, 209, 73, 237, 9, 163, 68, 175, 114, 180, 176, 75, 159, 224, 2, 179, 215, 96, 111, 40, 239, 188, 121, 164, 29, 154, 162, 107, 196, 66, 253, 156, 84, 65, 35, 177, 36, 138, 15, 186, 199, 206, 190, 43, 122, 125, 8, 202, 89, 127, 187, 160, 185, 238, 227, 142, 116, 102, 134, 171, 13, 7, 241, 110, 79, 3, 140, 194, 144, 38, 60, 230, 25, 53, 246, 172, 231, 243, 32, 37, 99, 251, 234, 126, 226, 181, 137, 54, 207, 151, 22, 170, 52, 28, 193, 183, 59, 12, 46, 5, 62, 152, 240, 149, 100, 212, 213, 174, 153, 201, 128, 148, 139, 233, 165, 247, 133, 210, 34, 216, 57, 90, 88, 166, 208, 112, 1], -[1, 219, 159, 126, 95, 245, 199, 148, 30, 145, 144, 182, 23, 154, 59, 71, 129, 238, 208, 63, 176, 251, 228, 74, 15, 201, 72, 91, 140, 77, 158, 164, 193, 119, 104, 160, 88, 254, 114, 37, 136, 229, 36, 174, 70, 167, 79, 82, 225, 188, 52, 80, 44, 127, 57, 147, 68, 243, 18, 87, 35, 212, 168, 41, 241, 94, 26, 40, 22, 192, 157, 202, 34, 250, 9, 172, 146, 106, 84, 149, 249, 47, 13, 20, 11, 96, 207, 101, 17, 125, 133, 86, 73, 53, 42, 203, 253, 152, 135, 10, 134, 48, 232, 179, 137, 191, 195, 43, 165, 155, 21, 230, 255, 76, 196, 5, 67, 24, 116, 218, 197, 224, 226, 150, 211, 206, 139, 115, 256, 38, 98, 131, 162, 12, 58, 109, 227, 112, 113, 75, 234, 103, 198, 186, 128, 19, 49, 194, 81, 6, 29, 183, 242, 56, 185, 166, 117, 180, 99, 93, 64, 138, 153, 97, 169, 3, 143, 220, 121, 28, 221, 83, 187, 90, 178, 175, 32, 69, 205, 177, 213, 130, 200, 110, 189, 14, 239, 170, 222, 45, 89, 216, 16, 163, 231, 217, 235, 65, 100, 55, 223, 7, 248, 85, 111, 151, 173, 108, 8, 210, 244, 237, 246, 161, 50, 156, 240, 132, 124, 171, 184, 204, 215, 54, 4, 105, 122, 247, 123, 209, 25, 78, 120, 66, 62, 214, 92, 102, 236, 27, 2, 181, 61, 252, 190, 233, 141, 39, 60, 33, 31, 107, 46, 51, 118, 142, 1], -[1, 220, 84, 233, 117, 40, 62, 19, 68, 54, 58, 167, 246, 150, 104, 7, 255, 74, 89, 48, 23, 177, 133, 219, 121, 149, 141, 180, 22, 214, 49, 243, 4, 109, 79, 161, 211, 160, 248, 76, 15, 216, 232, 154, 213, 86, 159, 28, 249, 39, 99, 192, 92, 194, 18, 105, 227, 82, 50, 206, 88, 85, 196, 201, 16, 179, 59, 130, 73, 126, 221, 47, 60, 93, 157, 102, 81, 87, 122, 112, 225, 156, 139, 254, 111, 5, 72, 163, 137, 71, 200, 53, 95, 83, 13, 33, 64, 202, 236, 6, 35, 247, 113, 188, 240, 115, 114, 151, 67, 91, 231, 191, 129, 110, 42, 245, 187, 20, 31, 138, 34, 27, 29, 212, 123, 75, 52, 132, 256, 37, 173, 24, 140, 217, 195, 238, 189, 203, 199, 90, 11, 107, 153, 250, 2, 183, 168, 209, 234, 80, 124, 38, 136, 108, 116, 77, 235, 43, 208, 14, 253, 148, 178, 96, 46, 97, 9, 181, 242, 41, 25, 103, 44, 171, 98, 229, 8, 218, 158, 65, 165, 63, 239, 152, 30, 175, 207, 51, 169, 172, 61, 56, 241, 78, 198, 127, 184, 131, 36, 210, 197, 164, 100, 155, 176, 170, 135, 145, 32, 101, 118, 3, 146, 252, 185, 94, 120, 186, 57, 204, 162, 174, 244, 224, 193, 55, 21, 251, 222, 10, 144, 69, 17, 142, 143, 106, 190, 166, 26, 66, 128, 147, 215, 12, 70, 237, 226, 119, 223, 230, 228, 45, 134, 182, 205, 125, 1], -[1, 221, 11, 118, 121, 13, 46, 143, 249, 31, 169, 84, 60, 153, 146, 141, 64, 9, 190, 99, 34, 61, 117, 157, 2, 185, 22, 236, 242, 26, 92, 29, 241, 62, 81, 168, 120, 49, 35, 25, 128, 18, 123, 198, 68, 122, 234, 57, 4, 113, 44, 215, 227, 52, 184, 58, 225, 124, 162, 79, 240, 98, 70, 50, 256, 36, 246, 139, 136, 244, 211, 114, 8, 226, 88, 173, 197, 104, 111, 116, 193, 248, 67, 158, 223, 196, 140, 100, 255, 72, 235, 21, 15, 231, 165, 228, 16, 195, 176, 89, 137, 208, 222, 232, 129, 239, 134, 59, 189, 135, 23, 200, 253, 144, 213, 42, 30, 205, 73, 199, 32, 133, 95, 178, 17, 159, 187, 207, 1, 221, 11, 118, 121, 13, 46, 143, 249, 31, 169, 84, 60, 153, 146, 141, 64, 9, 190, 99, 34, 61, 117, 157, 2, 185, 22, 236, 242, 26, 92, 29, 241, 62, 81, 168, 120, 49, 35, 25, 128, 18, 123, 198, 68, 122, 234, 57, 4, 113, 44, 215, 227, 52, 184, 58, 225, 124, 162, 79, 240, 98, 70, 50, 256, 36, 246, 139, 136, 244, 211, 114, 8, 226, 88, 173, 197, 104, 111, 116, 193, 248, 67, 158, 223, 196, 140, 100, 255, 72, 235, 21, 15, 231, 165, 228, 16, 195, 176, 89, 137, 208, 222, 232, 129, 239, 134, 59, 189, 135, 23, 200, 253, 144, 213, 42, 30, 205, 73, 199, 32, 133, 95, 178, 17, 159, 187, 207, 1], -[1, 222, 197, 44, 2, 187, 137, 88, 4, 117, 17, 176, 8, 234, 34, 95, 16, 211, 68, 190, 32, 165, 136, 123, 64, 73, 15, 246, 128, 146, 30, 235, 256, 35, 60, 213, 255, 70, 120, 169, 253, 140, 240, 81, 249, 23, 223, 162, 241, 46, 189, 67, 225, 92, 121, 134, 193, 184, 242, 11, 129, 111, 227, 22, 1, 222, 197, 44, 2, 187, 137, 88, 4, 117, 17, 176, 8, 234, 34, 95, 16, 211, 68, 190, 32, 165, 136, 123, 64, 73, 15, 246, 128, 146, 30, 235, 256, 35, 60, 213, 255, 70, 120, 169, 253, 140, 240, 81, 249, 23, 223, 162, 241, 46, 189, 67, 225, 92, 121, 134, 193, 184, 242, 11, 129, 111, 227, 22, 1, 222, 197, 44, 2, 187, 137, 88, 4, 117, 17, 176, 8, 234, 34, 95, 16, 211, 68, 190, 32, 165, 136, 123, 64, 73, 15, 246, 128, 146, 30, 235, 256, 35, 60, 213, 255, 70, 120, 169, 253, 140, 240, 81, 249, 23, 223, 162, 241, 46, 189, 67, 225, 92, 121, 134, 193, 184, 242, 11, 129, 111, 227, 22, 1, 222, 197, 44, 2, 187, 137, 88, 4, 117, 17, 176, 8, 234, 34, 95, 16, 211, 68, 190, 32, 165, 136, 123, 64, 73, 15, 246, 128, 146, 30, 235, 256, 35, 60, 213, 255, 70, 120, 169, 253, 140, 240, 81, 249, 23, 223, 162, 241, 46, 189, 67, 225, 92, 121, 134, 193, 184, 242, 11, 129, 111, 227, 22, 1], -[1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1], -[1, 224, 61, 43, 123, 53, 50, 149, 223, 94, 239, 80, 187, 254, 99, 74, 128, 145, 98, 107, 67, 102, 232, 54, 17, 210, 9, 217, 35, 130, 79, 220, 193, 56, 208, 75, 95, 206, 141, 230, 120, 152, 124, 20, 111, 192, 89, 147, 32, 229, 153, 91, 81, 154, 58, 142, 197, 181, 195, 247, 73, 161, 84, 55, 241, 14, 52, 83, 88, 180, 228, 186, 30, 38, 31, 5, 92, 48, 215, 101, 8, 250, 231, 87, 213, 167, 143, 164, 242, 238, 113, 126, 211, 233, 21, 78, 253, 132, 13, 85, 22, 45, 57, 175, 136, 138, 72, 194, 23, 12, 118, 218, 2, 191, 122, 86, 246, 106, 100, 41, 189, 188, 221, 160, 117, 251, 198, 148, 256, 33, 196, 214, 134, 204, 207, 108, 34, 163, 18, 177, 70, 3, 158, 183, 129, 112, 159, 150, 190, 155, 25, 203, 240, 47, 248, 40, 222, 127, 178, 37, 64, 201, 49, 182, 162, 51, 116, 27, 137, 105, 133, 237, 146, 65, 168, 110, 225, 28, 104, 166, 176, 103, 199, 115, 60, 76, 62, 10, 184, 96, 173, 202, 16, 243, 205, 174, 169, 77, 29, 71, 227, 219, 226, 252, 165, 209, 42, 156, 249, 7, 26, 170, 44, 90, 114, 93, 15, 19, 144, 131, 46, 24, 236, 179, 4, 125, 244, 172, 235, 212, 200, 82, 121, 119, 185, 63, 234, 245, 139, 39, 255, 66, 135, 171, 11, 151, 157, 216, 68, 69, 36, 97, 140, 6, 59, 109, 1], -[1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1], -[1, 226, 190, 21, 120, 135, 184, 207, 8, 9, 235, 168, 189, 52, 187, 114, 64, 72, 81, 59, 227, 159, 211, 141, 255, 62, 134, 215, 17, 244, 146, 100, 241, 239, 44, 178, 136, 153, 140, 29, 129, 113, 95, 139, 60, 196, 92, 232, 4, 133, 246, 84, 223, 26, 222, 57, 32, 36, 169, 158, 242, 208, 234, 199, 256, 31, 67, 236, 137, 122, 73, 50, 249, 248, 22, 89, 68, 205, 70, 143, 193, 185, 176, 198, 30, 98, 46, 116, 2, 195, 123, 42, 240, 13, 111, 157, 16, 18, 213, 79, 121, 104, 117, 228, 128, 144, 162, 118, 197, 61, 165, 25, 253, 124, 11, 173, 34, 231, 35, 200, 225, 221, 88, 99, 15, 49, 23, 58, 1, 226, 190, 21, 120, 135, 184, 207, 8, 9, 235, 168, 189, 52, 187, 114, 64, 72, 81, 59, 227, 159, 211, 141, 255, 62, 134, 215, 17, 244, 146, 100, 241, 239, 44, 178, 136, 153, 140, 29, 129, 113, 95, 139, 60, 196, 92, 232, 4, 133, 246, 84, 223, 26, 222, 57, 32, 36, 169, 158, 242, 208, 234, 199, 256, 31, 67, 236, 137, 122, 73, 50, 249, 248, 22, 89, 68, 205, 70, 143, 193, 185, 176, 198, 30, 98, 46, 116, 2, 195, 123, 42, 240, 13, 111, 157, 16, 18, 213, 79, 121, 104, 117, 228, 128, 144, 162, 118, 197, 61, 165, 25, 253, 124, 11, 173, 34, 231, 35, 200, 225, 221, 88, 99, 15, 49, 23, 58, 1], -[1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1], -[1, 228, 70, 26, 17, 21, 162, 185, 32, 100, 184, 61, 30, 158, 44, 9, 253, 116, 234, 153, 189, 173, 123, 31, 129, 114, 35, 13, 137, 139, 81, 221, 16, 50, 92, 159, 15, 79, 22, 133, 255, 58, 117, 205, 223, 215, 190, 144, 193, 57, 146, 135, 197, 198, 169, 239, 8, 25, 46, 208, 136, 168, 11, 195, 256, 29, 187, 231, 240, 236, 95, 72, 225, 157, 73, 196, 227, 99, 213, 248, 4, 141, 23, 104, 68, 84, 134, 226, 128, 143, 222, 244, 120, 118, 176, 36, 241, 207, 165, 98, 242, 178, 235, 124, 2, 199, 140, 52, 34, 42, 67, 113, 64, 200, 111, 122, 60, 59, 88, 18, 249, 232, 211, 49, 121, 89, 246, 62, 1, 228, 70, 26, 17, 21, 162, 185, 32, 100, 184, 61, 30, 158, 44, 9, 253, 116, 234, 153, 189, 173, 123, 31, 129, 114, 35, 13, 137, 139, 81, 221, 16, 50, 92, 159, 15, 79, 22, 133, 255, 58, 117, 205, 223, 215, 190, 144, 193, 57, 146, 135, 197, 198, 169, 239, 8, 25, 46, 208, 136, 168, 11, 195, 256, 29, 187, 231, 240, 236, 95, 72, 225, 157, 73, 196, 227, 99, 213, 248, 4, 141, 23, 104, 68, 84, 134, 226, 128, 143, 222, 244, 120, 118, 176, 36, 241, 207, 165, 98, 242, 178, 235, 124, 2, 199, 140, 52, 34, 42, 67, 113, 64, 200, 111, 122, 60, 59, 88, 18, 249, 232, 211, 49, 121, 89, 246, 62, 1], -[1, 229, 13, 150, 169, 151, 141, 164, 34, 76, 185, 217, 92, 251, 168, 179, 128, 14, 122, 182, 44, 53, 58, 175, 240, 219, 36, 20, 211, 3, 173, 39, 193, 250, 196, 166, 235, 102, 228, 41, 137, 19, 239, 247, 23, 127, 42, 109, 32, 132, 159, 174, 11, 206, 143, 108, 60, 119, 9, 5, 117, 65, 236, 74, 241, 191, 49, 170, 123, 154, 57, 203, 227, 69, 124, 126, 70, 96, 139, 220, 8, 33, 104, 172, 67, 180, 100, 27, 15, 94, 195, 194, 222, 209, 59, 147, 253, 112, 205, 171, 95, 167, 207, 115, 121, 210, 31, 160, 146, 24, 99, 55, 2, 201, 26, 43, 81, 45, 25, 71, 68, 152, 113, 177, 184, 245, 79, 101, 256, 28, 244, 107, 88, 106, 116, 93, 223, 181, 72, 40, 165, 6, 89, 78, 129, 243, 135, 75, 213, 204, 199, 82, 17, 38, 221, 237, 46, 254, 84, 218, 64, 7, 61, 91, 22, 155, 29, 216, 120, 238, 18, 10, 234, 130, 215, 148, 225, 125, 98, 83, 246, 51, 114, 149, 197, 138, 248, 252, 140, 192, 21, 183, 16, 66, 208, 87, 134, 103, 200, 54, 30, 188, 133, 131, 187, 161, 118, 37, 249, 224, 153, 85, 190, 77, 157, 230, 242, 163, 62, 63, 35, 48, 198, 110, 4, 145, 52, 86, 162, 90, 50, 142, 136, 47, 226, 97, 111, 233, 158, 202, 255, 56, 231, 214, 176, 212, 232, 186, 189, 105, 144, 80, 73, 12, 178, 156, 1], -[1, 230, 215, 106, 222, 174, 185, 145, 197, 78, 207, 65, 44, 97, 208, 38, 2, 203, 173, 212, 187, 91, 113, 33, 137, 156, 157, 130, 88, 194, 159, 76, 4, 149, 89, 167, 117, 182, 226, 66, 17, 55, 57, 3, 176, 131, 61, 152, 8, 41, 178, 77, 234, 107, 195, 132, 34, 110, 114, 6, 95, 5, 122, 47, 16, 82, 99, 154, 211, 214, 133, 7, 68, 220, 228, 12, 190, 10, 244, 94, 32, 164, 198, 51, 165, 171, 9, 14, 136, 183, 199, 24, 123, 20, 231, 188, 64, 71, 139, 102, 73, 85, 18, 28, 15, 109, 141, 48, 246, 40, 205, 119, 128, 142, 21, 204, 146, 170, 36, 56, 30, 218, 25, 96, 235, 80, 153, 238, 256, 27, 42, 151, 35, 83, 72, 112, 60, 179, 50, 192, 213, 160, 49, 219, 255, 54, 84, 45, 70, 166, 144, 224, 120, 101, 100, 127, 169, 63, 98, 181, 253, 108, 168, 90, 140, 75, 31, 191, 240, 202, 200, 254, 81, 126, 196, 105, 249, 216, 79, 180, 23, 150, 62, 125, 223, 147, 143, 251, 162, 252, 135, 210, 241, 175, 158, 103, 46, 43, 124, 250, 189, 37, 29, 245, 67, 247, 13, 163, 225, 93, 59, 206, 92, 86, 248, 243, 121, 74, 58, 233, 134, 237, 26, 69, 193, 186, 118, 155, 184, 172, 239, 229, 242, 148, 116, 209, 11, 217, 52, 138, 129, 115, 236, 53, 111, 87, 221, 201, 227, 39, 232, 161, 22, 177, 104, 19, 1], -[1, 231, 162, 157, 30, 248, 234, 84, 129, 244, 81, 207, 15, 124, 117, 42, 193, 122, 169, 232, 136, 62, 187, 21, 225, 61, 213, 116, 68, 31, 222, 139, 241, 159, 235, 58, 34, 144, 111, 198, 249, 208, 246, 29, 17, 72, 184, 99, 253, 104, 123, 143, 137, 36, 92, 178, 255, 52, 190, 200, 197, 18, 46, 89, 256, 26, 95, 100, 227, 9, 23, 173, 128, 13, 176, 50, 242, 133, 140, 215, 64, 135, 88, 25, 121, 195, 70, 236, 32, 196, 44, 141, 189, 226, 35, 118, 16, 98, 22, 199, 223, 113, 146, 59, 8, 49, 11, 228, 240, 185, 73, 158, 4, 153, 134, 114, 120, 221, 165, 79, 2, 205, 67, 57, 60, 239, 211, 168, 1, 231, 162, 157, 30, 248, 234, 84, 129, 244, 81, 207, 15, 124, 117, 42, 193, 122, 169, 232, 136, 62, 187, 21, 225, 61, 213, 116, 68, 31, 222, 139, 241, 159, 235, 58, 34, 144, 111, 198, 249, 208, 246, 29, 17, 72, 184, 99, 253, 104, 123, 143, 137, 36, 92, 178, 255, 52, 190, 200, 197, 18, 46, 89, 256, 26, 95, 100, 227, 9, 23, 173, 128, 13, 176, 50, 242, 133, 140, 215, 64, 135, 88, 25, 121, 195, 70, 236, 32, 196, 44, 141, 189, 226, 35, 118, 16, 98, 22, 199, 223, 113, 146, 59, 8, 49, 11, 228, 240, 185, 73, 158, 4, 153, 134, 114, 120, 221, 165, 79, 2, 205, 67, 57, 60, 239, 211, 168, 1], -[1, 232, 111, 52, 242, 118, 134, 248, 225, 29, 46, 135, 223, 79, 81, 31, 253, 100, 70, 49, 60, 42, 235, 36, 128, 141, 73, 231, 136, 198, 190, 133, 16, 114, 234, 61, 17, 89, 88, 113, 2, 207, 222, 104, 227, 236, 11, 239, 193, 58, 92, 13, 189, 158, 162, 62, 249, 200, 140, 98, 120, 84, 213, 72, 256, 25, 146, 205, 15, 139, 123, 9, 32, 228, 211, 122, 34, 178, 176, 226, 4, 157, 187, 208, 197, 215, 22, 221, 129, 116, 184, 26, 121, 59, 67, 124, 241, 143, 23, 196, 240, 168, 169, 144, 255, 50, 35, 153, 30, 21, 246, 18, 64, 199, 165, 244, 68, 99, 95, 195, 8, 57, 117, 159, 137, 173, 44, 185, 1, 232, 111, 52, 242, 118, 134, 248, 225, 29, 46, 135, 223, 79, 81, 31, 253, 100, 70, 49, 60, 42, 235, 36, 128, 141, 73, 231, 136, 198, 190, 133, 16, 114, 234, 61, 17, 89, 88, 113, 2, 207, 222, 104, 227, 236, 11, 239, 193, 58, 92, 13, 189, 158, 162, 62, 249, 200, 140, 98, 120, 84, 213, 72, 256, 25, 146, 205, 15, 139, 123, 9, 32, 228, 211, 122, 34, 178, 176, 226, 4, 157, 187, 208, 197, 215, 22, 221, 129, 116, 184, 26, 121, 59, 67, 124, 241, 143, 23, 196, 240, 168, 169, 144, 255, 50, 35, 153, 30, 21, 246, 18, 64, 199, 165, 244, 68, 99, 95, 195, 8, 57, 117, 159, 137, 173, 44, 185, 1], -[1, 233, 62, 54, 246, 7, 89, 177, 121, 180, 49, 109, 211, 76, 232, 86, 249, 192, 18, 82, 88, 201, 59, 126, 60, 102, 122, 156, 111, 163, 200, 83, 64, 6, 113, 115, 67, 191, 42, 20, 34, 212, 52, 37, 140, 238, 199, 107, 2, 209, 124, 108, 235, 14, 178, 97, 242, 103, 98, 218, 165, 152, 207, 172, 241, 127, 36, 164, 176, 145, 118, 252, 120, 204, 244, 55, 222, 69, 143, 166, 128, 12, 226, 230, 134, 125, 84, 40, 68, 167, 104, 74, 23, 219, 141, 214, 4, 161, 248, 216, 213, 28, 99, 194, 227, 206, 196, 179, 73, 47, 157, 87, 225, 254, 72, 71, 95, 33, 236, 247, 240, 151, 231, 110, 187, 138, 29, 75, 256, 24, 195, 203, 11, 250, 168, 80, 136, 77, 208, 148, 46, 181, 25, 171, 8, 65, 239, 175, 169, 56, 198, 131, 197, 155, 135, 101, 146, 94, 57, 174, 193, 251, 144, 142, 190, 66, 215, 237, 223, 45, 205, 220, 117, 19, 58, 150, 255, 48, 133, 149, 22, 243, 79, 160, 15, 154, 159, 39, 92, 105, 50, 85, 16, 130, 221, 93, 81, 112, 139, 5, 137, 53, 13, 202, 35, 188, 114, 91, 129, 245, 31, 27, 123, 132, 173, 217, 189, 90, 153, 183, 234, 38, 116, 43, 253, 96, 9, 41, 44, 229, 158, 63, 30, 51, 61, 78, 184, 210, 100, 170, 32, 3, 185, 186, 162, 224, 21, 10, 17, 106, 26, 147, 70, 119, 228, 182, 1], -[1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, 95, 128, 140, 121, 44, 16, 146, 240, 134, 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, 190, 256, 23, 242, 88, 32, 35, 223, 11, 4, 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, 123, 255, 46, 227, 176, 64, 70, 189, 22, 8, 73, 120, 67, 1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, 95, 128, 140, 121, 44, 16, 146, 240, 134, 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, 190, 256, 23, 242, 88, 32, 35, 223, 11, 4, 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, 123, 255, 46, 227, 176, 64, 70, 189, 22, 8, 73, 120, 67, 1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, 95, 128, 140, 121, 44, 16, 146, 240, 134, 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, 190, 256, 23, 242, 88, 32, 35, 223, 11, 4, 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, 123, 255, 46, 227, 176, 64, 70, 189, 22, 8, 73, 120, 67, 1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, 95, 128, 140, 121, 44, 16, 146, 240, 134, 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, 190, 256, 23, 242, 88, 32, 35, 223, 11, 4, 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, 123, 255, 46, 227, 176, 64, 70, 189, 22, 8, 73, 120, 67, 1], -[1, 235, 227, 146, 129, 246, 242, 73, 193, 123, 121, 165, 225, 190, 189, 211, 241, 95, 223, 234, 249, 176, 240, 117, 253, 88, 120, 187, 255, 44, 60, 222, 256, 22, 30, 111, 128, 11, 15, 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, 162, 34, 23, 8, 81, 17, 140, 4, 169, 137, 70, 2, 213, 197, 35, 1, 235, 227, 146, 129, 246, 242, 73, 193, 123, 121, 165, 225, 190, 189, 211, 241, 95, 223, 234, 249, 176, 240, 117, 253, 88, 120, 187, 255, 44, 60, 222, 256, 22, 30, 111, 128, 11, 15, 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, 162, 34, 23, 8, 81, 17, 140, 4, 169, 137, 70, 2, 213, 197, 35, 1, 235, 227, 146, 129, 246, 242, 73, 193, 123, 121, 165, 225, 190, 189, 211, 241, 95, 223, 234, 249, 176, 240, 117, 253, 88, 120, 187, 255, 44, 60, 222, 256, 22, 30, 111, 128, 11, 15, 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, 162, 34, 23, 8, 81, 17, 140, 4, 169, 137, 70, 2, 213, 197, 35, 1, 235, 227, 146, 129, 246, 242, 73, 193, 123, 121, 165, 225, 190, 189, 211, 241, 95, 223, 234, 249, 176, 240, 117, 253, 88, 120, 187, 255, 44, 60, 222, 256, 22, 30, 111, 128, 11, 15, 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, 162, 34, 23, 8, 81, 17, 140, 4, 169, 137, 70, 2, 213, 197, 35, 1], -[1, 236, 184, 248, 189, 143, 81, 98, 255, 42, 146, 18, 136, 228, 95, 61, 4, 173, 222, 221, 242, 58, 67, 135, 249, 168, 70, 72, 30, 141, 123, 244, 16, 178, 117, 113, 197, 232, 11, 26, 225, 158, 23, 31, 120, 50, 235, 205, 64, 198, 211, 195, 17, 157, 44, 104, 129, 118, 92, 124, 223, 200, 169, 49, 256, 21, 73, 9, 68, 114, 176, 159, 2, 215, 111, 239, 121, 29, 162, 196, 253, 84, 35, 36, 15, 199, 190, 122, 8, 89, 187, 185, 227, 116, 134, 13, 241, 79, 140, 144, 60, 25, 246, 231, 32, 99, 234, 226, 137, 207, 22, 52, 193, 59, 46, 62, 240, 100, 213, 153, 128, 139, 165, 133, 34, 57, 88, 208, 1, 236, 184, 248, 189, 143, 81, 98, 255, 42, 146, 18, 136, 228, 95, 61, 4, 173, 222, 221, 242, 58, 67, 135, 249, 168, 70, 72, 30, 141, 123, 244, 16, 178, 117, 113, 197, 232, 11, 26, 225, 158, 23, 31, 120, 50, 235, 205, 64, 198, 211, 195, 17, 157, 44, 104, 129, 118, 92, 124, 223, 200, 169, 49, 256, 21, 73, 9, 68, 114, 176, 159, 2, 215, 111, 239, 121, 29, 162, 196, 253, 84, 35, 36, 15, 199, 190, 122, 8, 89, 187, 185, 227, 116, 134, 13, 241, 79, 140, 144, 60, 25, 246, 231, 32, 99, 234, 226, 137, 207, 22, 52, 193, 59, 46, 62, 240, 100, 213, 153, 128, 139, 165, 133, 34, 57, 88, 208, 1], -[1, 237, 143, 224, 146, 164, 61, 65, 242, 43, 168, 238, 123, 110, 113, 53, 225, 126, 50, 28, 211, 149, 104, 233, 223, 166, 21, 94, 176, 78, 239, 103, 253, 80, 199, 132, 187, 115, 13, 254, 60, 85, 99, 76, 22, 74, 62, 45, 128, 10, 57, 145, 184, 175, 98, 96, 136, 107, 173, 138, 67, 202, 72, 102, 16, 194, 232, 243, 23, 54, 205, 12, 17, 174, 118, 210, 169, 218, 9, 77, 2, 217, 29, 191, 35, 71, 122, 130, 227, 86, 79, 219, 246, 220, 226, 106, 193, 252, 100, 56, 165, 41, 208, 209, 189, 75, 42, 188, 95, 156, 221, 206, 249, 160, 141, 7, 117, 230, 26, 251, 120, 170, 198, 152, 44, 148, 124, 90, 256, 20, 114, 33, 111, 93, 196, 192, 15, 214, 89, 19, 134, 147, 144, 204, 32, 131, 207, 229, 46, 108, 153, 24, 34, 91, 236, 163, 81, 179, 18, 154, 4, 177, 58, 125, 70, 142, 244, 3, 197, 172, 158, 181, 235, 183, 195, 212, 129, 247, 200, 112, 73, 82, 159, 161, 121, 150, 84, 119, 190, 55, 185, 155, 241, 63, 25, 14, 234, 203, 52, 245, 240, 83, 139, 47, 88, 39, 248, 180, 255, 40, 228, 66, 222, 186, 135, 127, 30, 171, 178, 38, 11, 37, 31, 151, 64, 5, 157, 201, 92, 216, 49, 48, 68, 182, 215, 69, 162, 101, 36, 51, 8, 97, 116, 250, 140, 27, 231, 6, 137, 87, 59, 105, 213, 109, 133, 167, 1], -[1, 238, 104, 80, 22, 96, 232, 218, 227, 56, 221, 170, 111, 204, 236, 142, 129, 119, 52, 40, 11, 48, 116, 109, 242, 28, 239, 85, 184, 102, 118, 71, 193, 188, 26, 20, 134, 24, 58, 183, 121, 14, 248, 171, 92, 51, 59, 164, 225, 94, 13, 10, 67, 12, 29, 220, 189, 7, 124, 214, 46, 154, 158, 82, 241, 47, 135, 5, 162, 6, 143, 110, 223, 132, 62, 107, 23, 77, 79, 41, 249, 152, 196, 131, 81, 3, 200, 55, 240, 66, 31, 182, 140, 167, 168, 149, 253, 76, 98, 194, 169, 130, 100, 156, 120, 33, 144, 91, 70, 212, 84, 203, 255, 38, 49, 97, 213, 65, 50, 78, 60, 145, 72, 174, 35, 106, 42, 230, 256, 19, 153, 177, 235, 161, 25, 39, 30, 201, 36, 87, 146, 53, 21, 115, 128, 138, 205, 217, 246, 209, 141, 148, 15, 229, 18, 172, 73, 155, 139, 186, 64, 69, 231, 237, 123, 233, 199, 74, 136, 243, 9, 86, 165, 206, 198, 93, 32, 163, 244, 247, 190, 245, 228, 37, 68, 250, 133, 43, 211, 103, 99, 175, 16, 210, 122, 252, 95, 251, 114, 147, 34, 125, 195, 150, 234, 180, 178, 216, 8, 105, 61, 126, 176, 254, 57, 202, 17, 191, 226, 75, 117, 90, 89, 108, 4, 181, 159, 63, 88, 127, 157, 101, 137, 224, 113, 166, 187, 45, 173, 54, 2, 219, 208, 160, 44, 192, 207, 179, 197, 112, 185, 83, 222, 151, 215, 27, 1], -[1, 239, 67, 79, 120, 153, 73, 228, 8, 113, 22, 118, 189, 196, 70, 25, 64, 133, 176, 173, 227, 26, 46, 200, 255, 36, 123, 99, 17, 208, 111, 58, 241, 31, 213, 21, 136, 122, 117, 207, 129, 248, 162, 168, 60, 205, 165, 114, 4, 185, 11, 59, 223, 98, 35, 141, 32, 195, 88, 215, 242, 13, 23, 100, 256, 18, 190, 178, 137, 104, 184, 29, 249, 144, 235, 139, 68, 61, 187, 232, 193, 124, 81, 84, 30, 231, 211, 57, 2, 221, 134, 158, 240, 49, 146, 199, 16, 226, 44, 236, 121, 135, 140, 50, 128, 9, 95, 89, 197, 52, 92, 143, 253, 72, 246, 198, 34, 159, 222, 116, 225, 62, 169, 42, 15, 244, 234, 157, 1, 239, 67, 79, 120, 153, 73, 228, 8, 113, 22, 118, 189, 196, 70, 25, 64, 133, 176, 173, 227, 26, 46, 200, 255, 36, 123, 99, 17, 208, 111, 58, 241, 31, 213, 21, 136, 122, 117, 207, 129, 248, 162, 168, 60, 205, 165, 114, 4, 185, 11, 59, 223, 98, 35, 141, 32, 195, 88, 215, 242, 13, 23, 100, 256, 18, 190, 178, 137, 104, 184, 29, 249, 144, 235, 139, 68, 61, 187, 232, 193, 124, 81, 84, 30, 231, 211, 57, 2, 221, 134, 158, 240, 49, 146, 199, 16, 226, 44, 236, 121, 135, 140, 50, 128, 9, 95, 89, 197, 52, 92, 143, 253, 72, 246, 198, 34, 159, 222, 116, 225, 62, 169, 42, 15, 244, 234, 157, 1], -[1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1], -[1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1], -[1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1], -[1, 243, 196, 83, 123, 77, 207, 186, 223, 219, 18, 5, 187, 209, 158, 101, 128, 7, 159, 87, 67, 90, 25, 164, 17, 19, 248, 126, 35, 24, 178, 78, 193, 125, 49, 85, 95, 212, 116, 175, 120, 119, 133, 194, 111, 245, 168, 218, 32, 66, 104, 86, 81, 151, 199, 41, 197, 69, 62, 160, 73, 6, 173, 148, 241, 224, 205, 214, 88, 53, 29, 108, 30, 94, 226, 177, 92, 254, 42, 183, 8, 145, 26, 150, 213, 102, 114, 203, 242, 210, 144, 40, 211, 130, 236, 37, 253, 56, 244, 182, 22, 206, 200, 27, 136, 152, 185, 237, 23, 192, 139, 110, 2, 229, 135, 166, 246, 154, 157, 115, 189, 181, 36, 10, 117, 161, 59, 202, 256, 14, 61, 174, 134, 180, 50, 71, 34, 38, 239, 252, 70, 48, 99, 156, 129, 250, 98, 170, 190, 167, 232, 93, 240, 238, 9, 131, 222, 233, 79, 179, 64, 132, 208, 172, 162, 45, 141, 82, 137, 138, 124, 63, 146, 12, 89, 39, 225, 191, 153, 171, 176, 106, 58, 216, 60, 188, 195, 97, 184, 251, 84, 109, 16, 33, 52, 43, 169, 204, 228, 149, 227, 163, 31, 80, 165, 3, 215, 74, 249, 112, 231, 107, 44, 155, 143, 54, 15, 47, 113, 217, 46, 127, 21, 220, 4, 201, 13, 75, 235, 51, 57, 230, 121, 105, 72, 20, 234, 65, 118, 147, 255, 28, 122, 91, 11, 103, 100, 142, 68, 76, 221, 247, 140, 96, 198, 55, 1], -[1, 244, 169, 116, 34, 72, 92, 89, 128, 135, 44, 199, 240, 221, 211, 84, 193, 61, 235, 29, 137, 18, 23, 215, 32, 98, 11, 114, 60, 248, 117, 21, 241, 208, 123, 200, 227, 133, 70, 118, 8, 153, 67, 157, 15, 62, 222, 198, 253, 52, 95, 50, 121, 226, 146, 158, 2, 231, 81, 232, 68, 144, 184, 178, 256, 13, 88, 141, 223, 185, 165, 168, 129, 122, 213, 58, 17, 36, 46, 173, 64, 196, 22, 228, 120, 239, 234, 42, 225, 159, 246, 143, 197, 9, 140, 236, 16, 49, 134, 57, 30, 124, 187, 139, 249, 104, 190, 100, 242, 195, 35, 59, 4, 205, 162, 207, 136, 31, 111, 99, 255, 26, 176, 25, 189, 113, 73, 79, 1, 244, 169, 116, 34, 72, 92, 89, 128, 135, 44, 199, 240, 221, 211, 84, 193, 61, 235, 29, 137, 18, 23, 215, 32, 98, 11, 114, 60, 248, 117, 21, 241, 208, 123, 200, 227, 133, 70, 118, 8, 153, 67, 157, 15, 62, 222, 198, 253, 52, 95, 50, 121, 226, 146, 158, 2, 231, 81, 232, 68, 144, 184, 178, 256, 13, 88, 141, 223, 185, 165, 168, 129, 122, 213, 58, 17, 36, 46, 173, 64, 196, 22, 228, 120, 239, 234, 42, 225, 159, 246, 143, 197, 9, 140, 236, 16, 49, 134, 57, 30, 124, 187, 139, 249, 104, 190, 100, 242, 195, 35, 59, 4, 205, 162, 207, 136, 31, 111, 99, 255, 26, 176, 25, 189, 113, 73, 79, 1], -[1, 245, 144, 71, 176, 201, 158, 160, 136, 167, 52, 147, 35, 94, 157, 172, 249, 96, 133, 203, 134, 191, 21, 5, 197, 206, 98, 109, 234, 19, 29, 166, 64, 3, 221, 175, 213, 14, 89, 217, 223, 151, 244, 156, 184, 105, 25, 214, 2, 233, 31, 142, 95, 145, 59, 63, 15, 77, 104, 37, 70, 188, 57, 87, 241, 192, 9, 149, 11, 125, 42, 10, 137, 155, 196, 218, 211, 38, 58, 75, 128, 6, 185, 93, 169, 28, 178, 177, 189, 45, 231, 55, 111, 210, 50, 171, 4, 209, 62, 27, 190, 33, 118, 126, 30, 154, 208, 74, 140, 119, 114, 174, 225, 127, 18, 41, 22, 250, 84, 20, 17, 53, 135, 179, 165, 76, 116, 150, 256, 12, 113, 186, 81, 56, 99, 97, 121, 90, 205, 110, 222, 163, 100, 85, 8, 161, 124, 54, 123, 66, 236, 252, 60, 51, 159, 148, 23, 238, 228, 91, 193, 254, 36, 82, 44, 243, 168, 40, 34, 106, 13, 101, 73, 152, 232, 43, 255, 24, 226, 115, 162, 112, 198, 194, 242, 180, 153, 220, 187, 69, 200, 170, 16, 65, 248, 108, 246, 132, 215, 247, 120, 102, 61, 39, 46, 219, 199, 182, 129, 251, 72, 164, 88, 229, 79, 80, 68, 212, 26, 202, 146, 47, 207, 86, 253, 48, 195, 230, 67, 224, 139, 131, 227, 103, 49, 183, 117, 138, 143, 83, 32, 130, 239, 216, 235, 7, 173, 237, 240, 204, 122, 78, 92, 181, 141, 107, 1], -[1, 246, 121, 211, 249, 88, 60, 111, 64, 67, 34, 140, 2, 235, 242, 165, 241, 176, 120, 222, 128, 134, 68, 23, 4, 213, 227, 73, 225, 95, 240, 187, 256, 11, 136, 46, 8, 169, 197, 146, 193, 190, 223, 117, 255, 22, 15, 92, 16, 81, 137, 35, 129, 123, 189, 234, 253, 44, 30, 184, 32, 162, 17, 70, 1, 246, 121, 211, 249, 88, 60, 111, 64, 67, 34, 140, 2, 235, 242, 165, 241, 176, 120, 222, 128, 134, 68, 23, 4, 213, 227, 73, 225, 95, 240, 187, 256, 11, 136, 46, 8, 169, 197, 146, 193, 190, 223, 117, 255, 22, 15, 92, 16, 81, 137, 35, 129, 123, 189, 234, 253, 44, 30, 184, 32, 162, 17, 70, 1, 246, 121, 211, 249, 88, 60, 111, 64, 67, 34, 140, 2, 235, 242, 165, 241, 176, 120, 222, 128, 134, 68, 23, 4, 213, 227, 73, 225, 95, 240, 187, 256, 11, 136, 46, 8, 169, 197, 146, 193, 190, 223, 117, 255, 22, 15, 92, 16, 81, 137, 35, 129, 123, 189, 234, 253, 44, 30, 184, 32, 162, 17, 70, 1, 246, 121, 211, 249, 88, 60, 111, 64, 67, 34, 140, 2, 235, 242, 165, 241, 176, 120, 222, 128, 134, 68, 23, 4, 213, 227, 73, 225, 95, 240, 187, 256, 11, 136, 46, 8, 169, 197, 146, 193, 190, 223, 117, 255, 22, 15, 92, 16, 81, 137, 35, 129, 123, 189, 234, 253, 44, 30, 184, 32, 162, 17, 70, 1], -[1, 247, 100, 28, 234, 230, 13, 127, 15, 107, 215, 163, 169, 109, 195, 106, 225, 63, 141, 132, 222, 93, 98, 48, 34, 174, 59, 181, 246, 110, 185, 206, 253, 40, 114, 145, 92, 108, 205, 6, 197, 86, 168, 119, 95, 78, 248, 90, 128, 5, 207, 243, 140, 142, 122, 65, 121, 75, 21, 47, 44, 74, 31, 204, 16, 97, 58, 191, 146, 82, 208, 233, 240, 170, 99, 38, 134, 202, 36, 154, 2, 237, 200, 56, 211, 203, 26, 254, 30, 214, 173, 69, 81, 218, 133, 212, 193, 126, 25, 7, 187, 186, 196, 96, 68, 91, 118, 105, 235, 220, 113, 155, 249, 80, 228, 33, 184, 216, 153, 12, 137, 172, 79, 238, 190, 156, 239, 180, 256, 10, 157, 229, 23, 27, 244, 130, 242, 150, 42, 94, 88, 148, 62, 151, 32, 194, 116, 125, 35, 164, 159, 209, 223, 83, 198, 76, 11, 147, 72, 51, 4, 217, 143, 112, 165, 149, 52, 251, 60, 171, 89, 138, 162, 179, 9, 167, 129, 252, 50, 14, 117, 115, 135, 192, 136, 182, 236, 210, 213, 183, 226, 53, 241, 160, 199, 66, 111, 175, 49, 24, 17, 87, 158, 219, 123, 55, 221, 103, 255, 20, 57, 201, 46, 54, 231, 3, 227, 43, 84, 188, 176, 39, 124, 45, 64, 131, 232, 250, 70, 71, 61, 161, 189, 166, 139, 152, 22, 37, 144, 102, 8, 177, 29, 224, 73, 41, 104, 245, 120, 85, 178, 19, 67, 101, 18, 77, 1], -[1, 248, 81, 42, 136, 61, 222, 58, 249, 72, 123, 178, 197, 26, 23, 50, 64, 195, 44, 118, 223, 49, 73, 114, 2, 239, 162, 84, 15, 122, 187, 116, 241, 144, 246, 99, 137, 52, 46, 100, 128, 133, 88, 236, 189, 98, 146, 228, 4, 221, 67, 168, 30, 244, 117, 232, 225, 31, 235, 198, 17, 104, 92, 200, 256, 9, 176, 215, 121, 196, 35, 199, 8, 185, 134, 79, 60, 231, 234, 207, 193, 62, 213, 139, 34, 208, 184, 143, 255, 18, 95, 173, 242, 135, 70, 141, 16, 113, 11, 158, 120, 205, 211, 157, 129, 124, 169, 21, 68, 159, 111, 29, 253, 36, 190, 89, 227, 13, 140, 25, 32, 226, 22, 59, 240, 153, 165, 57, 1, 248, 81, 42, 136, 61, 222, 58, 249, 72, 123, 178, 197, 26, 23, 50, 64, 195, 44, 118, 223, 49, 73, 114, 2, 239, 162, 84, 15, 122, 187, 116, 241, 144, 246, 99, 137, 52, 46, 100, 128, 133, 88, 236, 189, 98, 146, 228, 4, 221, 67, 168, 30, 244, 117, 232, 225, 31, 235, 198, 17, 104, 92, 200, 256, 9, 176, 215, 121, 196, 35, 199, 8, 185, 134, 79, 60, 231, 234, 207, 193, 62, 213, 139, 34, 208, 184, 143, 255, 18, 95, 173, 242, 135, 70, 141, 16, 113, 11, 158, 120, 205, 211, 157, 129, 124, 169, 21, 68, 159, 111, 29, 253, 36, 190, 89, 227, 13, 140, 25, 32, 226, 22, 59, 240, 153, 165, 57, 1], -[1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1], -[1, 250, 49, 171, 88, 155, 200, 142, 34, 19, 124, 160, 165, 130, 118, 202, 128, 132, 104, 43, 213, 51, 157, 186, 240, 119, 195, 177, 46, 192, 198, 156, 193, 191, 205, 107, 22, 103, 50, 164, 137, 69, 31, 40, 234, 161, 158, 179, 32, 33, 26, 75, 246, 77, 232, 175, 60, 94, 113, 237, 140, 48, 178, 39, 241, 112, 244, 91, 134, 90, 141, 41, 227, 210, 72, 10, 187, 233, 168, 109, 8, 201, 135, 83, 190, 212, 58, 108, 15, 152, 221, 252, 35, 12, 173, 74, 253, 28, 61, 87, 162, 151, 228, 203, 121, 181, 18, 131, 111, 251, 42, 220, 2, 243, 98, 85, 176, 53, 143, 27, 68, 38, 248, 63, 73, 3, 236, 147, 256, 7, 208, 86, 169, 102, 57, 115, 223, 238, 133, 97, 92, 127, 139, 55, 129, 125, 153, 214, 44, 206, 100, 71, 17, 138, 62, 80, 211, 65, 59, 101, 64, 66, 52, 150, 235, 154, 207, 93, 120, 188, 226, 217, 23, 96, 99, 78, 225, 224, 231, 182, 11, 180, 25, 82, 197, 163, 144, 20, 117, 209, 79, 218, 16, 145, 13, 166, 123, 167, 116, 216, 30, 47, 185, 247, 70, 24, 89, 148, 249, 56, 122, 174, 67, 45, 199, 149, 242, 105, 36, 5, 222, 245, 84, 183, 4, 229, 196, 170, 95, 106, 29, 54, 136, 76, 239, 126, 146, 6, 215, 37, 255, 14, 159, 172, 81, 204, 114, 230, 189, 219, 9, 194, 184, 254, 21, 110, 1], -[1, 251, 36, 41, 11, 191, 139, 194, 121, 45, 244, 78, 46, 238, 114, 87, 249, 48, 226, 186, 169, 14, 173, 247, 60, 154, 104, 147, 146, 152, 116, 75, 64, 130, 248, 54, 190, 145, 158, 80, 34, 53, 196, 109, 117, 69, 100, 171, 2, 245, 72, 82, 22, 125, 21, 131, 242, 90, 231, 156, 92, 219, 228, 174, 241, 96, 195, 115, 81, 28, 89, 237, 120, 51, 208, 37, 35, 47, 232, 150, 128, 3, 239, 108, 123, 33, 59, 160, 68, 106, 135, 218, 234, 138, 200, 85, 4, 233, 144, 164, 44, 250, 42, 5, 227, 180, 205, 55, 184, 181, 199, 91, 225, 192, 133, 230, 162, 56, 178, 217, 240, 102, 159, 74, 70, 94, 207, 43, 256, 6, 221, 216, 246, 66, 118, 63, 136, 212, 13, 179, 211, 19, 143, 170, 8, 209, 31, 71, 88, 243, 84, 10, 197, 103, 153, 110, 111, 105, 141, 182, 193, 127, 9, 203, 67, 112, 99, 177, 223, 204, 61, 148, 140, 188, 157, 86, 255, 12, 185, 175, 235, 132, 236, 126, 15, 167, 26, 101, 165, 38, 29, 83, 16, 161, 62, 142, 176, 229, 168, 20, 137, 206, 49, 220, 222, 210, 25, 107, 129, 254, 18, 149, 134, 224, 198, 97, 189, 151, 122, 39, 23, 119, 57, 172, 253, 24, 113, 93, 213, 7, 215, 252, 30, 77, 52, 202, 73, 76, 58, 166, 32, 65, 124, 27, 95, 201, 79, 40, 17, 155, 98, 183, 187, 163, 50, 214, 1], -[1, 252, 25, 132, 111, 216, 205, 3, 242, 75, 139, 76, 134, 101, 9, 212, 225, 160, 228, 145, 46, 27, 122, 161, 223, 170, 178, 138, 81, 109, 226, 155, 253, 20, 157, 243, 70, 164, 208, 245, 60, 214, 215, 210, 235, 110, 221, 180, 128, 131, 116, 191, 73, 149, 26, 127, 136, 91, 59, 219, 190, 78, 124, 151, 16, 177, 143, 56, 234, 115, 196, 48, 17, 172, 168, 188, 88, 74, 144, 51, 2, 247, 50, 7, 222, 175, 153, 6, 227, 150, 21, 152, 11, 202, 18, 167, 193, 63, 199, 33, 92, 54, 244, 65, 189, 83, 99, 19, 162, 218, 195, 53, 249, 40, 57, 229, 140, 71, 159, 233, 120, 171, 173, 163, 213, 220, 185, 103, 256, 5, 232, 125, 146, 41, 52, 254, 15, 182, 118, 181, 123, 156, 248, 45, 32, 97, 29, 112, 211, 230, 135, 96, 34, 87, 79, 119, 176, 148, 31, 102, 4, 237, 100, 14, 187, 93, 49, 12, 197, 43, 42, 47, 22, 147, 36, 77, 129, 126, 141, 66, 184, 108, 231, 130, 121, 166, 198, 38, 67, 179, 133, 106, 241, 80, 114, 201, 23, 142, 61, 209, 240, 85, 89, 69, 169, 183, 113, 206, 255, 10, 207, 250, 35, 82, 104, 251, 30, 107, 236, 105, 246, 55, 239, 90, 64, 194, 58, 224, 165, 203, 13, 192, 68, 174, 158, 238, 95, 39, 62, 204, 8, 217, 200, 28, 117, 186, 98, 24, 137, 86, 84, 94, 44, 37, 72, 154, 1], -[1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1], -[1, 254, 9, 230, 81, 14, 215, 126, 136, 106, 196, 183, 222, 105, 199, 174, 249, 24, 185, 216, 123, 145, 79, 20, 197, 180, 231, 78, 23, 188, 207, 150, 64, 65, 62, 71, 44, 125, 139, 97, 223, 102, 208, 147, 73, 38, 143, 85, 2, 251, 18, 203, 162, 28, 173, 252, 15, 212, 135, 109, 187, 210, 141, 91, 241, 48, 113, 175, 246, 33, 158, 40, 137, 103, 205, 156, 46, 119, 157, 43, 128, 130, 124, 142, 88, 250, 21, 194, 189, 204, 159, 37, 146, 76, 29, 170, 4, 245, 36, 149, 67, 56, 89, 247, 30, 167, 13, 218, 117, 163, 25, 182, 225, 96, 226, 93, 235, 66, 59, 80, 17, 206, 153, 55, 92, 238, 57, 86, 256, 3, 248, 27, 176, 243, 42, 131, 121, 151, 61, 74, 35, 152, 58, 83, 8, 233, 72, 41, 134, 112, 178, 237, 60, 77, 26, 179, 234, 69, 50, 107, 193, 192, 195, 186, 213, 132, 118, 160, 34, 155, 49, 110, 184, 219, 114, 172, 255, 6, 239, 54, 95, 229, 84, 5, 242, 45, 122, 148, 70, 47, 116, 166, 16, 209, 144, 82, 11, 224, 99, 217, 120, 154, 52, 101, 211, 138, 100, 214, 129, 127, 133, 115, 169, 7, 236, 63, 68, 53, 98, 220, 111, 181, 228, 87, 253, 12, 221, 108, 190, 201, 168, 10, 227, 90, 244, 39, 140, 94, 232, 75, 32, 161, 31, 164, 22, 191, 198, 177, 240, 51, 104, 202, 165, 19, 200, 171, 1], -[1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1], -[1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, + ], + [ + 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, + 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, + 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, + 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, + 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, + 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, + 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, + 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, + 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, + 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, + 8, 16, 32, 64, 128, 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, + 256, 255, 253, 249, 241, 225, 193, 129, 1, 2, 4, 8, 16, 32, 64, 128, 256, 255, 253, 249, + 241, 225, 193, 129, 1, + ], + [ + 1, 3, 9, 27, 81, 243, 215, 131, 136, 151, 196, 74, 222, 152, 199, 83, 249, 233, 185, 41, + 123, 112, 79, 237, 197, 77, 231, 179, 23, 69, 207, 107, 64, 192, 62, 186, 44, 132, 139, 160, + 223, 155, 208, 110, 73, 219, 143, 172, 2, 6, 18, 54, 162, 229, 173, 5, 15, 45, 135, 148, + 187, 47, 141, 166, 241, 209, 113, 82, 246, 224, 158, 217, 137, 154, 205, 101, 46, 138, 157, + 214, 128, 127, 124, 115, 88, 7, 21, 63, 189, 53, 159, 220, 146, 181, 29, 87, 4, 12, 36, 108, + 67, 201, 89, 10, 30, 90, 13, 39, 117, 94, 25, 75, 225, 161, 226, 164, 235, 191, 59, 177, 17, + 51, 153, 202, 92, 19, 57, 171, 256, 254, 248, 230, 176, 14, 42, 126, 121, 106, 61, 183, 35, + 105, 58, 174, 8, 24, 72, 216, 134, 145, 178, 20, 60, 180, 26, 78, 234, 188, 50, 150, 193, + 65, 195, 71, 213, 125, 118, 97, 34, 102, 49, 147, 184, 38, 114, 85, 255, 251, 239, 203, 95, + 28, 84, 252, 242, 212, 122, 109, 70, 210, 116, 91, 16, 48, 144, 175, 11, 33, 99, 40, 120, + 103, 52, 156, 211, 119, 100, 43, 129, 130, 133, 142, 169, 250, 236, 194, 68, 204, 98, 37, + 111, 76, 228, 170, 253, 245, 221, 149, 190, 56, 168, 247, 227, 167, 244, 218, 140, 163, 232, + 182, 32, 96, 31, 93, 22, 66, 198, 80, 240, 206, 104, 55, 165, 238, 200, 86, 1, + ], + [ + 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, + 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, + 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, + 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, + 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, + 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, + 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, + 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, + 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, + 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, + 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, + 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, 4, 16, 64, 256, 253, 241, 193, 1, + ], + [ + 1, 5, 25, 125, 111, 41, 205, 254, 242, 182, 139, 181, 134, 156, 9, 45, 225, 97, 228, 112, + 46, 230, 122, 96, 223, 87, 178, 119, 81, 148, 226, 102, 253, 237, 157, 14, 70, 93, 208, 12, + 60, 43, 215, 47, 235, 147, 221, 77, 128, 126, 116, 66, 73, 108, 26, 130, 136, 166, 59, 38, + 190, 179, 124, 106, 16, 80, 143, 201, 234, 142, 196, 209, 17, 85, 168, 69, 88, 183, 144, + 206, 2, 10, 50, 250, 222, 82, 153, 251, 227, 107, 21, 105, 11, 55, 18, 90, 193, 194, 199, + 224, 92, 203, 244, 192, 189, 174, 99, 238, 162, 39, 195, 204, 249, 217, 57, 28, 140, 186, + 159, 24, 120, 86, 173, 94, 213, 37, 185, 154, 256, 252, 232, 132, 146, 216, 52, 3, 15, 75, + 118, 76, 123, 101, 248, 212, 32, 160, 29, 145, 211, 27, 135, 161, 34, 170, 79, 138, 176, + 109, 31, 155, 4, 20, 100, 243, 187, 164, 49, 245, 197, 214, 42, 210, 22, 110, 36, 180, 129, + 131, 141, 191, 184, 149, 231, 127, 121, 91, 198, 219, 67, 78, 133, 151, 241, 177, 114, 56, + 23, 115, 61, 48, 240, 172, 89, 188, 169, 74, 113, 51, 255, 247, 207, 7, 35, 175, 104, 6, 30, + 150, 236, 152, 246, 202, 239, 167, 64, 63, 58, 33, 165, 54, 13, 65, 68, 83, 158, 19, 95, + 218, 62, 53, 8, 40, 200, 229, 117, 71, 98, 233, 137, 171, 84, 163, 44, 220, 72, 103, 1, + ], + [ + 1, 6, 36, 216, 11, 66, 139, 63, 121, 212, 244, 179, 46, 19, 114, 170, 249, 209, 226, 71, + 169, 243, 173, 10, 60, 103, 104, 110, 146, 105, 116, 182, 64, 127, 248, 203, 190, 112, 158, + 177, 34, 204, 196, 148, 117, 188, 100, 86, 2, 12, 72, 175, 22, 132, 21, 126, 242, 167, 231, + 101, 92, 38, 228, 83, 241, 161, 195, 142, 81, 229, 89, 20, 120, 206, 208, 220, 35, 210, 232, + 107, 128, 254, 239, 149, 123, 224, 59, 97, 68, 151, 135, 39, 234, 119, 200, 172, 4, 24, 144, + 93, 44, 7, 42, 252, 227, 77, 205, 202, 184, 76, 199, 166, 225, 65, 133, 27, 162, 201, 178, + 40, 240, 155, 159, 183, 70, 163, 207, 214, 256, 251, 221, 41, 246, 191, 118, 194, 136, 45, + 13, 78, 211, 238, 143, 87, 8, 48, 31, 186, 88, 14, 84, 247, 197, 154, 153, 147, 111, 152, + 141, 75, 193, 130, 9, 54, 67, 145, 99, 80, 223, 53, 61, 109, 140, 69, 157, 171, 255, 245, + 185, 82, 235, 125, 236, 131, 15, 90, 26, 156, 165, 219, 29, 174, 16, 96, 62, 115, 176, 28, + 168, 237, 137, 51, 49, 37, 222, 47, 25, 150, 129, 3, 18, 108, 134, 33, 198, 160, 189, 106, + 122, 218, 23, 138, 57, 85, 253, 233, 113, 164, 213, 250, 215, 5, 30, 180, 52, 55, 73, 181, + 58, 91, 32, 192, 124, 230, 95, 56, 79, 217, 17, 102, 98, 74, 187, 94, 50, 43, 1, + ], + [ + 1, 7, 49, 86, 88, 102, 200, 115, 34, 238, 124, 97, 165, 127, 118, 55, 128, 125, 104, 214, + 213, 206, 157, 71, 240, 138, 195, 80, 46, 65, 198, 101, 193, 66, 205, 150, 22, 154, 50, 93, + 137, 188, 31, 217, 234, 96, 158, 78, 32, 224, 26, 182, 246, 180, 232, 82, 60, 163, 113, 20, + 140, 209, 178, 218, 241, 145, 244, 166, 134, 167, 141, 216, 227, 47, 72, 247, 187, 24, 168, + 148, 8, 56, 135, 174, 190, 45, 58, 149, 15, 105, 221, 5, 35, 245, 173, 183, 253, 229, 61, + 170, 162, 106, 228, 54, 121, 76, 18, 126, 111, 6, 42, 37, 2, 14, 98, 172, 176, 204, 143, + 230, 68, 219, 248, 194, 73, 254, 236, 110, 256, 250, 208, 171, 169, 155, 57, 142, 223, 19, + 133, 160, 92, 130, 139, 202, 129, 132, 153, 43, 44, 51, 100, 186, 17, 119, 62, 177, 211, + 192, 59, 156, 64, 191, 52, 107, 235, 103, 207, 164, 120, 69, 226, 40, 23, 161, 99, 179, 225, + 33, 231, 75, 11, 77, 25, 175, 197, 94, 144, 237, 117, 48, 79, 39, 16, 112, 13, 91, 123, 90, + 116, 41, 30, 210, 185, 10, 70, 233, 89, 109, 249, 201, 122, 83, 67, 212, 199, 108, 242, 152, + 36, 252, 222, 12, 84, 74, 4, 28, 196, 87, 95, 151, 29, 203, 136, 181, 239, 131, 146, 251, + 215, 220, 255, 243, 159, 85, 81, 53, 114, 27, 189, 38, 9, 63, 184, 3, 21, 147, 1, + ], + [ + 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, + 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, + 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, + 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, + 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, + 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, + 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, + 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, + 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, + 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, + 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, + 32, 256, 249, 193, 2, 16, 128, 253, 225, 1, 8, 64, 255, 241, 129, 4, 32, 256, 249, 193, 2, + 16, 128, 253, 225, 1, + ], + [ + 1, 9, 81, 215, 136, 196, 222, 199, 249, 185, 123, 79, 197, 231, 23, 207, 64, 62, 44, 139, + 223, 208, 73, 143, 2, 18, 162, 173, 15, 135, 187, 141, 241, 113, 246, 158, 137, 205, 46, + 157, 128, 124, 88, 21, 189, 159, 146, 29, 4, 36, 67, 89, 30, 13, 117, 25, 225, 226, 235, 59, + 17, 153, 92, 57, 256, 248, 176, 42, 121, 61, 35, 58, 8, 72, 134, 178, 60, 26, 234, 50, 193, + 195, 213, 118, 34, 49, 184, 114, 255, 239, 95, 84, 242, 122, 70, 116, 16, 144, 11, 99, 120, + 52, 211, 100, 129, 133, 169, 236, 68, 98, 111, 228, 253, 221, 190, 168, 227, 244, 140, 232, + 32, 31, 22, 198, 240, 104, 165, 200, 1, 9, 81, 215, 136, 196, 222, 199, 249, 185, 123, 79, + 197, 231, 23, 207, 64, 62, 44, 139, 223, 208, 73, 143, 2, 18, 162, 173, 15, 135, 187, 141, + 241, 113, 246, 158, 137, 205, 46, 157, 128, 124, 88, 21, 189, 159, 146, 29, 4, 36, 67, 89, + 30, 13, 117, 25, 225, 226, 235, 59, 17, 153, 92, 57, 256, 248, 176, 42, 121, 61, 35, 58, 8, + 72, 134, 178, 60, 26, 234, 50, 193, 195, 213, 118, 34, 49, 184, 114, 255, 239, 95, 84, 242, + 122, 70, 116, 16, 144, 11, 99, 120, 52, 211, 100, 129, 133, 169, 236, 68, 98, 111, 228, 253, + 221, 190, 168, 227, 244, 140, 232, 32, 31, 22, 198, 240, 104, 165, 200, 1, + ], + [ + 1, 10, 100, 229, 234, 27, 13, 130, 15, 150, 215, 94, 169, 148, 195, 151, 225, 194, 141, 125, + 222, 164, 98, 209, 34, 83, 59, 76, 246, 147, 185, 51, 253, 217, 114, 112, 92, 149, 205, 251, + 197, 171, 168, 138, 95, 179, 248, 167, 128, 252, 207, 14, 140, 115, 122, 192, 121, 182, 21, + 210, 44, 183, 31, 53, 16, 160, 58, 66, 146, 175, 208, 24, 240, 87, 99, 219, 134, 55, 36, + 103, 2, 20, 200, 201, 211, 54, 26, 3, 30, 43, 173, 188, 81, 39, 133, 45, 193, 131, 25, 250, + 187, 71, 196, 161, 68, 166, 118, 152, 235, 37, 113, 102, 249, 177, 228, 224, 184, 41, 153, + 245, 137, 85, 79, 19, 190, 101, 239, 77, 256, 247, 157, 28, 23, 230, 244, 127, 242, 107, 42, + 163, 88, 109, 62, 106, 32, 63, 116, 132, 35, 93, 159, 48, 223, 174, 198, 181, 11, 110, 72, + 206, 4, 40, 143, 145, 165, 108, 52, 6, 60, 86, 89, 119, 162, 78, 9, 90, 129, 5, 50, 243, + 117, 142, 135, 65, 136, 75, 236, 47, 213, 74, 226, 204, 241, 97, 199, 191, 111, 82, 49, 233, + 17, 170, 158, 38, 123, 202, 221, 154, 255, 237, 57, 56, 46, 203, 231, 254, 227, 214, 84, 69, + 176, 218, 124, 212, 64, 126, 232, 7, 70, 186, 61, 96, 189, 91, 139, 105, 22, 220, 144, 155, + 8, 80, 29, 33, 73, 216, 104, 12, 120, 172, 178, 238, 67, 156, 18, 180, 1, + ], + [ + 1, 11, 121, 46, 249, 169, 60, 146, 64, 190, 34, 117, 2, 22, 242, 92, 241, 81, 120, 35, 128, + 123, 68, 234, 4, 44, 227, 184, 225, 162, 240, 70, 256, 246, 136, 211, 8, 88, 197, 111, 193, + 67, 223, 140, 255, 235, 15, 165, 16, 176, 137, 222, 129, 134, 189, 23, 253, 213, 30, 73, 32, + 95, 17, 187, 1, 11, 121, 46, 249, 169, 60, 146, 64, 190, 34, 117, 2, 22, 242, 92, 241, 81, + 120, 35, 128, 123, 68, 234, 4, 44, 227, 184, 225, 162, 240, 70, 256, 246, 136, 211, 8, 88, + 197, 111, 193, 67, 223, 140, 255, 235, 15, 165, 16, 176, 137, 222, 129, 134, 189, 23, 253, + 213, 30, 73, 32, 95, 17, 187, 1, 11, 121, 46, 249, 169, 60, 146, 64, 190, 34, 117, 2, 22, + 242, 92, 241, 81, 120, 35, 128, 123, 68, 234, 4, 44, 227, 184, 225, 162, 240, 70, 256, 246, + 136, 211, 8, 88, 197, 111, 193, 67, 223, 140, 255, 235, 15, 165, 16, 176, 137, 222, 129, + 134, 189, 23, 253, 213, 30, 73, 32, 95, 17, 187, 1, 11, 121, 46, 249, 169, 60, 146, 64, 190, + 34, 117, 2, 22, 242, 92, 241, 81, 120, 35, 128, 123, 68, 234, 4, 44, 227, 184, 225, 162, + 240, 70, 256, 246, 136, 211, 8, 88, 197, 111, 193, 67, 223, 140, 255, 235, 15, 165, 16, 176, + 137, 222, 129, 134, 189, 23, 253, 213, 30, 73, 32, 95, 17, 187, 1, + ], + [ + 1, 12, 144, 186, 176, 56, 158, 97, 136, 90, 52, 110, 35, 163, 157, 85, 249, 161, 133, 54, + 134, 66, 21, 252, 197, 51, 98, 148, 234, 238, 29, 91, 64, 254, 221, 82, 213, 243, 89, 40, + 223, 106, 244, 101, 184, 152, 25, 43, 2, 24, 31, 115, 95, 112, 59, 194, 15, 180, 104, 220, + 70, 69, 57, 170, 241, 65, 9, 108, 11, 132, 42, 247, 137, 102, 196, 39, 211, 219, 58, 182, + 128, 251, 185, 164, 169, 229, 178, 80, 189, 212, 231, 202, 111, 47, 50, 86, 4, 48, 62, 230, + 190, 224, 118, 131, 30, 103, 208, 183, 140, 138, 114, 83, 225, 130, 18, 216, 22, 7, 84, 237, + 17, 204, 135, 78, 165, 181, 116, 107, 256, 245, 113, 71, 81, 201, 99, 160, 121, 167, 205, + 147, 222, 94, 100, 172, 8, 96, 124, 203, 123, 191, 236, 5, 60, 206, 159, 109, 23, 19, 228, + 166, 193, 3, 36, 175, 44, 14, 168, 217, 34, 151, 13, 156, 73, 105, 232, 214, 255, 233, 226, + 142, 162, 145, 198, 63, 242, 77, 153, 37, 187, 188, 200, 87, 16, 192, 248, 149, 246, 125, + 215, 10, 120, 155, 61, 218, 46, 38, 199, 75, 129, 6, 72, 93, 88, 28, 79, 177, 68, 45, 26, + 55, 146, 210, 207, 171, 253, 209, 195, 27, 67, 33, 139, 126, 227, 154, 49, 74, 117, 119, + 143, 174, 32, 127, 239, 41, 235, 250, 173, 20, 240, 53, 122, 179, 92, 76, 141, 150, 1, + ], + [ + 1, 13, 169, 141, 34, 185, 92, 168, 128, 122, 44, 58, 240, 36, 211, 173, 193, 196, 235, 228, + 137, 239, 23, 42, 32, 159, 11, 143, 60, 9, 117, 236, 241, 49, 123, 57, 227, 124, 70, 139, 8, + 104, 67, 100, 15, 195, 222, 59, 253, 205, 95, 207, 121, 31, 146, 99, 2, 26, 81, 25, 68, 113, + 184, 79, 256, 244, 88, 116, 223, 72, 165, 89, 129, 135, 213, 199, 17, 221, 46, 84, 64, 61, + 22, 29, 120, 18, 234, 215, 225, 98, 246, 114, 197, 248, 140, 21, 16, 208, 134, 200, 30, 133, + 187, 118, 249, 153, 190, 157, 242, 62, 35, 198, 4, 52, 162, 50, 136, 226, 111, 158, 255, + 231, 176, 232, 189, 144, 73, 178, 1, 13, 169, 141, 34, 185, 92, 168, 128, 122, 44, 58, 240, + 36, 211, 173, 193, 196, 235, 228, 137, 239, 23, 42, 32, 159, 11, 143, 60, 9, 117, 236, 241, + 49, 123, 57, 227, 124, 70, 139, 8, 104, 67, 100, 15, 195, 222, 59, 253, 205, 95, 207, 121, + 31, 146, 99, 2, 26, 81, 25, 68, 113, 184, 79, 256, 244, 88, 116, 223, 72, 165, 89, 129, 135, + 213, 199, 17, 221, 46, 84, 64, 61, 22, 29, 120, 18, 234, 215, 225, 98, 246, 114, 197, 248, + 140, 21, 16, 208, 134, 200, 30, 133, 187, 118, 249, 153, 190, 157, 242, 62, 35, 198, 4, 52, + 162, 50, 136, 226, 111, 158, 255, 231, 176, 232, 189, 144, 73, 178, 1, + ], + [ + 1, 14, 196, 174, 123, 180, 207, 71, 223, 38, 18, 252, 187, 48, 158, 156, 128, 250, 159, 170, + 67, 167, 25, 93, 17, 238, 248, 131, 35, 233, 178, 179, 193, 132, 49, 172, 95, 45, 116, 82, + 120, 138, 133, 63, 111, 12, 168, 39, 32, 191, 104, 171, 81, 106, 199, 216, 197, 188, 62, 97, + 73, 251, 173, 109, 241, 33, 205, 43, 88, 204, 29, 149, 30, 163, 226, 80, 92, 3, 42, 74, 8, + 112, 26, 107, 213, 155, 114, 54, 242, 47, 144, 217, 211, 127, 236, 220, 253, 201, 244, 75, + 22, 51, 200, 230, 136, 105, 185, 20, 23, 65, 139, 147, 2, 28, 135, 91, 246, 103, 157, 142, + 189, 76, 36, 247, 117, 96, 59, 55, 256, 243, 61, 83, 134, 77, 50, 186, 34, 219, 239, 5, 70, + 209, 99, 101, 129, 7, 98, 87, 190, 90, 232, 164, 240, 19, 9, 126, 222, 24, 79, 78, 64, 125, + 208, 85, 162, 212, 141, 175, 137, 119, 124, 194, 146, 245, 89, 218, 225, 66, 153, 86, 176, + 151, 58, 41, 60, 69, 195, 160, 184, 6, 84, 148, 16, 224, 52, 214, 169, 53, 228, 108, 227, + 94, 31, 177, 165, 254, 215, 183, 249, 145, 231, 150, 44, 102, 143, 203, 15, 210, 113, 40, + 46, 130, 21, 37, 4, 56, 13, 182, 235, 206, 57, 27, 121, 152, 72, 237, 234, 192, 118, 110, + 255, 229, 122, 166, 11, 154, 100, 115, 68, 181, 221, 10, 140, 161, 198, 202, 1, + ], + [ + 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, + 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, + 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, + 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, + 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, + 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, + 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, + 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, + 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, + 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, + 68, 249, 137, 256, 242, 32, 223, 4, 60, 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, 15, + 225, 34, 253, 197, 128, 121, 16, 240, 2, 30, 193, 68, 249, 137, 256, 242, 32, 223, 4, 60, + 129, 136, 241, 17, 255, 227, 64, 189, 8, 120, 1, + ], + [ + 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, + 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, + 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, + 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, + 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, + 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, + 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, + 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, + 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, + 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, + 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, + 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, 16, 256, 241, 1, + ], + [ + 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, + 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, + 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, + 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, + 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, + 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, + 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, + 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, + 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, + 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, + 197, 8, 136, 256, 240, 225, 227, 4, 68, 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, 17, + 32, 30, 253, 189, 129, 137, 16, 15, 255, 223, 193, 197, 8, 136, 256, 240, 225, 227, 4, 68, + 128, 120, 241, 242, 2, 34, 64, 60, 249, 121, 1, + ], + [ + 1, 18, 67, 178, 120, 104, 73, 29, 8, 144, 22, 139, 189, 61, 70, 232, 64, 124, 176, 84, 227, + 231, 46, 57, 255, 221, 123, 158, 17, 49, 111, 199, 241, 226, 213, 236, 136, 135, 117, 50, + 129, 9, 162, 89, 60, 52, 165, 143, 4, 72, 11, 198, 223, 159, 35, 116, 32, 62, 88, 42, 242, + 244, 23, 157, 256, 239, 190, 79, 137, 153, 184, 228, 249, 113, 235, 118, 68, 196, 187, 25, + 193, 133, 81, 173, 30, 26, 211, 200, 2, 36, 134, 99, 240, 208, 146, 58, 16, 31, 44, 21, 121, + 122, 140, 207, 128, 248, 95, 168, 197, 205, 92, 114, 253, 185, 246, 59, 34, 98, 222, 141, + 225, 195, 169, 215, 15, 13, 234, 100, 1, 18, 67, 178, 120, 104, 73, 29, 8, 144, 22, 139, + 189, 61, 70, 232, 64, 124, 176, 84, 227, 231, 46, 57, 255, 221, 123, 158, 17, 49, 111, 199, + 241, 226, 213, 236, 136, 135, 117, 50, 129, 9, 162, 89, 60, 52, 165, 143, 4, 72, 11, 198, + 223, 159, 35, 116, 32, 62, 88, 42, 242, 244, 23, 157, 256, 239, 190, 79, 137, 153, 184, 228, + 249, 113, 235, 118, 68, 196, 187, 25, 193, 133, 81, 173, 30, 26, 211, 200, 2, 36, 134, 99, + 240, 208, 146, 58, 16, 31, 44, 21, 121, 122, 140, 207, 128, 248, 95, 168, 197, 205, 92, 114, + 253, 185, 246, 59, 34, 98, 222, 141, 225, 195, 169, 215, 15, 13, 234, 100, 1, + ], + [ + 1, 19, 104, 177, 22, 161, 232, 39, 227, 201, 221, 87, 111, 53, 236, 115, 129, 138, 52, 217, + 11, 209, 116, 148, 242, 229, 239, 172, 184, 155, 118, 186, 193, 69, 26, 237, 134, 233, 58, + 74, 121, 243, 248, 86, 92, 206, 59, 93, 225, 163, 13, 247, 67, 245, 29, 37, 189, 250, 124, + 43, 46, 103, 158, 175, 241, 210, 135, 252, 162, 251, 143, 147, 223, 125, 62, 150, 23, 180, + 79, 216, 249, 105, 196, 126, 81, 254, 200, 202, 240, 191, 31, 75, 140, 90, 168, 108, 253, + 181, 98, 63, 169, 127, 100, 101, 120, 224, 144, 166, 70, 45, 84, 54, 255, 219, 49, 160, 213, + 192, 50, 179, 60, 112, 72, 83, 35, 151, 42, 27, 256, 238, 153, 80, 235, 96, 25, 218, 30, 56, + 36, 170, 146, 204, 21, 142, 128, 119, 205, 40, 246, 48, 141, 109, 15, 28, 18, 85, 73, 102, + 139, 71, 64, 188, 231, 20, 123, 24, 199, 183, 136, 14, 9, 171, 165, 51, 198, 164, 32, 94, + 244, 10, 190, 12, 228, 220, 68, 7, 133, 214, 211, 154, 99, 82, 16, 47, 122, 5, 95, 6, 114, + 110, 34, 132, 195, 107, 234, 77, 178, 41, 8, 152, 61, 131, 176, 3, 57, 55, 17, 66, 226, 182, + 117, 167, 89, 149, 4, 76, 159, 194, 88, 130, 157, 156, 137, 33, 113, 91, 187, 212, 173, 203, + 2, 38, 208, 97, 44, 65, 207, 78, 197, 145, 185, 174, 222, 106, 215, 230, 1, + ], + [ + 1, 20, 143, 33, 146, 93, 61, 192, 242, 214, 168, 19, 123, 147, 113, 204, 225, 131, 50, 229, + 211, 108, 104, 24, 223, 91, 21, 163, 176, 179, 239, 154, 253, 177, 199, 125, 187, 142, 13, + 3, 60, 172, 99, 181, 22, 183, 62, 212, 128, 247, 57, 112, 184, 82, 98, 161, 136, 150, 173, + 119, 67, 55, 72, 155, 16, 63, 232, 14, 23, 203, 205, 245, 17, 83, 118, 47, 169, 39, 9, 180, + 2, 40, 29, 66, 35, 186, 122, 127, 227, 171, 79, 38, 246, 37, 226, 151, 193, 5, 100, 201, + 165, 216, 208, 48, 189, 182, 42, 69, 95, 101, 221, 51, 249, 97, 141, 250, 117, 27, 26, 6, + 120, 87, 198, 105, 44, 109, 124, 167, 256, 237, 114, 224, 111, 164, 196, 65, 15, 43, 89, + 238, 134, 110, 144, 53, 32, 126, 207, 28, 46, 149, 153, 233, 34, 166, 236, 94, 81, 78, 18, + 103, 4, 80, 58, 132, 70, 115, 244, 254, 197, 85, 158, 76, 235, 74, 195, 45, 129, 10, 200, + 145, 73, 175, 159, 96, 121, 107, 84, 138, 190, 202, 185, 102, 241, 194, 25, 243, 234, 54, + 52, 12, 240, 174, 139, 210, 88, 218, 248, 77, 255, 217, 228, 191, 222, 71, 135, 130, 30, 86, + 178, 219, 11, 220, 31, 106, 64, 252, 157, 56, 92, 41, 49, 209, 68, 75, 215, 188, 162, 156, + 36, 206, 8, 160, 116, 7, 140, 230, 231, 251, 137, 170, 59, 152, 213, 148, 133, 90, 1, + ], + [ + 1, 21, 184, 9, 189, 114, 81, 159, 255, 215, 146, 239, 136, 29, 95, 196, 4, 84, 222, 36, 242, + 199, 67, 122, 249, 89, 70, 185, 30, 116, 123, 13, 16, 79, 117, 144, 197, 25, 11, 231, 225, + 99, 23, 226, 120, 207, 235, 52, 64, 59, 211, 62, 17, 100, 44, 153, 129, 139, 92, 133, 223, + 57, 169, 208, 256, 236, 73, 248, 68, 143, 176, 98, 2, 42, 111, 18, 121, 228, 162, 61, 253, + 173, 35, 221, 15, 58, 190, 135, 8, 168, 187, 72, 227, 141, 134, 244, 241, 178, 140, 113, 60, + 232, 246, 26, 32, 158, 234, 31, 137, 50, 22, 205, 193, 198, 46, 195, 240, 157, 213, 104, + 128, 118, 165, 124, 34, 200, 88, 49, 1, 21, 184, 9, 189, 114, 81, 159, 255, 215, 146, 239, + 136, 29, 95, 196, 4, 84, 222, 36, 242, 199, 67, 122, 249, 89, 70, 185, 30, 116, 123, 13, 16, + 79, 117, 144, 197, 25, 11, 231, 225, 99, 23, 226, 120, 207, 235, 52, 64, 59, 211, 62, 17, + 100, 44, 153, 129, 139, 92, 133, 223, 57, 169, 208, 256, 236, 73, 248, 68, 143, 176, 98, 2, + 42, 111, 18, 121, 228, 162, 61, 253, 173, 35, 221, 15, 58, 190, 135, 8, 168, 187, 72, 227, + 141, 134, 244, 241, 178, 140, 113, 60, 232, 246, 26, 32, 158, 234, 31, 137, 50, 22, 205, + 193, 198, 46, 195, 240, 157, 213, 104, 128, 118, 165, 124, 34, 200, 88, 49, 1, + ], + [ + 1, 22, 227, 111, 129, 11, 242, 184, 193, 134, 121, 92, 225, 67, 189, 46, 241, 162, 223, 23, + 249, 81, 240, 140, 253, 169, 120, 70, 255, 213, 60, 35, 256, 235, 30, 146, 128, 246, 15, 73, + 64, 123, 136, 165, 32, 190, 68, 211, 16, 95, 34, 234, 8, 176, 17, 117, 4, 88, 137, 187, 2, + 44, 197, 222, 1, 22, 227, 111, 129, 11, 242, 184, 193, 134, 121, 92, 225, 67, 189, 46, 241, + 162, 223, 23, 249, 81, 240, 140, 253, 169, 120, 70, 255, 213, 60, 35, 256, 235, 30, 146, + 128, 246, 15, 73, 64, 123, 136, 165, 32, 190, 68, 211, 16, 95, 34, 234, 8, 176, 17, 117, 4, + 88, 137, 187, 2, 44, 197, 222, 1, 22, 227, 111, 129, 11, 242, 184, 193, 134, 121, 92, 225, + 67, 189, 46, 241, 162, 223, 23, 249, 81, 240, 140, 253, 169, 120, 70, 255, 213, 60, 35, 256, + 235, 30, 146, 128, 246, 15, 73, 64, 123, 136, 165, 32, 190, 68, 211, 16, 95, 34, 234, 8, + 176, 17, 117, 4, 88, 137, 187, 2, 44, 197, 222, 1, 22, 227, 111, 129, 11, 242, 184, 193, + 134, 121, 92, 225, 67, 189, 46, 241, 162, 223, 23, 249, 81, 240, 140, 253, 169, 120, 70, + 255, 213, 60, 35, 256, 235, 30, 146, 128, 246, 15, 73, 64, 123, 136, 165, 32, 190, 68, 211, + 16, 95, 34, 234, 8, 176, 17, 117, 4, 88, 137, 187, 2, 44, 197, 222, 1, + ], + [ + 1, 23, 15, 88, 225, 35, 34, 11, 253, 165, 197, 162, 128, 117, 121, 213, 16, 111, 240, 123, + 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, 137, 67, 256, 234, 242, 169, 32, 222, 223, 246, 4, + 92, 60, 95, 129, 140, 136, 44, 241, 146, 17, 134, 255, 211, 227, 81, 64, 187, 189, 235, 8, + 184, 120, 190, 1, 23, 15, 88, 225, 35, 34, 11, 253, 165, 197, 162, 128, 117, 121, 213, 16, + 111, 240, 123, 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, 137, 67, 256, 234, 242, 169, 32, + 222, 223, 246, 4, 92, 60, 95, 129, 140, 136, 44, 241, 146, 17, 134, 255, 211, 227, 81, 64, + 187, 189, 235, 8, 184, 120, 190, 1, 23, 15, 88, 225, 35, 34, 11, 253, 165, 197, 162, 128, + 117, 121, 213, 16, 111, 240, 123, 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, 137, 67, 256, + 234, 242, 169, 32, 222, 223, 246, 4, 92, 60, 95, 129, 140, 136, 44, 241, 146, 17, 134, 255, + 211, 227, 81, 64, 187, 189, 235, 8, 184, 120, 190, 1, 23, 15, 88, 225, 35, 34, 11, 253, 165, + 197, 162, 128, 117, 121, 213, 16, 111, 240, 123, 2, 46, 30, 176, 193, 70, 68, 22, 249, 73, + 137, 67, 256, 234, 242, 169, 32, 222, 223, 246, 4, 92, 60, 95, 129, 140, 136, 44, 241, 146, + 17, 134, 255, 211, 227, 81, 64, 187, 189, 235, 8, 184, 120, 190, 1, + ], + [ + 1, 24, 62, 203, 246, 250, 89, 80, 121, 77, 49, 148, 211, 181, 232, 171, 249, 65, 18, 175, + 88, 56, 59, 131, 60, 155, 122, 101, 111, 94, 200, 174, 64, 251, 113, 142, 67, 66, 42, 237, + 34, 45, 52, 220, 140, 19, 199, 150, 2, 48, 124, 149, 235, 243, 178, 160, 242, 154, 98, 39, + 165, 105, 207, 85, 241, 130, 36, 93, 176, 112, 118, 5, 120, 53, 244, 202, 222, 188, 143, 91, + 128, 245, 226, 27, 134, 132, 84, 217, 68, 90, 104, 183, 23, 38, 141, 43, 4, 96, 248, 41, + 213, 229, 99, 63, 227, 51, 196, 78, 73, 210, 157, 170, 225, 3, 72, 186, 95, 224, 236, 10, + 240, 106, 231, 147, 187, 119, 29, 182, 256, 233, 195, 54, 11, 7, 168, 177, 136, 180, 208, + 109, 46, 76, 25, 86, 8, 192, 239, 82, 169, 201, 198, 126, 197, 102, 135, 156, 146, 163, 57, + 83, 193, 6, 144, 115, 190, 191, 215, 20, 223, 212, 205, 37, 117, 238, 58, 107, 255, 209, + 133, 108, 22, 14, 79, 97, 15, 103, 159, 218, 92, 152, 50, 172, 16, 127, 221, 164, 81, 145, + 139, 252, 137, 204, 13, 55, 35, 69, 114, 166, 129, 12, 31, 230, 123, 125, 173, 40, 189, 167, + 153, 74, 234, 219, 116, 214, 253, 161, 9, 216, 44, 28, 158, 194, 30, 206, 61, 179, 184, 47, + 100, 87, 32, 254, 185, 71, 162, 33, 21, 247, 17, 151, 26, 110, 70, 138, 228, 75, 1, + ], + [ + 1, 25, 111, 205, 242, 139, 134, 9, 225, 228, 46, 122, 223, 178, 81, 226, 253, 157, 70, 208, + 60, 215, 235, 221, 128, 116, 73, 26, 136, 59, 190, 124, 16, 143, 234, 196, 17, 168, 88, 144, + 2, 50, 222, 153, 227, 21, 11, 18, 193, 199, 92, 244, 189, 99, 162, 195, 249, 57, 140, 159, + 120, 173, 213, 185, 256, 232, 146, 52, 15, 118, 123, 248, 32, 29, 211, 135, 34, 79, 176, 31, + 4, 100, 187, 49, 197, 42, 22, 36, 129, 141, 184, 231, 121, 198, 67, 133, 241, 114, 23, 61, + 240, 89, 169, 113, 255, 207, 35, 104, 30, 236, 246, 239, 64, 58, 165, 13, 68, 158, 95, 62, + 8, 200, 117, 98, 137, 84, 44, 72, 1, 25, 111, 205, 242, 139, 134, 9, 225, 228, 46, 122, 223, + 178, 81, 226, 253, 157, 70, 208, 60, 215, 235, 221, 128, 116, 73, 26, 136, 59, 190, 124, 16, + 143, 234, 196, 17, 168, 88, 144, 2, 50, 222, 153, 227, 21, 11, 18, 193, 199, 92, 244, 189, + 99, 162, 195, 249, 57, 140, 159, 120, 173, 213, 185, 256, 232, 146, 52, 15, 118, 123, 248, + 32, 29, 211, 135, 34, 79, 176, 31, 4, 100, 187, 49, 197, 42, 22, 36, 129, 141, 184, 231, + 121, 198, 67, 133, 241, 114, 23, 61, 240, 89, 169, 113, 255, 207, 35, 104, 30, 236, 246, + 239, 64, 58, 165, 13, 68, 158, 95, 62, 8, 200, 117, 98, 137, 84, 44, 72, 1, + ], + [ + 1, 26, 162, 100, 30, 9, 234, 173, 129, 13, 81, 50, 15, 133, 117, 215, 193, 135, 169, 25, + 136, 195, 187, 236, 225, 196, 213, 141, 68, 226, 222, 118, 241, 98, 235, 199, 34, 113, 111, + 59, 249, 49, 246, 228, 17, 185, 184, 158, 253, 153, 123, 114, 137, 221, 92, 79, 255, 205, + 190, 57, 197, 239, 46, 168, 256, 231, 95, 157, 227, 248, 23, 84, 128, 244, 176, 207, 242, + 124, 140, 42, 64, 122, 88, 232, 121, 62, 70, 21, 32, 61, 44, 116, 189, 31, 35, 139, 16, 159, + 22, 58, 223, 144, 146, 198, 8, 208, 11, 29, 240, 72, 73, 99, 4, 104, 134, 143, 120, 36, 165, + 178, 2, 52, 67, 200, 60, 18, 211, 89, 1, 26, 162, 100, 30, 9, 234, 173, 129, 13, 81, 50, 15, + 133, 117, 215, 193, 135, 169, 25, 136, 195, 187, 236, 225, 196, 213, 141, 68, 226, 222, 118, + 241, 98, 235, 199, 34, 113, 111, 59, 249, 49, 246, 228, 17, 185, 184, 158, 253, 153, 123, + 114, 137, 221, 92, 79, 255, 205, 190, 57, 197, 239, 46, 168, 256, 231, 95, 157, 227, 248, + 23, 84, 128, 244, 176, 207, 242, 124, 140, 42, 64, 122, 88, 232, 121, 62, 70, 21, 32, 61, + 44, 116, 189, 31, 35, 139, 16, 159, 22, 58, 223, 144, 146, 198, 8, 208, 11, 29, 240, 72, 73, + 99, 4, 104, 134, 143, 120, 36, 165, 178, 2, 52, 67, 200, 60, 18, 211, 89, 1, + ], + [ + 1, 27, 215, 151, 222, 83, 185, 112, 197, 179, 207, 192, 44, 160, 208, 219, 2, 54, 173, 45, + 187, 166, 113, 224, 137, 101, 157, 127, 88, 63, 159, 181, 4, 108, 89, 90, 117, 75, 226, 191, + 17, 202, 57, 254, 176, 126, 61, 105, 8, 216, 178, 180, 234, 150, 195, 125, 34, 147, 114, + 251, 95, 252, 122, 210, 16, 175, 99, 103, 211, 43, 133, 250, 68, 37, 228, 245, 190, 247, + 244, 163, 32, 93, 198, 206, 165, 86, 9, 243, 136, 74, 199, 233, 123, 237, 231, 69, 64, 186, + 139, 155, 73, 172, 18, 229, 15, 148, 141, 209, 246, 217, 205, 138, 128, 115, 21, 53, 146, + 87, 36, 201, 30, 39, 25, 161, 235, 177, 153, 19, 256, 230, 42, 106, 35, 174, 72, 145, 60, + 78, 50, 65, 213, 97, 49, 38, 255, 203, 84, 212, 70, 91, 144, 33, 120, 156, 100, 130, 169, + 194, 98, 76, 253, 149, 168, 167, 140, 182, 31, 66, 240, 55, 200, 3, 81, 131, 196, 152, 249, + 41, 79, 77, 23, 107, 62, 132, 223, 110, 143, 6, 162, 5, 135, 47, 241, 82, 158, 154, 46, 214, + 124, 7, 189, 220, 29, 12, 67, 10, 13, 94, 225, 164, 59, 51, 92, 171, 248, 14, 121, 183, 58, + 24, 134, 20, 26, 188, 193, 71, 118, 102, 184, 85, 239, 28, 242, 109, 116, 48, 11, 40, 52, + 119, 129, 142, 236, 204, 111, 170, 221, 56, 227, 218, 232, 96, 22, 80, 104, 238, 1, + ], + [ + 1, 28, 13, 107, 169, 106, 141, 93, 34, 181, 185, 40, 92, 6, 168, 78, 128, 243, 122, 75, 44, + 204, 58, 82, 240, 38, 36, 237, 211, 254, 173, 218, 193, 7, 196, 91, 235, 155, 228, 216, 137, + 238, 239, 10, 23, 130, 42, 148, 32, 125, 159, 83, 11, 51, 143, 149, 60, 138, 9, 252, 117, + 192, 236, 183, 241, 66, 49, 87, 123, 103, 57, 54, 227, 188, 124, 131, 70, 161, 139, 37, 8, + 224, 104, 85, 67, 77, 100, 230, 15, 163, 195, 63, 222, 48, 59, 110, 253, 145, 205, 86, 95, + 90, 207, 142, 121, 47, 31, 97, 146, 233, 99, 202, 2, 56, 26, 214, 81, 212, 25, 186, 68, 105, + 113, 80, 184, 12, 79, 156, 256, 229, 244, 150, 88, 151, 116, 164, 223, 76, 72, 217, 165, + 251, 89, 179, 129, 14, 135, 182, 213, 53, 199, 175, 17, 219, 221, 20, 46, 3, 84, 39, 64, + 250, 61, 166, 22, 102, 29, 41, 120, 19, 18, 247, 234, 127, 215, 109, 225, 132, 98, 174, 246, + 206, 114, 108, 197, 119, 248, 5, 140, 65, 21, 74, 16, 191, 208, 170, 134, 154, 200, 203, 30, + 69, 133, 126, 187, 96, 118, 220, 249, 33, 153, 172, 190, 180, 157, 27, 242, 94, 62, 194, 35, + 209, 198, 147, 4, 112, 52, 171, 162, 167, 50, 115, 136, 210, 226, 160, 111, 24, 158, 55, + 255, 201, 231, 43, 176, 45, 232, 71, 189, 152, 144, 177, 73, 245, 178, 101, 1, + ], + [ + 1, 29, 70, 231, 17, 236, 162, 72, 32, 157, 184, 196, 30, 99, 44, 248, 253, 141, 234, 104, + 189, 84, 123, 226, 129, 143, 35, 244, 137, 118, 81, 36, 16, 207, 92, 98, 15, 178, 22, 124, + 255, 199, 117, 52, 223, 42, 190, 113, 193, 200, 146, 122, 197, 59, 169, 18, 8, 232, 46, 49, + 136, 89, 11, 62, 256, 228, 187, 26, 240, 21, 95, 185, 225, 100, 73, 61, 227, 158, 213, 9, 4, + 116, 23, 153, 68, 173, 134, 31, 128, 114, 222, 13, 120, 139, 176, 221, 241, 50, 165, 159, + 242, 79, 235, 133, 2, 58, 140, 205, 34, 215, 67, 144, 64, 57, 111, 135, 60, 198, 88, 239, + 249, 25, 211, 208, 121, 168, 246, 195, 1, 29, 70, 231, 17, 236, 162, 72, 32, 157, 184, 196, + 30, 99, 44, 248, 253, 141, 234, 104, 189, 84, 123, 226, 129, 143, 35, 244, 137, 118, 81, 36, + 16, 207, 92, 98, 15, 178, 22, 124, 255, 199, 117, 52, 223, 42, 190, 113, 193, 200, 146, 122, + 197, 59, 169, 18, 8, 232, 46, 49, 136, 89, 11, 62, 256, 228, 187, 26, 240, 21, 95, 185, 225, + 100, 73, 61, 227, 158, 213, 9, 4, 116, 23, 153, 68, 173, 134, 31, 128, 114, 222, 13, 120, + 139, 176, 221, 241, 50, 165, 159, 242, 79, 235, 133, 2, 58, 140, 205, 34, 215, 67, 144, 64, + 57, 111, 135, 60, 198, 88, 239, 249, 25, 211, 208, 121, 168, 246, 195, 1, + ], + [ + 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, + 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, + 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, + 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, + 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, + 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, + 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, + 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, + 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, + 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, + 17, 253, 137, 255, 197, 256, 227, 128, 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, + 60, 1, 30, 129, 15, 193, 136, 225, 68, 241, 34, 249, 17, 253, 137, 255, 197, 256, 227, 128, + 242, 64, 121, 32, 189, 16, 223, 8, 240, 4, 120, 2, 60, 1, + ], + [ + 1, 31, 190, 236, 120, 122, 184, 50, 8, 248, 235, 89, 189, 205, 187, 143, 64, 185, 81, 198, + 227, 98, 211, 116, 255, 195, 134, 42, 17, 13, 146, 157, 241, 18, 44, 79, 136, 104, 140, 228, + 129, 144, 95, 118, 60, 61, 92, 25, 4, 124, 246, 173, 223, 231, 222, 200, 32, 221, 169, 99, + 242, 49, 234, 58, 256, 226, 67, 21, 137, 135, 73, 207, 249, 9, 22, 168, 68, 52, 70, 114, + 193, 72, 176, 59, 30, 159, 46, 141, 2, 62, 123, 215, 240, 244, 111, 100, 16, 239, 213, 178, + 121, 153, 117, 29, 128, 113, 162, 139, 197, 196, 165, 232, 253, 133, 11, 84, 34, 26, 35, 57, + 225, 36, 88, 158, 15, 208, 23, 199, 1, 31, 190, 236, 120, 122, 184, 50, 8, 248, 235, 89, + 189, 205, 187, 143, 64, 185, 81, 198, 227, 98, 211, 116, 255, 195, 134, 42, 17, 13, 146, + 157, 241, 18, 44, 79, 136, 104, 140, 228, 129, 144, 95, 118, 60, 61, 92, 25, 4, 124, 246, + 173, 223, 231, 222, 200, 32, 221, 169, 99, 242, 49, 234, 58, 256, 226, 67, 21, 137, 135, 73, + 207, 249, 9, 22, 168, 68, 52, 70, 114, 193, 72, 176, 59, 30, 159, 46, 141, 2, 62, 123, 215, + 240, 244, 111, 100, 16, 239, 213, 178, 121, 153, 117, 29, 128, 113, 162, 139, 197, 196, 165, + 232, 253, 133, 11, 84, 34, 26, 35, 57, 225, 36, 88, 158, 15, 208, 23, 199, 1, + ], + [ + 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, + 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, + 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, + 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, + 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, + 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, + 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, + 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, + 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, + 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, + 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, + 256, 225, 4, 128, 241, 2, 64, 249, 1, 32, 253, 129, 16, 255, 193, 8, 256, 225, 4, 128, 241, + 2, 64, 249, 1, + ], + [ + 1, 33, 61, 214, 123, 204, 50, 108, 223, 163, 239, 177, 187, 3, 99, 183, 128, 112, 98, 150, + 67, 155, 232, 203, 17, 47, 9, 40, 35, 127, 79, 37, 193, 201, 208, 182, 95, 51, 141, 27, 120, + 105, 124, 237, 111, 65, 89, 110, 32, 28, 153, 166, 81, 103, 58, 115, 197, 76, 195, 10, 73, + 96, 84, 202, 241, 243, 52, 174, 88, 77, 228, 71, 30, 219, 31, 252, 92, 209, 215, 156, 8, 7, + 231, 170, 213, 90, 143, 93, 242, 19, 113, 131, 211, 24, 21, 179, 253, 125, 13, 172, 22, 212, + 57, 82, 136, 119, 72, 63, 23, 245, 118, 39, 2, 66, 122, 171, 246, 151, 100, 216, 189, 69, + 221, 97, 117, 6, 198, 109, 256, 224, 196, 43, 134, 53, 207, 149, 34, 94, 18, 80, 70, 254, + 158, 74, 129, 145, 159, 107, 190, 102, 25, 54, 240, 210, 248, 217, 222, 130, 178, 220, 64, + 56, 49, 75, 162, 206, 116, 230, 137, 152, 133, 20, 146, 192, 168, 147, 225, 229, 104, 91, + 176, 154, 199, 142, 60, 181, 62, 247, 184, 161, 173, 55, 16, 14, 205, 83, 169, 180, 29, 186, + 227, 38, 226, 5, 165, 48, 42, 101, 249, 250, 26, 87, 44, 167, 114, 164, 15, 238, 144, 126, + 46, 233, 236, 78, 4, 132, 244, 85, 235, 45, 200, 175, 121, 138, 185, 194, 234, 12, 139, 218, + 255, 191, 135, 86, 11, 106, 157, 41, 68, 188, 36, 160, 140, 251, 59, 148, 1, + ], + [ + 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, + 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, + 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, + 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, + 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, + 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, + 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, + 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, + 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, + 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, + 121, 2, 68, 256, 223, 129, 17, 64, 120, 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, 34, + 128, 240, 193, 137, 32, 60, 241, 227, 8, 15, 253, 121, 2, 68, 256, 223, 129, 17, 64, 120, + 225, 197, 16, 30, 249, 242, 4, 136, 255, 189, 1, + ], + [ + 1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, 81, 8, 23, 34, 162, 16, 46, 68, 67, 32, 92, + 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, 256, 222, 60, 44, 255, 187, 120, 88, 253, 117, + 240, 176, 249, 234, 223, 95, 241, 211, 189, 190, 225, 165, 121, 123, 193, 73, 242, 246, 129, + 146, 227, 235, 1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, 81, 8, 23, 34, 162, 16, 46, 68, + 67, 32, 92, 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, 256, 222, 60, 44, 255, 187, 120, + 88, 253, 117, 240, 176, 249, 234, 223, 95, 241, 211, 189, 190, 225, 165, 121, 123, 193, 73, + 242, 246, 129, 146, 227, 235, 1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, 81, 8, 23, 34, + 162, 16, 46, 68, 67, 32, 92, 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, 256, 222, 60, 44, + 255, 187, 120, 88, 253, 117, 240, 176, 249, 234, 223, 95, 241, 211, 189, 190, 225, 165, 121, + 123, 193, 73, 242, 246, 129, 146, 227, 235, 1, 35, 197, 213, 2, 70, 137, 169, 4, 140, 17, + 81, 8, 23, 34, 162, 16, 46, 68, 67, 32, 92, 136, 134, 64, 184, 15, 11, 128, 111, 30, 22, + 256, 222, 60, 44, 255, 187, 120, 88, 253, 117, 240, 176, 249, 234, 223, 95, 241, 211, 189, + 190, 225, 165, 121, 123, 193, 73, 242, 246, 129, 146, 227, 235, 1, + ], + [ + 1, 36, 11, 139, 121, 244, 46, 114, 249, 226, 169, 173, 60, 104, 146, 116, 64, 248, 190, 158, + 34, 196, 117, 100, 2, 72, 22, 21, 242, 231, 92, 228, 241, 195, 81, 89, 120, 208, 35, 232, + 128, 239, 123, 59, 68, 135, 234, 200, 4, 144, 44, 42, 227, 205, 184, 199, 225, 133, 162, + 178, 240, 159, 70, 207, 256, 221, 246, 118, 136, 13, 211, 143, 8, 31, 88, 84, 197, 153, 111, + 141, 193, 9, 67, 99, 223, 61, 140, 157, 255, 185, 235, 236, 15, 26, 165, 29, 16, 62, 176, + 168, 137, 49, 222, 25, 129, 18, 134, 198, 189, 122, 23, 57, 253, 113, 213, 215, 30, 52, 73, + 58, 32, 124, 95, 79, 17, 98, 187, 50, 1, 36, 11, 139, 121, 244, 46, 114, 249, 226, 169, 173, + 60, 104, 146, 116, 64, 248, 190, 158, 34, 196, 117, 100, 2, 72, 22, 21, 242, 231, 92, 228, + 241, 195, 81, 89, 120, 208, 35, 232, 128, 239, 123, 59, 68, 135, 234, 200, 4, 144, 44, 42, + 227, 205, 184, 199, 225, 133, 162, 178, 240, 159, 70, 207, 256, 221, 246, 118, 136, 13, 211, + 143, 8, 31, 88, 84, 197, 153, 111, 141, 193, 9, 67, 99, 223, 61, 140, 157, 255, 185, 235, + 236, 15, 26, 165, 29, 16, 62, 176, 168, 137, 49, 222, 25, 129, 18, 134, 198, 189, 122, 23, + 57, 253, 113, 213, 215, 30, 52, 73, 58, 32, 124, 95, 79, 17, 98, 187, 50, 1, + ], + [ + 1, 37, 84, 24, 117, 217, 62, 238, 68, 203, 58, 90, 246, 107, 104, 250, 255, 183, 89, 209, + 23, 80, 133, 38, 121, 108, 141, 77, 22, 43, 49, 14, 4, 148, 79, 96, 211, 97, 248, 181, 15, + 41, 232, 103, 213, 171, 159, 229, 249, 218, 99, 65, 92, 63, 18, 152, 227, 175, 50, 51, 88, + 172, 196, 56, 16, 78, 59, 127, 73, 131, 221, 210, 60, 164, 157, 155, 81, 170, 122, 145, 225, + 101, 139, 3, 111, 252, 72, 94, 137, 186, 200, 204, 95, 174, 13, 224, 64, 55, 236, 251, 35, + 10, 113, 69, 240, 142, 114, 106, 67, 166, 231, 66, 129, 147, 42, 12, 187, 237, 31, 119, 34, + 230, 29, 45, 123, 182, 52, 125, 256, 220, 173, 233, 140, 40, 195, 19, 189, 54, 199, 167, 11, + 150, 153, 7, 2, 74, 168, 48, 234, 177, 124, 219, 136, 149, 116, 180, 235, 214, 208, 243, + 253, 109, 178, 161, 46, 160, 9, 76, 242, 216, 25, 154, 44, 86, 98, 28, 8, 39, 158, 192, 165, + 194, 239, 105, 30, 82, 207, 206, 169, 85, 61, 201, 241, 179, 198, 130, 184, 126, 36, 47, + 197, 93, 100, 102, 176, 87, 135, 112, 32, 156, 118, 254, 146, 5, 185, 163, 120, 71, 57, 53, + 162, 83, 244, 33, 193, 202, 21, 6, 222, 247, 144, 188, 17, 115, 143, 151, 190, 91, 26, 191, + 128, 110, 215, 245, 70, 20, 226, 138, 223, 27, 228, 212, 134, 75, 205, 132, 1, + ], + [ + 1, 38, 159, 131, 95, 12, 199, 109, 30, 112, 144, 75, 23, 103, 59, 186, 129, 19, 208, 194, + 176, 6, 228, 183, 15, 56, 72, 166, 140, 180, 158, 93, 193, 138, 104, 97, 88, 3, 114, 220, + 136, 28, 36, 83, 70, 90, 79, 175, 225, 69, 52, 177, 44, 130, 57, 110, 68, 14, 18, 170, 35, + 45, 168, 216, 241, 163, 26, 217, 22, 65, 157, 55, 34, 7, 9, 85, 146, 151, 84, 108, 249, 210, + 13, 237, 11, 161, 207, 156, 17, 132, 133, 171, 73, 204, 42, 54, 253, 105, 135, 247, 134, + 209, 232, 78, 137, 66, 195, 214, 165, 102, 21, 27, 255, 181, 196, 252, 67, 233, 116, 39, + 197, 33, 226, 107, 211, 51, 139, 142, 256, 219, 98, 126, 162, 245, 58, 148, 227, 145, 113, + 182, 234, 154, 198, 71, 128, 238, 49, 63, 81, 251, 29, 74, 242, 201, 185, 91, 117, 77, 99, + 164, 64, 119, 153, 160, 169, 254, 143, 37, 121, 229, 221, 174, 187, 167, 178, 82, 32, 188, + 205, 80, 213, 127, 200, 147, 189, 243, 239, 87, 222, 212, 89, 41, 16, 94, 231, 40, 235, 192, + 100, 202, 223, 250, 248, 172, 111, 106, 173, 149, 8, 47, 244, 20, 246, 96, 50, 101, 240, + 125, 124, 86, 184, 53, 215, 203, 4, 152, 122, 10, 123, 48, 25, 179, 120, 191, 62, 43, 92, + 155, 236, 230, 2, 76, 61, 5, 190, 24, 141, 218, 60, 224, 31, 150, 46, 206, 118, 115, 1, + ], + [ + 1, 39, 236, 209, 184, 237, 248, 163, 189, 175, 143, 180, 81, 75, 98, 224, 255, 179, 42, 96, + 146, 40, 18, 188, 136, 164, 228, 154, 95, 107, 61, 66, 4, 156, 173, 65, 222, 177, 221, 138, + 242, 186, 58, 206, 67, 43, 135, 125, 249, 202, 168, 127, 70, 160, 72, 238, 30, 142, 141, + 102, 123, 171, 244, 7, 16, 110, 178, 3, 117, 194, 113, 38, 197, 230, 232, 53, 11, 172, 26, + 243, 225, 37, 158, 251, 23, 126, 31, 181, 120, 54, 50, 151, 235, 170, 205, 28, 64, 183, 198, + 12, 211, 5, 195, 152, 17, 149, 157, 212, 44, 174, 104, 201, 129, 148, 118, 233, 92, 247, + 124, 210, 223, 216, 200, 90, 169, 166, 49, 112, 256, 218, 21, 48, 73, 20, 9, 94, 68, 82, + 114, 77, 176, 182, 159, 33, 2, 78, 215, 161, 111, 217, 239, 69, 121, 93, 29, 103, 162, 150, + 196, 191, 253, 101, 84, 192, 35, 80, 36, 119, 15, 71, 199, 51, 190, 214, 122, 132, 8, 55, + 89, 130, 187, 97, 185, 19, 227, 115, 116, 155, 134, 86, 13, 250, 241, 147, 79, 254, 140, 63, + 144, 219, 60, 27, 25, 204, 246, 85, 231, 14, 32, 220, 99, 6, 234, 131, 226, 76, 137, 203, + 207, 106, 22, 87, 52, 229, 193, 74, 59, 245, 46, 252, 62, 105, 240, 108, 100, 45, 213, 83, + 153, 56, 128, 109, 139, 24, 165, 10, 133, 47, 34, 41, 57, 167, 88, 91, 208, 145, 1, + ], + [ + 1, 40, 58, 7, 23, 149, 49, 161, 15, 86, 99, 105, 88, 179, 221, 102, 225, 5, 200, 33, 35, + 115, 231, 245, 34, 75, 173, 238, 11, 183, 124, 77, 253, 97, 25, 229, 165, 175, 61, 127, 197, + 170, 118, 94, 162, 55, 144, 106, 128, 237, 228, 125, 117, 54, 104, 48, 121, 214, 79, 76, + 213, 39, 18, 206, 16, 126, 157, 112, 111, 71, 13, 6, 240, 91, 42, 138, 123, 37, 195, 90, 2, + 80, 116, 14, 46, 41, 98, 65, 30, 172, 198, 210, 176, 101, 185, 204, 193, 10, 143, 66, 70, + 230, 205, 233, 68, 150, 89, 219, 22, 109, 248, 154, 249, 194, 50, 201, 73, 93, 122, 254, + 137, 83, 236, 188, 67, 110, 31, 212, 256, 217, 199, 250, 234, 108, 208, 96, 242, 171, 158, + 152, 169, 78, 36, 155, 32, 252, 57, 224, 222, 142, 26, 12, 223, 182, 84, 19, 246, 74, 133, + 180, 4, 160, 232, 28, 92, 82, 196, 130, 60, 87, 139, 163, 95, 202, 113, 151, 129, 20, 29, + 132, 140, 203, 153, 209, 136, 43, 178, 181, 44, 218, 239, 51, 241, 131, 100, 145, 146, 186, + 244, 251, 17, 166, 215, 119, 134, 220, 62, 167, 255, 177, 141, 243, 211, 216, 159, 192, 227, + 85, 59, 47, 81, 156, 72, 53, 64, 247, 114, 191, 187, 27, 52, 24, 189, 107, 168, 38, 235, + 148, 9, 103, 8, 63, 207, 56, 184, 164, 135, 3, 120, 174, 21, 69, 190, 147, 226, 45, 1, + ], + [ + 1, 41, 139, 45, 46, 87, 226, 14, 60, 147, 116, 130, 190, 80, 196, 69, 2, 82, 21, 90, 92, + 174, 195, 28, 120, 37, 232, 3, 123, 160, 135, 138, 4, 164, 42, 180, 184, 91, 133, 56, 240, + 74, 207, 6, 246, 63, 13, 19, 8, 71, 84, 103, 111, 182, 9, 112, 223, 148, 157, 12, 235, 126, + 26, 38, 16, 142, 168, 206, 222, 107, 18, 224, 189, 39, 57, 24, 213, 252, 52, 76, 32, 27, 79, + 155, 187, 214, 36, 191, 121, 78, 114, 48, 169, 247, 104, 152, 64, 54, 158, 53, 117, 171, 72, + 125, 242, 156, 228, 96, 81, 237, 208, 47, 128, 108, 59, 106, 234, 85, 144, 250, 227, 55, + 199, 192, 162, 217, 159, 94, 256, 216, 118, 212, 211, 170, 31, 243, 197, 110, 141, 127, 67, + 177, 61, 188, 255, 175, 236, 167, 165, 83, 62, 229, 137, 220, 25, 254, 134, 97, 122, 119, + 253, 93, 215, 77, 73, 166, 124, 201, 17, 183, 50, 251, 11, 194, 244, 238, 249, 186, 173, + 154, 146, 75, 248, 145, 34, 109, 100, 245, 22, 131, 231, 219, 241, 115, 89, 51, 35, 150, + 239, 33, 68, 218, 200, 233, 44, 5, 205, 181, 225, 230, 178, 102, 70, 43, 221, 66, 136, 179, + 143, 209, 88, 10, 153, 105, 193, 203, 99, 204, 140, 86, 185, 132, 15, 101, 29, 161, 176, 20, + 49, 210, 129, 149, 198, 151, 23, 172, 113, 7, 30, 202, 58, 65, 95, 40, 98, 163, 1, + ], + [ + 1, 42, 222, 72, 197, 50, 44, 49, 2, 84, 187, 144, 137, 100, 88, 98, 4, 168, 117, 31, 17, + 200, 176, 196, 8, 79, 234, 62, 34, 143, 95, 135, 16, 158, 211, 124, 68, 29, 190, 13, 32, 59, + 165, 248, 136, 58, 123, 26, 64, 118, 73, 239, 15, 116, 246, 52, 128, 236, 146, 221, 30, 232, + 235, 104, 256, 215, 35, 185, 60, 207, 213, 208, 255, 173, 70, 113, 120, 157, 169, 159, 253, + 89, 140, 226, 240, 57, 81, 61, 249, 178, 23, 195, 223, 114, 162, 122, 241, 99, 46, 133, 189, + 228, 67, 244, 225, 198, 92, 9, 121, 199, 134, 231, 193, 139, 184, 18, 242, 141, 11, 205, + 129, 21, 111, 36, 227, 25, 22, 153, 1, 42, 222, 72, 197, 50, 44, 49, 2, 84, 187, 144, 137, + 100, 88, 98, 4, 168, 117, 31, 17, 200, 176, 196, 8, 79, 234, 62, 34, 143, 95, 135, 16, 158, + 211, 124, 68, 29, 190, 13, 32, 59, 165, 248, 136, 58, 123, 26, 64, 118, 73, 239, 15, 116, + 246, 52, 128, 236, 146, 221, 30, 232, 235, 104, 256, 215, 35, 185, 60, 207, 213, 208, 255, + 173, 70, 113, 120, 157, 169, 159, 253, 89, 140, 226, 240, 57, 81, 61, 249, 178, 23, 195, + 223, 114, 162, 122, 241, 99, 46, 133, 189, 228, 67, 244, 225, 198, 92, 9, 121, 199, 134, + 231, 193, 139, 184, 18, 242, 141, 11, 205, 129, 21, 111, 36, 227, 25, 22, 153, 1, + ], + [ + 1, 43, 50, 94, 187, 74, 98, 102, 17, 217, 79, 56, 95, 230, 124, 192, 32, 91, 58, 181, 73, + 55, 52, 180, 30, 5, 215, 250, 213, 164, 113, 233, 253, 85, 57, 138, 23, 218, 122, 106, 189, + 160, 198, 33, 134, 108, 18, 3, 129, 150, 25, 47, 222, 37, 49, 51, 137, 237, 168, 28, 176, + 115, 62, 96, 16, 174, 29, 219, 165, 156, 26, 90, 15, 131, 236, 125, 235, 82, 185, 245, 255, + 171, 157, 69, 140, 109, 61, 53, 223, 80, 99, 145, 67, 54, 9, 130, 193, 75, 141, 152, 111, + 147, 153, 154, 197, 247, 84, 14, 88, 186, 31, 48, 8, 87, 143, 238, 211, 78, 13, 45, 136, + 194, 118, 191, 246, 41, 221, 251, 256, 214, 207, 163, 70, 183, 159, 155, 240, 40, 178, 201, + 162, 27, 133, 65, 225, 166, 199, 76, 184, 202, 205, 77, 227, 252, 42, 7, 44, 93, 144, 24, 4, + 172, 200, 119, 234, 39, 135, 151, 68, 97, 59, 224, 123, 149, 239, 254, 128, 107, 232, 210, + 35, 220, 208, 206, 120, 20, 89, 229, 81, 142, 195, 161, 241, 83, 228, 38, 92, 101, 231, 167, + 242, 126, 21, 132, 22, 175, 72, 12, 2, 86, 100, 188, 117, 148, 196, 204, 34, 177, 158, 112, + 190, 203, 248, 127, 64, 182, 116, 105, 146, 110, 104, 103, 60, 10, 173, 243, 169, 71, 226, + 209, 249, 170, 114, 19, 46, 179, 244, 212, 121, 63, 139, 66, 11, 216, 36, 6, 1, + ], + [ + 1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, 35, 255, 169, 240, 23, 241, 67, 121, 184, 129, + 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, 146, 256, 213, 120, 140, 249, 162, 189, 92, 193, + 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, 73, 128, 235, 60, 70, 253, 81, 223, 46, 225, + 134, 242, 111, 1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, 35, 255, 169, 240, 23, 241, 67, + 121, 184, 129, 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, 146, 256, 213, 120, 140, 249, + 162, 189, 92, 193, 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, 73, 128, 235, 60, 70, 253, + 81, 223, 46, 225, 134, 242, 111, 1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, 35, 255, 169, + 240, 23, 241, 67, 121, 184, 129, 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, 146, 256, 213, + 120, 140, 249, 162, 189, 92, 193, 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, 73, 128, 235, + 60, 70, 253, 81, 223, 46, 225, 134, 242, 111, 1, 44, 137, 117, 8, 95, 68, 165, 64, 246, 30, + 35, 255, 169, 240, 23, 241, 67, 121, 184, 129, 22, 197, 187, 4, 176, 34, 211, 32, 123, 15, + 146, 256, 213, 120, 140, 249, 162, 189, 92, 193, 11, 227, 222, 2, 88, 17, 234, 16, 190, 136, + 73, 128, 235, 60, 70, 253, 81, 223, 46, 225, 134, 242, 111, 1, + ], + [ + 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, 8, 103, 9, 148, 235, + 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, 64, 53, 72, 156, 81, 47, 59, 85, 227, + 192, 159, 216, 211, 243, 141, 177, 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, + 146, 145, 100, 131, 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, + 20, 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, + 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152, 158, + 171, 242, 96, 208, 108, 234, 250, 199, 217, 256, 212, 31, 110, 67, 188, 236, 83, 137, 254, + 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, + 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, 2, 90, + 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, + 214, 121, 48, 104, 54, 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, + 61, 175, 165, 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, + 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40, 1, + ], + [ + 1, 46, 60, 190, 2, 92, 120, 123, 4, 184, 240, 246, 8, 111, 223, 235, 16, 222, 189, 213, 32, + 187, 121, 169, 64, 117, 242, 81, 128, 234, 227, 162, 256, 211, 197, 67, 255, 165, 137, 134, + 253, 73, 17, 11, 249, 146, 34, 22, 241, 35, 68, 44, 225, 70, 136, 88, 193, 140, 15, 176, + 129, 23, 30, 95, 1, 46, 60, 190, 2, 92, 120, 123, 4, 184, 240, 246, 8, 111, 223, 235, 16, + 222, 189, 213, 32, 187, 121, 169, 64, 117, 242, 81, 128, 234, 227, 162, 256, 211, 197, 67, + 255, 165, 137, 134, 253, 73, 17, 11, 249, 146, 34, 22, 241, 35, 68, 44, 225, 70, 136, 88, + 193, 140, 15, 176, 129, 23, 30, 95, 1, 46, 60, 190, 2, 92, 120, 123, 4, 184, 240, 246, 8, + 111, 223, 235, 16, 222, 189, 213, 32, 187, 121, 169, 64, 117, 242, 81, 128, 234, 227, 162, + 256, 211, 197, 67, 255, 165, 137, 134, 253, 73, 17, 11, 249, 146, 34, 22, 241, 35, 68, 44, + 225, 70, 136, 88, 193, 140, 15, 176, 129, 23, 30, 95, 1, 46, 60, 190, 2, 92, 120, 123, 4, + 184, 240, 246, 8, 111, 223, 235, 16, 222, 189, 213, 32, 187, 121, 169, 64, 117, 242, 81, + 128, 234, 227, 162, 256, 211, 197, 67, 255, 165, 137, 134, 253, 73, 17, 11, 249, 146, 34, + 22, 241, 35, 68, 44, 225, 70, 136, 88, 193, 140, 15, 176, 129, 23, 30, 95, 1, + ], + [ + 1, 47, 153, 252, 22, 6, 25, 147, 227, 132, 36, 150, 111, 77, 21, 216, 129, 152, 205, 126, + 11, 3, 141, 202, 242, 66, 18, 75, 184, 167, 139, 108, 193, 76, 231, 63, 134, 130, 199, 101, + 121, 33, 9, 166, 92, 212, 198, 54, 225, 38, 244, 160, 67, 65, 228, 179, 189, 145, 133, 83, + 46, 106, 99, 27, 241, 19, 122, 80, 162, 161, 114, 218, 223, 201, 195, 170, 23, 53, 178, 142, + 249, 138, 61, 40, 81, 209, 57, 109, 240, 229, 226, 85, 140, 155, 89, 71, 253, 69, 159, 20, + 169, 233, 157, 183, 120, 243, 113, 171, 70, 206, 173, 164, 255, 163, 208, 10, 213, 245, 207, + 220, 60, 250, 185, 214, 35, 103, 215, 82, 256, 210, 104, 5, 235, 251, 232, 110, 30, 125, + 221, 107, 146, 180, 236, 41, 128, 105, 52, 131, 246, 254, 116, 55, 15, 191, 239, 182, 73, + 90, 118, 149, 64, 181, 26, 194, 123, 127, 58, 156, 136, 224, 248, 91, 165, 45, 59, 203, 32, + 219, 13, 97, 190, 192, 29, 78, 68, 112, 124, 174, 211, 151, 158, 230, 16, 238, 135, 177, 95, + 96, 143, 39, 34, 56, 62, 87, 234, 204, 79, 115, 8, 119, 196, 217, 176, 48, 200, 148, 17, 28, + 31, 172, 117, 102, 168, 186, 4, 188, 98, 237, 88, 24, 100, 74, 137, 14, 144, 86, 187, 51, + 84, 93, 2, 94, 49, 247, 44, 12, 50, 37, 197, 7, 72, 43, 222, 154, 42, 175, 1, + ], + [ + 1, 48, 248, 82, 81, 33, 42, 217, 136, 103, 61, 101, 222, 119, 58, 214, 249, 130, 72, 115, + 123, 250, 178, 63, 197, 204, 26, 220, 23, 76, 50, 87, 64, 245, 195, 108, 44, 56, 118, 10, + 223, 167, 49, 39, 73, 163, 114, 75, 2, 96, 239, 164, 162, 66, 84, 177, 15, 206, 122, 202, + 187, 238, 116, 171, 241, 3, 144, 230, 246, 243, 99, 126, 137, 151, 52, 183, 46, 152, 100, + 174, 128, 233, 133, 216, 88, 112, 236, 20, 189, 77, 98, 78, 146, 69, 228, 150, 4, 192, 221, + 71, 67, 132, 168, 97, 30, 155, 244, 147, 117, 219, 232, 85, 225, 6, 31, 203, 235, 229, 198, + 252, 17, 45, 104, 109, 92, 47, 200, 91, 256, 209, 9, 175, 176, 224, 215, 40, 121, 154, 196, + 156, 35, 138, 199, 43, 8, 127, 185, 142, 134, 7, 79, 194, 60, 53, 231, 37, 234, 181, 207, + 170, 193, 12, 62, 149, 213, 201, 139, 247, 34, 90, 208, 218, 184, 94, 143, 182, 255, 161, + 18, 93, 95, 191, 173, 80, 242, 51, 135, 55, 70, 19, 141, 86, 16, 254, 113, 27, 11, 14, 158, + 131, 120, 106, 205, 74, 211, 105, 157, 83, 129, 24, 124, 41, 169, 145, 21, 237, 68, 180, + 159, 179, 111, 188, 29, 107, 253, 65, 36, 186, 190, 125, 89, 160, 227, 102, 13, 110, 140, + 38, 25, 172, 32, 251, 226, 54, 22, 28, 59, 5, 240, 212, 153, 148, 165, 210, 57, 166, 1, + ], + [ + 1, 49, 88, 200, 34, 124, 165, 118, 128, 104, 213, 157, 240, 195, 46, 198, 193, 205, 22, 50, + 137, 31, 234, 158, 32, 26, 246, 232, 60, 113, 140, 178, 241, 244, 134, 141, 227, 72, 187, + 168, 8, 135, 190, 58, 15, 221, 35, 173, 253, 61, 162, 228, 121, 18, 111, 42, 2, 98, 176, + 143, 68, 248, 73, 236, 256, 208, 169, 57, 223, 133, 92, 139, 129, 153, 44, 100, 17, 62, 211, + 59, 64, 52, 235, 207, 120, 226, 23, 99, 225, 231, 11, 25, 197, 144, 117, 79, 16, 13, 123, + 116, 30, 185, 70, 89, 249, 122, 67, 199, 242, 36, 222, 84, 4, 196, 95, 29, 136, 239, 146, + 215, 255, 159, 81, 114, 189, 9, 184, 21, 1, 49, 88, 200, 34, 124, 165, 118, 128, 104, 213, + 157, 240, 195, 46, 198, 193, 205, 22, 50, 137, 31, 234, 158, 32, 26, 246, 232, 60, 113, 140, + 178, 241, 244, 134, 141, 227, 72, 187, 168, 8, 135, 190, 58, 15, 221, 35, 173, 253, 61, 162, + 228, 121, 18, 111, 42, 2, 98, 176, 143, 68, 248, 73, 236, 256, 208, 169, 57, 223, 133, 92, + 139, 129, 153, 44, 100, 17, 62, 211, 59, 64, 52, 235, 207, 120, 226, 23, 99, 225, 231, 11, + 25, 197, 144, 117, 79, 16, 13, 123, 116, 30, 185, 70, 89, 249, 122, 67, 199, 242, 36, 222, + 84, 4, 196, 95, 29, 136, 239, 146, 215, 255, 159, 81, 114, 189, 9, 184, 21, 1, + ], + [ + 1, 50, 187, 98, 17, 79, 95, 124, 32, 58, 73, 52, 30, 215, 213, 113, 253, 57, 23, 122, 189, + 198, 134, 18, 129, 25, 222, 49, 137, 168, 176, 62, 16, 29, 165, 26, 15, 236, 235, 185, 255, + 157, 140, 61, 223, 99, 67, 9, 193, 141, 111, 153, 197, 84, 88, 31, 8, 143, 211, 13, 136, + 118, 246, 221, 256, 207, 70, 159, 240, 178, 162, 133, 225, 199, 184, 205, 227, 42, 44, 144, + 4, 200, 234, 135, 68, 59, 123, 239, 128, 232, 35, 208, 120, 89, 81, 195, 241, 228, 92, 231, + 242, 21, 22, 72, 2, 100, 117, 196, 34, 158, 190, 248, 64, 116, 146, 104, 60, 173, 169, 226, + 249, 114, 46, 244, 121, 139, 11, 36, 1, 50, 187, 98, 17, 79, 95, 124, 32, 58, 73, 52, 30, + 215, 213, 113, 253, 57, 23, 122, 189, 198, 134, 18, 129, 25, 222, 49, 137, 168, 176, 62, 16, + 29, 165, 26, 15, 236, 235, 185, 255, 157, 140, 61, 223, 99, 67, 9, 193, 141, 111, 153, 197, + 84, 88, 31, 8, 143, 211, 13, 136, 118, 246, 221, 256, 207, 70, 159, 240, 178, 162, 133, 225, + 199, 184, 205, 227, 42, 44, 144, 4, 200, 234, 135, 68, 59, 123, 239, 128, 232, 35, 208, 120, + 89, 81, 195, 241, 228, 92, 231, 242, 21, 22, 72, 2, 100, 117, 196, 34, 158, 190, 248, 64, + 116, 146, 104, 60, 173, 169, 226, 249, 114, 46, 244, 121, 139, 11, 36, 1, + ], + [ + 1, 51, 31, 39, 190, 181, 236, 214, 120, 209, 122, 54, 184, 132, 50, 237, 8, 151, 248, 55, + 235, 163, 89, 170, 189, 130, 205, 175, 187, 28, 143, 97, 64, 180, 185, 183, 81, 19, 198, 75, + 227, 12, 98, 115, 211, 224, 116, 5, 255, 155, 195, 179, 134, 152, 42, 86, 17, 96, 13, 149, + 146, 250, 157, 40, 241, 212, 18, 147, 44, 188, 79, 174, 136, 254, 104, 164, 140, 201, 228, + 63, 129, 154, 144, 148, 95, 219, 118, 107, 60, 233, 61, 27, 92, 66, 25, 247, 4, 204, 124, + 156, 246, 210, 173, 85, 223, 65, 231, 216, 222, 14, 200, 177, 32, 90, 221, 220, 169, 138, + 99, 166, 242, 6, 49, 186, 234, 112, 58, 131, 256, 206, 226, 218, 67, 76, 21, 43, 137, 48, + 135, 203, 73, 125, 207, 20, 249, 106, 9, 202, 22, 94, 168, 87, 68, 127, 52, 82, 70, 229, + 114, 160, 193, 77, 72, 74, 176, 238, 59, 182, 30, 245, 159, 142, 46, 33, 141, 252, 2, 102, + 62, 78, 123, 105, 215, 171, 240, 161, 244, 108, 111, 7, 100, 217, 16, 45, 239, 110, 213, 69, + 178, 83, 121, 3, 153, 93, 117, 56, 29, 194, 128, 103, 113, 109, 162, 38, 139, 150, 197, 24, + 196, 230, 165, 191, 232, 10, 253, 53, 133, 101, 11, 47, 84, 172, 34, 192, 26, 41, 35, 243, + 57, 80, 225, 167, 36, 37, 88, 119, 158, 91, 15, 251, 208, 71, 23, 145, 199, 126, 1, + ], + [ + 1, 52, 134, 29, 223, 31, 70, 42, 128, 231, 190, 114, 17, 113, 222, 236, 193, 13, 162, 200, + 120, 72, 146, 139, 32, 122, 176, 157, 197, 221, 184, 59, 241, 196, 169, 50, 30, 18, 165, 99, + 8, 159, 44, 232, 242, 248, 46, 79, 253, 49, 235, 141, 136, 133, 234, 89, 2, 104, 11, 58, + 189, 62, 140, 84, 256, 205, 123, 228, 34, 226, 187, 215, 129, 26, 67, 143, 240, 144, 35, 21, + 64, 244, 95, 57, 137, 185, 111, 118, 225, 135, 81, 100, 60, 36, 73, 198, 16, 61, 88, 207, + 227, 239, 92, 158, 249, 98, 213, 25, 15, 9, 211, 178, 4, 208, 22, 116, 121, 124, 23, 168, + 255, 153, 246, 199, 68, 195, 117, 173, 1, 52, 134, 29, 223, 31, 70, 42, 128, 231, 190, 114, + 17, 113, 222, 236, 193, 13, 162, 200, 120, 72, 146, 139, 32, 122, 176, 157, 197, 221, 184, + 59, 241, 196, 169, 50, 30, 18, 165, 99, 8, 159, 44, 232, 242, 248, 46, 79, 253, 49, 235, + 141, 136, 133, 234, 89, 2, 104, 11, 58, 189, 62, 140, 84, 256, 205, 123, 228, 34, 226, 187, + 215, 129, 26, 67, 143, 240, 144, 35, 21, 64, 244, 95, 57, 137, 185, 111, 118, 225, 135, 81, + 100, 60, 36, 73, 198, 16, 61, 88, 207, 227, 239, 92, 158, 249, 98, 213, 25, 15, 9, 211, 178, + 4, 208, 22, 116, 121, 124, 23, 168, 255, 153, 246, 199, 68, 195, 117, 173, 1, + ], + [ + 1, 53, 239, 74, 67, 210, 79, 75, 120, 192, 153, 142, 73, 14, 228, 5, 8, 167, 113, 78, 22, + 138, 118, 86, 189, 251, 196, 108, 70, 112, 25, 40, 64, 51, 133, 110, 176, 76, 173, 174, 227, + 209, 26, 93, 46, 125, 200, 63, 255, 151, 36, 109, 123, 94, 99, 107, 17, 130, 208, 230, 111, + 229, 58, 247, 241, 180, 31, 101, 213, 238, 21, 85, 136, 12, 122, 41, 117, 33, 207, 177, 129, + 155, 248, 37, 162, 105, 168, 166, 60, 96, 205, 71, 165, 7, 114, 131, 4, 212, 185, 39, 11, + 69, 59, 43, 223, 254, 98, 54, 35, 56, 141, 20, 32, 154, 195, 55, 88, 38, 215, 87, 242, 233, + 13, 175, 23, 191, 100, 160, 256, 204, 18, 183, 190, 47, 178, 182, 137, 65, 104, 115, 184, + 243, 29, 252, 249, 90, 144, 179, 235, 119, 139, 171, 68, 6, 61, 149, 187, 145, 232, 217, + 193, 206, 124, 147, 81, 181, 84, 83, 30, 48, 231, 164, 211, 132, 57, 194, 2, 106, 221, 148, + 134, 163, 158, 150, 240, 127, 49, 27, 146, 28, 199, 10, 16, 77, 226, 156, 44, 19, 236, 172, + 121, 245, 135, 216, 140, 224, 50, 80, 128, 102, 9, 220, 95, 152, 89, 91, 197, 161, 52, 186, + 92, 250, 143, 126, 253, 45, 72, 218, 246, 188, 198, 214, 34, 3, 159, 203, 222, 201, 116, + 237, 225, 103, 62, 202, 169, 219, 42, 170, 15, 24, 244, 82, 234, 66, 157, 97, 1, + ], + [ + 1, 54, 89, 180, 211, 86, 18, 201, 60, 156, 200, 6, 67, 20, 52, 238, 2, 108, 178, 103, 165, + 172, 36, 145, 120, 55, 143, 12, 134, 40, 104, 219, 4, 216, 99, 206, 73, 87, 72, 33, 240, + 110, 29, 24, 11, 80, 208, 181, 8, 175, 198, 155, 146, 174, 144, 66, 223, 220, 58, 48, 22, + 160, 159, 105, 16, 93, 139, 53, 35, 91, 31, 132, 189, 183, 116, 96, 44, 63, 61, 210, 32, + 186, 21, 106, 70, 182, 62, 7, 121, 109, 232, 192, 88, 126, 122, 163, 64, 115, 42, 212, 140, + 107, 124, 14, 242, 218, 207, 127, 176, 252, 244, 69, 128, 230, 84, 167, 23, 214, 248, 28, + 227, 179, 157, 254, 95, 247, 231, 138, 256, 203, 168, 77, 46, 171, 239, 56, 197, 101, 57, + 251, 190, 237, 205, 19, 255, 149, 79, 154, 92, 85, 221, 112, 137, 202, 114, 245, 123, 217, + 153, 38, 253, 41, 158, 51, 184, 170, 185, 224, 17, 147, 228, 233, 246, 177, 49, 76, 249, 82, + 59, 102, 111, 83, 113, 191, 34, 37, 199, 209, 235, 97, 98, 152, 241, 164, 118, 204, 222, + 166, 226, 125, 68, 74, 141, 161, 213, 194, 196, 47, 225, 71, 236, 151, 187, 75, 195, 250, + 136, 148, 25, 65, 169, 131, 135, 94, 193, 142, 215, 45, 117, 150, 133, 243, 15, 39, 50, 130, + 81, 5, 13, 188, 129, 27, 173, 90, 234, 43, 9, 229, 30, 78, 100, 3, 162, 10, 26, 119, 1, + ], + [ + 1, 55, 198, 96, 140, 247, 221, 76, 68, 142, 100, 103, 11, 91, 122, 28, 255, 147, 118, 65, + 234, 20, 72, 105, 121, 230, 57, 51, 235, 75, 13, 201, 4, 220, 21, 127, 46, 217, 113, 47, 15, + 54, 143, 155, 44, 107, 231, 112, 249, 74, 215, 3, 165, 80, 31, 163, 227, 149, 228, 204, 169, + 43, 52, 33, 16, 109, 84, 251, 184, 97, 195, 188, 60, 216, 58, 106, 176, 171, 153, 191, 225, + 39, 89, 12, 146, 63, 124, 138, 137, 82, 141, 45, 162, 172, 208, 132, 64, 179, 79, 233, 222, + 131, 9, 238, 240, 93, 232, 167, 190, 170, 98, 250, 129, 156, 99, 48, 70, 252, 239, 38, 34, + 71, 50, 180, 134, 174, 61, 14, 256, 202, 59, 161, 117, 10, 36, 181, 189, 115, 157, 154, 246, + 166, 135, 229, 2, 110, 139, 192, 23, 237, 185, 152, 136, 27, 200, 206, 22, 182, 244, 56, + 253, 37, 236, 130, 211, 40, 144, 210, 242, 203, 114, 102, 213, 150, 26, 145, 8, 183, 42, + 254, 92, 177, 226, 94, 30, 108, 29, 53, 88, 214, 205, 224, 241, 148, 173, 6, 73, 160, 62, + 69, 197, 41, 199, 151, 81, 86, 104, 66, 32, 218, 168, 245, 111, 194, 133, 119, 120, 175, + 116, 212, 95, 85, 49, 125, 193, 78, 178, 24, 35, 126, 248, 19, 17, 164, 25, 90, 67, 87, 159, + 7, 128, 101, 158, 209, 187, 5, 18, 219, 223, 186, 207, 77, 123, 83, 196, 243, 1, + ], + [ + 1, 56, 52, 85, 134, 51, 29, 82, 223, 152, 31, 194, 70, 65, 42, 39, 128, 229, 231, 86, 190, + 103, 114, 216, 17, 181, 113, 160, 222, 96, 236, 109, 193, 14, 13, 214, 162, 77, 200, 149, + 120, 38, 72, 177, 146, 209, 139, 74, 32, 250, 122, 150, 176, 90, 157, 54, 197, 238, 221, 40, + 184, 24, 59, 220, 241, 132, 196, 182, 169, 212, 50, 230, 30, 138, 18, 237, 165, 245, 99, + 147, 8, 191, 159, 166, 44, 151, 232, 142, 242, 188, 248, 10, 46, 6, 79, 55, 253, 33, 49, + 174, 235, 53, 141, 186, 136, 163, 133, 252, 234, 254, 89, 101, 2, 112, 104, 170, 11, 102, + 58, 164, 189, 47, 62, 131, 140, 130, 84, 78, 256, 201, 205, 172, 123, 206, 228, 175, 34, + 105, 226, 63, 187, 192, 215, 218, 129, 28, 26, 171, 67, 154, 143, 41, 240, 76, 144, 97, 35, + 161, 21, 148, 64, 243, 244, 43, 95, 180, 57, 108, 137, 219, 185, 80, 111, 48, 118, 183, 225, + 7, 135, 107, 81, 167, 100, 203, 60, 19, 36, 217, 73, 233, 198, 37, 16, 125, 61, 75, 88, 45, + 207, 27, 227, 119, 239, 20, 92, 12, 158, 110, 249, 66, 98, 91, 213, 106, 25, 115, 15, 69, 9, + 247, 211, 251, 178, 202, 4, 224, 208, 83, 22, 204, 116, 71, 121, 94, 124, 5, 23, 3, 168, + 156, 255, 145, 153, 87, 246, 155, 199, 93, 68, 210, 195, 126, 117, 127, 173, 179, 1, + ], + [ + 1, 57, 165, 153, 240, 59, 22, 226, 32, 25, 140, 13, 227, 89, 190, 36, 253, 29, 111, 159, 68, + 21, 169, 124, 129, 157, 211, 205, 120, 158, 11, 113, 16, 141, 70, 135, 242, 173, 95, 18, + 255, 143, 184, 208, 34, 139, 213, 62, 193, 207, 234, 231, 60, 79, 134, 185, 8, 199, 35, 196, + 121, 215, 176, 9, 256, 200, 92, 104, 17, 198, 235, 31, 225, 232, 117, 244, 30, 168, 67, 221, + 4, 228, 146, 98, 189, 236, 88, 133, 128, 100, 46, 52, 137, 99, 246, 144, 241, 116, 187, 122, + 15, 84, 162, 239, 2, 114, 73, 49, 223, 118, 44, 195, 64, 50, 23, 26, 197, 178, 123, 72, 249, + 58, 222, 61, 136, 42, 81, 248, 1, 57, 165, 153, 240, 59, 22, 226, 32, 25, 140, 13, 227, 89, + 190, 36, 253, 29, 111, 159, 68, 21, 169, 124, 129, 157, 211, 205, 120, 158, 11, 113, 16, + 141, 70, 135, 242, 173, 95, 18, 255, 143, 184, 208, 34, 139, 213, 62, 193, 207, 234, 231, + 60, 79, 134, 185, 8, 199, 35, 196, 121, 215, 176, 9, 256, 200, 92, 104, 17, 198, 235, 31, + 225, 232, 117, 244, 30, 168, 67, 221, 4, 228, 146, 98, 189, 236, 88, 133, 128, 100, 46, 52, + 137, 99, 246, 144, 241, 116, 187, 122, 15, 84, 162, 239, 2, 114, 73, 49, 223, 118, 44, 195, + 64, 50, 23, 26, 197, 178, 123, 72, 249, 58, 222, 61, 136, 42, 81, 248, 1, + ], + [ + 1, 58, 23, 49, 15, 99, 88, 221, 225, 200, 35, 231, 34, 173, 11, 124, 253, 25, 165, 61, 197, + 118, 162, 144, 128, 228, 117, 104, 121, 79, 213, 18, 16, 157, 111, 13, 240, 42, 123, 195, 2, + 116, 46, 98, 30, 198, 176, 185, 193, 143, 70, 205, 68, 89, 22, 248, 249, 50, 73, 122, 137, + 236, 67, 31, 256, 199, 234, 208, 242, 158, 169, 36, 32, 57, 222, 26, 223, 84, 246, 133, 4, + 232, 92, 196, 60, 139, 95, 113, 129, 29, 140, 153, 136, 178, 44, 239, 241, 100, 146, 244, + 17, 215, 134, 62, 255, 141, 211, 159, 227, 59, 81, 72, 64, 114, 187, 52, 189, 168, 235, 9, + 8, 207, 184, 135, 120, 21, 190, 226, 1, 58, 23, 49, 15, 99, 88, 221, 225, 200, 35, 231, 34, + 173, 11, 124, 253, 25, 165, 61, 197, 118, 162, 144, 128, 228, 117, 104, 121, 79, 213, 18, + 16, 157, 111, 13, 240, 42, 123, 195, 2, 116, 46, 98, 30, 198, 176, 185, 193, 143, 70, 205, + 68, 89, 22, 248, 249, 50, 73, 122, 137, 236, 67, 31, 256, 199, 234, 208, 242, 158, 169, 36, + 32, 57, 222, 26, 223, 84, 246, 133, 4, 232, 92, 196, 60, 139, 95, 113, 129, 29, 140, 153, + 136, 178, 44, 239, 241, 100, 146, 244, 17, 215, 134, 62, 255, 141, 211, 159, 227, 59, 81, + 72, 64, 114, 187, 52, 189, 168, 235, 9, 8, 207, 184, 135, 120, 21, 190, 226, 1, + ], + [ + 1, 59, 140, 36, 68, 157, 11, 135, 255, 139, 234, 185, 121, 200, 235, 244, 4, 236, 46, 144, + 15, 114, 44, 26, 249, 42, 165, 226, 227, 29, 169, 205, 16, 173, 184, 62, 60, 199, 176, 104, + 225, 168, 146, 133, 137, 116, 162, 49, 64, 178, 222, 248, 240, 25, 190, 159, 129, 158, 70, + 18, 34, 207, 134, 196, 256, 198, 117, 221, 189, 100, 246, 122, 2, 118, 23, 72, 136, 57, 22, + 13, 253, 21, 211, 113, 242, 143, 213, 231, 8, 215, 92, 31, 30, 228, 88, 52, 241, 84, 73, + 195, 197, 58, 81, 153, 32, 89, 111, 124, 120, 141, 95, 208, 193, 79, 35, 9, 17, 232, 67, 98, + 128, 99, 187, 239, 223, 50, 123, 61, 1, 59, 140, 36, 68, 157, 11, 135, 255, 139, 234, 185, + 121, 200, 235, 244, 4, 236, 46, 144, 15, 114, 44, 26, 249, 42, 165, 226, 227, 29, 169, 205, + 16, 173, 184, 62, 60, 199, 176, 104, 225, 168, 146, 133, 137, 116, 162, 49, 64, 178, 222, + 248, 240, 25, 190, 159, 129, 158, 70, 18, 34, 207, 134, 196, 256, 198, 117, 221, 189, 100, + 246, 122, 2, 118, 23, 72, 136, 57, 22, 13, 253, 21, 211, 113, 242, 143, 213, 231, 8, 215, + 92, 31, 30, 228, 88, 52, 241, 84, 73, 195, 197, 58, 81, 153, 32, 89, 111, 124, 120, 141, 95, + 208, 193, 79, 35, 9, 17, 232, 67, 98, 128, 99, 187, 239, 223, 50, 123, 61, 1, + ], + [ + 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, + 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, + 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, + 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, + 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, + 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, + 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, + 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, + 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, + 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, + 64, 242, 128, 227, 256, 197, 255, 137, 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, + 30, 1, 60, 2, 120, 4, 240, 8, 223, 16, 189, 32, 121, 64, 242, 128, 227, 256, 197, 255, 137, + 253, 17, 249, 34, 241, 68, 225, 136, 193, 15, 129, 30, 1, + ], + [ + 1, 61, 123, 50, 223, 239, 187, 99, 128, 98, 67, 232, 17, 9, 35, 79, 193, 208, 95, 141, 120, + 124, 111, 89, 32, 153, 81, 58, 197, 195, 73, 84, 241, 52, 88, 228, 30, 31, 92, 215, 8, 231, + 213, 143, 242, 113, 211, 21, 253, 13, 22, 57, 136, 72, 23, 118, 2, 122, 246, 100, 189, 221, + 117, 198, 256, 196, 134, 207, 34, 18, 70, 158, 129, 159, 190, 25, 240, 248, 222, 178, 64, + 49, 162, 116, 137, 133, 146, 168, 225, 104, 176, 199, 60, 62, 184, 173, 16, 205, 169, 29, + 227, 226, 165, 42, 249, 26, 44, 114, 15, 144, 46, 236, 4, 244, 235, 200, 121, 185, 234, 139, + 255, 135, 11, 157, 68, 36, 140, 59, 1, 61, 123, 50, 223, 239, 187, 99, 128, 98, 67, 232, 17, + 9, 35, 79, 193, 208, 95, 141, 120, 124, 111, 89, 32, 153, 81, 58, 197, 195, 73, 84, 241, 52, + 88, 228, 30, 31, 92, 215, 8, 231, 213, 143, 242, 113, 211, 21, 253, 13, 22, 57, 136, 72, 23, + 118, 2, 122, 246, 100, 189, 221, 117, 198, 256, 196, 134, 207, 34, 18, 70, 158, 129, 159, + 190, 25, 240, 248, 222, 178, 64, 49, 162, 116, 137, 133, 146, 168, 225, 104, 176, 199, 60, + 62, 184, 173, 16, 205, 169, 29, 227, 226, 165, 42, 249, 26, 44, 114, 15, 144, 46, 236, 4, + 244, 235, 200, 121, 185, 234, 139, 255, 135, 11, 157, 68, 36, 140, 59, 1, + ], + [ + 1, 62, 246, 89, 121, 49, 211, 232, 249, 18, 88, 59, 60, 122, 111, 200, 64, 113, 67, 42, 34, + 52, 140, 199, 2, 124, 235, 178, 242, 98, 165, 207, 241, 36, 176, 118, 120, 244, 222, 143, + 128, 226, 134, 84, 68, 104, 23, 141, 4, 248, 213, 99, 227, 196, 73, 157, 225, 72, 95, 236, + 240, 231, 187, 29, 256, 195, 11, 168, 136, 208, 46, 25, 8, 239, 169, 198, 197, 135, 146, 57, + 193, 144, 190, 215, 223, 205, 117, 58, 255, 133, 22, 79, 15, 159, 92, 50, 16, 221, 81, 139, + 137, 13, 35, 114, 129, 31, 123, 173, 189, 153, 234, 116, 253, 9, 44, 158, 30, 61, 184, 100, + 32, 185, 162, 21, 17, 26, 70, 228, 1, 62, 246, 89, 121, 49, 211, 232, 249, 18, 88, 59, 60, + 122, 111, 200, 64, 113, 67, 42, 34, 52, 140, 199, 2, 124, 235, 178, 242, 98, 165, 207, 241, + 36, 176, 118, 120, 244, 222, 143, 128, 226, 134, 84, 68, 104, 23, 141, 4, 248, 213, 99, 227, + 196, 73, 157, 225, 72, 95, 236, 240, 231, 187, 29, 256, 195, 11, 168, 136, 208, 46, 25, 8, + 239, 169, 198, 197, 135, 146, 57, 193, 144, 190, 215, 223, 205, 117, 58, 255, 133, 22, 79, + 15, 159, 92, 50, 16, 221, 81, 139, 137, 13, 35, 114, 129, 31, 123, 173, 189, 153, 234, 116, + 253, 9, 44, 158, 30, 61, 184, 100, 32, 185, 162, 21, 17, 26, 70, 228, 1, + ], + [ + 1, 63, 114, 243, 146, 203, 196, 12, 242, 83, 89, 210, 123, 39, 144, 77, 225, 40, 207, 191, + 211, 186, 153, 130, 223, 171, 236, 219, 176, 37, 18, 106, 253, 5, 58, 56, 187, 216, 244, + 209, 60, 182, 158, 188, 22, 101, 195, 206, 128, 97, 200, 7, 184, 27, 159, 251, 136, 87, 84, + 152, 67, 109, 185, 90, 16, 237, 25, 33, 23, 164, 52, 192, 17, 43, 139, 19, 169, 110, 248, + 204, 2, 126, 228, 229, 35, 149, 135, 24, 227, 166, 178, 163, 246, 78, 31, 154, 193, 80, 157, + 125, 165, 115, 49, 3, 189, 85, 215, 181, 95, 74, 36, 212, 249, 10, 116, 112, 117, 175, 231, + 161, 120, 107, 59, 119, 44, 202, 133, 155, 256, 194, 143, 14, 111, 54, 61, 245, 15, 174, + 168, 47, 134, 218, 113, 180, 32, 217, 50, 66, 46, 71, 104, 127, 34, 86, 21, 38, 81, 220, + 239, 151, 4, 252, 199, 201, 70, 41, 13, 48, 197, 75, 99, 69, 235, 156, 62, 51, 129, 160, 57, + 250, 73, 230, 98, 6, 121, 170, 173, 105, 190, 148, 72, 167, 241, 20, 232, 224, 234, 93, 205, + 65, 240, 214, 118, 238, 88, 147, 9, 53, 255, 131, 29, 28, 222, 108, 122, 233, 30, 91, 79, + 94, 11, 179, 226, 103, 64, 177, 100, 132, 92, 142, 208, 254, 68, 172, 42, 76, 162, 183, 221, + 45, 8, 247, 141, 145, 140, 82, 26, 96, 137, 150, 198, 138, 213, 55, 124, 102, 1, + ], + [ + 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, + 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, + 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, + 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, + 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, + 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, + 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, + 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, + 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, + 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, + 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, + 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, 64, 241, 4, 256, 193, 16, 253, 1, + ], + [ + 1, 65, 113, 149, 176, 132, 99, 10, 136, 102, 205, 218, 35, 219, 100, 75, 249, 251, 124, 93, + 134, 229, 236, 177, 197, 212, 159, 55, 234, 47, 228, 171, 64, 48, 36, 27, 213, 224, 168, + 126, 223, 103, 13, 74, 184, 138, 232, 174, 2, 130, 226, 41, 95, 7, 198, 20, 15, 204, 153, + 179, 70, 181, 200, 150, 241, 245, 248, 186, 11, 201, 215, 97, 137, 167, 61, 110, 211, 94, + 199, 85, 128, 96, 72, 54, 169, 191, 79, 252, 189, 206, 26, 148, 111, 19, 207, 91, 4, 3, 195, + 82, 190, 14, 139, 40, 30, 151, 49, 101, 140, 105, 143, 43, 225, 233, 239, 115, 22, 145, 173, + 194, 17, 77, 122, 220, 165, 188, 141, 170, 256, 192, 144, 108, 81, 125, 158, 247, 121, 155, + 52, 39, 222, 38, 157, 182, 8, 6, 133, 164, 123, 28, 21, 80, 60, 45, 98, 202, 23, 210, 29, + 86, 193, 209, 221, 230, 44, 33, 89, 131, 34, 154, 244, 183, 73, 119, 25, 83, 255, 127, 31, + 216, 162, 250, 59, 237, 242, 53, 104, 78, 187, 76, 57, 107, 16, 12, 9, 71, 246, 56, 42, 160, + 120, 90, 196, 147, 46, 163, 58, 172, 129, 161, 185, 203, 88, 66, 178, 5, 68, 51, 231, 109, + 146, 238, 50, 166, 253, 254, 62, 175, 67, 243, 118, 217, 227, 106, 208, 156, 117, 152, 114, + 214, 32, 24, 18, 142, 235, 112, 84, 63, 240, 180, 135, 37, 92, 69, 116, 87, 1, + ], + [ + 1, 66, 244, 170, 169, 103, 116, 203, 34, 188, 72, 126, 92, 161, 89, 220, 128, 224, 135, 172, + 44, 77, 199, 27, 240, 163, 221, 194, 211, 48, 84, 147, 193, 145, 61, 171, 235, 90, 29, 115, + 137, 47, 18, 160, 23, 233, 215, 55, 32, 56, 98, 43, 11, 212, 114, 71, 60, 105, 248, 177, + 117, 12, 21, 101, 241, 229, 208, 107, 123, 151, 200, 93, 227, 76, 133, 40, 70, 251, 118, 78, + 8, 14, 153, 75, 67, 53, 157, 82, 15, 219, 62, 237, 222, 3, 198, 218, 253, 250, 52, 91, 95, + 102, 50, 216, 121, 19, 226, 10, 146, 127, 158, 148, 2, 132, 231, 83, 81, 206, 232, 149, 68, + 119, 144, 252, 184, 65, 178, 183, 256, 191, 13, 87, 88, 154, 141, 54, 223, 69, 185, 131, + 165, 96, 168, 37, 129, 33, 122, 85, 213, 180, 58, 230, 17, 94, 36, 63, 46, 209, 173, 110, + 64, 112, 196, 86, 22, 167, 228, 142, 120, 210, 239, 97, 234, 24, 42, 202, 225, 201, 159, + 214, 246, 45, 143, 186, 197, 152, 9, 80, 140, 245, 236, 156, 16, 28, 49, 150, 134, 106, 57, + 164, 30, 181, 124, 217, 187, 6, 139, 179, 249, 243, 104, 182, 190, 204, 100, 175, 242, 38, + 195, 20, 35, 254, 59, 39, 4, 7, 205, 166, 162, 155, 207, 41, 136, 238, 31, 247, 111, 130, + 99, 109, 255, 125, 26, 174, 176, 51, 25, 108, 189, 138, 113, 5, 73, 192, 79, 74, 1, + ], + [ + 1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, 46, 255, 123, 17, 111, 241, 213, 136, 117, + 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, 23, 256, 190, 137, 184, 249, 235, 68, 187, + 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, 140, 128, 95, 197, 92, 253, 246, 34, 222, + 225, 169, 15, 234, 1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, 46, 255, 123, 17, 111, 241, + 213, 136, 117, 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, 23, 256, 190, 137, 184, 249, + 235, 68, 187, 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, 140, 128, 95, 197, 92, 253, + 246, 34, 222, 225, 169, 15, 234, 1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, 46, 255, 123, + 17, 111, 241, 213, 136, 117, 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, 23, 256, 190, + 137, 184, 249, 235, 68, 187, 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, 140, 128, 95, + 197, 92, 253, 246, 34, 222, 225, 169, 15, 234, 1, 67, 120, 73, 8, 22, 189, 70, 64, 176, 227, + 46, 255, 123, 17, 111, 241, 213, 136, 117, 129, 162, 60, 165, 4, 11, 223, 35, 32, 88, 242, + 23, 256, 190, 137, 184, 249, 235, 68, 187, 193, 81, 30, 211, 2, 134, 240, 146, 16, 44, 121, + 140, 128, 95, 197, 92, 253, 246, 34, 222, 225, 169, 15, 234, 1, + ], + [ + 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, + 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, + 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, + 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, + 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, + 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, + 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, + 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, + 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, + 241, 197, 32, 120, 193, 17, 128, 223, 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, + 64, 240, 129, 34, 256, 189, 2, 136, 253, 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, + 1, 68, 255, 121, 4, 15, 249, 227, 16, 60, 225, 137, 64, 240, 129, 34, 256, 189, 2, 136, 253, + 242, 8, 30, 241, 197, 32, 120, 193, 17, 128, 223, 1, + ], + [ + 1, 69, 135, 63, 235, 24, 114, 156, 227, 243, 62, 166, 146, 51, 178, 203, 129, 163, 196, 160, + 246, 12, 57, 78, 242, 250, 31, 83, 73, 154, 89, 230, 193, 210, 98, 80, 123, 6, 157, 39, 121, + 125, 144, 170, 165, 77, 173, 115, 225, 105, 49, 40, 190, 3, 207, 148, 189, 191, 72, 85, 211, + 167, 215, 186, 241, 181, 153, 20, 95, 130, 232, 74, 223, 224, 36, 171, 234, 212, 236, 93, + 249, 219, 205, 10, 176, 65, 116, 37, 240, 112, 18, 214, 117, 106, 118, 175, 253, 238, 231, + 5, 88, 161, 58, 147, 120, 56, 9, 107, 187, 53, 59, 216, 255, 119, 244, 131, 44, 209, 29, + 202, 60, 28, 133, 182, 222, 155, 158, 108, 256, 188, 122, 194, 22, 233, 143, 101, 30, 14, + 195, 91, 111, 206, 79, 54, 128, 94, 61, 97, 11, 245, 200, 179, 15, 7, 226, 174, 184, 103, + 168, 27, 64, 47, 159, 177, 134, 251, 100, 218, 136, 132, 113, 87, 92, 180, 84, 142, 32, 152, + 208, 217, 67, 254, 50, 109, 68, 66, 185, 172, 46, 90, 42, 71, 16, 76, 104, 237, 162, 127, + 25, 183, 34, 33, 221, 86, 23, 45, 21, 164, 8, 38, 52, 247, 81, 192, 141, 220, 17, 145, 239, + 43, 140, 151, 139, 82, 4, 19, 26, 252, 169, 96, 199, 110, 137, 201, 248, 150, 70, 204, 198, + 41, 2, 138, 13, 126, 213, 48, 228, 55, 197, 229, 124, 75, 35, 102, 99, 149, 1, + ], + [ + 1, 70, 17, 162, 32, 184, 30, 44, 253, 234, 189, 123, 129, 35, 137, 81, 16, 92, 15, 22, 255, + 117, 223, 190, 193, 146, 197, 169, 8, 46, 136, 11, 256, 187, 240, 95, 225, 73, 227, 213, 4, + 23, 68, 134, 128, 222, 120, 176, 241, 165, 242, 235, 2, 140, 34, 67, 64, 111, 60, 88, 249, + 211, 121, 246, 1, 70, 17, 162, 32, 184, 30, 44, 253, 234, 189, 123, 129, 35, 137, 81, 16, + 92, 15, 22, 255, 117, 223, 190, 193, 146, 197, 169, 8, 46, 136, 11, 256, 187, 240, 95, 225, + 73, 227, 213, 4, 23, 68, 134, 128, 222, 120, 176, 241, 165, 242, 235, 2, 140, 34, 67, 64, + 111, 60, 88, 249, 211, 121, 246, 1, 70, 17, 162, 32, 184, 30, 44, 253, 234, 189, 123, 129, + 35, 137, 81, 16, 92, 15, 22, 255, 117, 223, 190, 193, 146, 197, 169, 8, 46, 136, 11, 256, + 187, 240, 95, 225, 73, 227, 213, 4, 23, 68, 134, 128, 222, 120, 176, 241, 165, 242, 235, 2, + 140, 34, 67, 64, 111, 60, 88, 249, 211, 121, 246, 1, 70, 17, 162, 32, 184, 30, 44, 253, 234, + 189, 123, 129, 35, 137, 81, 16, 92, 15, 22, 255, 117, 223, 190, 193, 146, 197, 169, 8, 46, + 136, 11, 256, 187, 240, 95, 225, 73, 227, 213, 4, 23, 68, 134, 128, 222, 120, 176, 241, 165, + 242, 235, 2, 140, 34, 67, 64, 111, 60, 88, 249, 211, 121, 246, 1, + ], + [ + 1, 71, 158, 167, 35, 172, 133, 191, 197, 109, 29, 3, 213, 217, 244, 105, 2, 142, 59, 77, 70, + 87, 9, 125, 137, 218, 58, 6, 169, 177, 231, 210, 4, 27, 118, 154, 140, 174, 18, 250, 17, + 179, 116, 12, 81, 97, 205, 163, 8, 54, 236, 51, 23, 91, 36, 243, 34, 101, 232, 24, 162, 194, + 153, 69, 16, 108, 215, 102, 46, 182, 72, 229, 68, 202, 207, 48, 67, 131, 49, 138, 32, 216, + 173, 204, 92, 107, 144, 201, 136, 147, 157, 96, 134, 5, 98, 19, 64, 175, 89, 151, 184, 214, + 31, 145, 15, 37, 57, 192, 11, 10, 196, 38, 128, 93, 178, 45, 111, 171, 62, 33, 30, 74, 114, + 127, 22, 20, 135, 76, 256, 186, 99, 90, 222, 85, 124, 66, 60, 148, 228, 254, 44, 40, 13, + 152, 255, 115, 198, 180, 187, 170, 248, 132, 120, 39, 199, 251, 88, 80, 26, 47, 253, 230, + 139, 103, 117, 83, 239, 7, 240, 78, 141, 245, 176, 160, 52, 94, 249, 203, 21, 206, 234, 166, + 221, 14, 223, 156, 25, 233, 95, 63, 104, 188, 241, 149, 42, 155, 211, 75, 185, 28, 189, 55, + 50, 209, 190, 126, 208, 119, 225, 41, 84, 53, 165, 150, 113, 56, 121, 110, 100, 161, 123, + 252, 159, 238, 193, 82, 168, 106, 73, 43, 226, 112, 242, 220, 200, 65, 246, 247, 61, 219, + 129, 164, 79, 212, 146, 86, 195, 224, 227, 183, 143, 130, 235, 237, 122, 181, 1, + ], + [ + 1, 72, 44, 84, 137, 98, 117, 200, 8, 62, 95, 158, 68, 13, 165, 58, 64, 239, 246, 236, 30, + 104, 35, 207, 255, 113, 169, 89, 240, 61, 23, 114, 241, 133, 67, 198, 121, 231, 184, 141, + 129, 36, 22, 42, 197, 49, 187, 100, 4, 31, 176, 79, 34, 135, 211, 29, 32, 248, 123, 118, 15, + 52, 146, 232, 256, 185, 213, 173, 120, 159, 140, 57, 249, 195, 162, 99, 189, 244, 92, 199, + 193, 18, 11, 21, 227, 153, 222, 50, 2, 144, 88, 168, 17, 196, 234, 143, 16, 124, 190, 59, + 136, 26, 73, 116, 128, 221, 235, 215, 60, 208, 70, 157, 253, 226, 81, 178, 223, 122, 46, + 228, 225, 9, 134, 139, 242, 205, 111, 25, 1, 72, 44, 84, 137, 98, 117, 200, 8, 62, 95, 158, + 68, 13, 165, 58, 64, 239, 246, 236, 30, 104, 35, 207, 255, 113, 169, 89, 240, 61, 23, 114, + 241, 133, 67, 198, 121, 231, 184, 141, 129, 36, 22, 42, 197, 49, 187, 100, 4, 31, 176, 79, + 34, 135, 211, 29, 32, 248, 123, 118, 15, 52, 146, 232, 256, 185, 213, 173, 120, 159, 140, + 57, 249, 195, 162, 99, 189, 244, 92, 199, 193, 18, 11, 21, 227, 153, 222, 50, 2, 144, 88, + 168, 17, 196, 234, 143, 16, 124, 190, 59, 136, 26, 73, 116, 128, 221, 235, 215, 60, 208, 70, + 157, 253, 226, 81, 178, 223, 122, 46, 228, 225, 9, 134, 139, 242, 205, 111, 25, 1, + ], + [ + 1, 73, 189, 176, 255, 111, 136, 162, 4, 35, 242, 190, 249, 187, 30, 134, 16, 140, 197, 246, + 225, 234, 120, 22, 64, 46, 17, 213, 129, 165, 223, 88, 256, 184, 68, 81, 2, 146, 121, 95, + 253, 222, 15, 67, 8, 70, 227, 123, 241, 117, 60, 11, 32, 23, 137, 235, 193, 211, 240, 44, + 128, 92, 34, 169, 1, 73, 189, 176, 255, 111, 136, 162, 4, 35, 242, 190, 249, 187, 30, 134, + 16, 140, 197, 246, 225, 234, 120, 22, 64, 46, 17, 213, 129, 165, 223, 88, 256, 184, 68, 81, + 2, 146, 121, 95, 253, 222, 15, 67, 8, 70, 227, 123, 241, 117, 60, 11, 32, 23, 137, 235, 193, + 211, 240, 44, 128, 92, 34, 169, 1, 73, 189, 176, 255, 111, 136, 162, 4, 35, 242, 190, 249, + 187, 30, 134, 16, 140, 197, 246, 225, 234, 120, 22, 64, 46, 17, 213, 129, 165, 223, 88, 256, + 184, 68, 81, 2, 146, 121, 95, 253, 222, 15, 67, 8, 70, 227, 123, 241, 117, 60, 11, 32, 23, + 137, 235, 193, 211, 240, 44, 128, 92, 34, 169, 1, 73, 189, 176, 255, 111, 136, 162, 4, 35, + 242, 190, 249, 187, 30, 134, 16, 140, 197, 246, 225, 234, 120, 22, 64, 46, 17, 213, 129, + 165, 223, 88, 256, 184, 68, 81, 2, 146, 121, 95, 253, 222, 15, 67, 8, 70, 227, 123, 241, + 117, 60, 11, 32, 23, 137, 235, 193, 211, 240, 44, 128, 92, 34, 169, 1, + ], + [ + 1, 74, 79, 192, 73, 5, 113, 138, 189, 108, 25, 51, 176, 174, 26, 125, 255, 109, 99, 130, + 111, 247, 31, 238, 136, 41, 207, 155, 162, 166, 205, 7, 4, 39, 59, 254, 35, 20, 195, 38, + 242, 175, 100, 204, 190, 182, 104, 243, 249, 179, 139, 6, 187, 217, 124, 181, 30, 164, 57, + 106, 134, 150, 49, 28, 16, 156, 236, 245, 140, 80, 9, 152, 197, 186, 143, 45, 246, 214, 159, + 201, 225, 202, 42, 24, 234, 97, 239, 210, 120, 142, 228, 167, 22, 86, 196, 112, 64, 110, + 173, 209, 46, 63, 36, 94, 17, 230, 58, 180, 213, 85, 122, 33, 129, 37, 168, 96, 165, 131, + 185, 69, 223, 54, 141, 154, 88, 87, 13, 191, 256, 183, 178, 65, 184, 252, 144, 119, 68, 149, + 232, 206, 81, 83, 231, 132, 2, 148, 158, 127, 146, 10, 226, 19, 121, 216, 50, 102, 95, 91, + 52, 250, 253, 218, 198, 3, 222, 237, 62, 219, 15, 82, 157, 53, 67, 75, 153, 14, 8, 78, 118, + 251, 70, 40, 133, 76, 227, 93, 200, 151, 123, 107, 208, 229, 241, 101, 21, 12, 117, 177, + 248, 105, 60, 71, 114, 212, 11, 43, 98, 56, 32, 55, 215, 233, 23, 160, 18, 47, 137, 115, 29, + 90, 235, 171, 61, 145, 193, 147, 84, 48, 211, 194, 221, 163, 240, 27, 199, 77, 44, 172, 135, + 224, 128, 220, 89, 161, 92, 126, 72, 188, 34, 203, 116, 103, 169, 170, 244, 66, 1, + ], + [ + 1, 75, 228, 138, 70, 110, 26, 151, 17, 247, 21, 33, 162, 71, 185, 254, 32, 87, 100, 47, 184, + 179, 61, 206, 30, 194, 158, 28, 44, 216, 9, 161, 253, 214, 116, 219, 234, 74, 153, 167, 189, + 40, 173, 125, 123, 230, 31, 12, 129, 166, 114, 69, 35, 55, 13, 204, 137, 252, 139, 145, 81, + 164, 221, 127, 16, 172, 50, 152, 92, 218, 159, 103, 15, 97, 79, 14, 22, 108, 133, 209, 255, + 107, 58, 238, 117, 37, 205, 212, 223, 20, 215, 191, 190, 115, 144, 6, 193, 83, 57, 163, 146, + 156, 135, 102, 197, 126, 198, 201, 169, 82, 239, 192, 8, 86, 25, 76, 46, 109, 208, 180, 136, + 177, 168, 7, 11, 54, 195, 233, 256, 182, 29, 119, 187, 147, 231, 106, 240, 10, 236, 224, 95, + 186, 72, 3, 225, 170, 157, 210, 73, 78, 196, 51, 227, 63, 99, 229, 213, 41, 248, 96, 4, 43, + 141, 38, 23, 183, 104, 90, 68, 217, 84, 132, 134, 27, 226, 245, 128, 91, 143, 188, 222, 202, + 244, 53, 120, 5, 118, 112, 176, 93, 36, 130, 241, 85, 207, 105, 165, 39, 98, 154, 242, 160, + 178, 243, 235, 149, 124, 48, 2, 150, 199, 19, 140, 220, 52, 45, 34, 237, 42, 66, 67, 142, + 113, 251, 64, 174, 200, 94, 111, 101, 122, 155, 60, 131, 59, 56, 88, 175, 18, 65, 249, 171, + 232, 181, 211, 148, 49, 77, 121, 80, 89, 250, 246, 203, 62, 24, 1, + ], + [ + 1, 76, 122, 20, 235, 127, 143, 74, 227, 33, 195, 171, 146, 45, 79, 93, 129, 38, 61, 10, 246, + 192, 200, 37, 242, 145, 226, 214, 73, 151, 168, 175, 193, 19, 159, 5, 123, 96, 100, 147, + 121, 201, 113, 107, 165, 204, 84, 216, 225, 138, 208, 131, 190, 48, 50, 202, 189, 229, 185, + 182, 211, 102, 42, 108, 241, 69, 104, 194, 95, 24, 25, 101, 223, 243, 221, 91, 234, 51, 21, + 54, 249, 163, 52, 97, 176, 12, 141, 179, 240, 250, 239, 174, 117, 154, 139, 27, 253, 210, + 26, 177, 88, 6, 199, 218, 120, 125, 248, 87, 187, 77, 198, 142, 255, 105, 13, 217, 44, 3, + 228, 109, 60, 191, 124, 172, 222, 167, 99, 71, 256, 181, 135, 237, 22, 130, 114, 183, 30, + 224, 62, 86, 111, 212, 178, 164, 128, 219, 196, 247, 11, 65, 57, 220, 15, 112, 31, 43, 184, + 106, 89, 82, 64, 238, 98, 252, 134, 161, 157, 110, 136, 56, 144, 150, 92, 53, 173, 41, 32, + 119, 49, 126, 67, 209, 207, 55, 68, 28, 72, 75, 46, 155, 215, 149, 16, 188, 153, 63, 162, + 233, 232, 156, 34, 14, 36, 166, 23, 206, 236, 203, 8, 94, 205, 160, 81, 245, 116, 78, 17, 7, + 18, 83, 140, 103, 118, 230, 4, 47, 231, 80, 169, 251, 58, 39, 137, 132, 9, 170, 70, 180, 59, + 115, 2, 152, 244, 40, 213, 254, 29, 148, 197, 66, 133, 85, 35, 90, 158, 186, 1, + ], + [ + 1, 77, 18, 101, 67, 19, 178, 85, 120, 245, 104, 41, 73, 224, 29, 177, 8, 102, 144, 37, 22, + 152, 139, 166, 189, 161, 61, 71, 70, 250, 232, 131, 64, 45, 124, 39, 176, 188, 84, 43, 227, + 3, 231, 54, 46, 201, 57, 20, 255, 103, 221, 55, 123, 219, 158, 87, 17, 24, 49, 175, 111, 66, + 199, 160, 241, 53, 226, 183, 213, 210, 236, 182, 136, 192, 135, 115, 117, 14, 50, 252, 129, + 167, 9, 179, 162, 138, 89, 171, 60, 251, 52, 149, 165, 112, 143, 217, 4, 51, 72, 147, 11, + 76, 198, 83, 223, 209, 159, 164, 35, 125, 116, 194, 32, 151, 62, 148, 88, 94, 42, 150, 242, + 130, 244, 27, 23, 229, 157, 10, 256, 180, 239, 156, 190, 238, 79, 172, 137, 12, 153, 216, + 184, 33, 228, 80, 249, 155, 113, 220, 235, 105, 118, 91, 68, 96, 196, 186, 187, 7, 25, 126, + 193, 212, 133, 218, 81, 69, 173, 214, 30, 254, 26, 203, 211, 56, 200, 237, 2, 154, 36, 202, + 134, 38, 99, 170, 240, 233, 208, 82, 146, 191, 58, 97, 16, 204, 31, 74, 44, 47, 21, 75, 121, + 65, 122, 142, 140, 243, 207, 5, 128, 90, 248, 78, 95, 119, 168, 86, 197, 6, 205, 108, 92, + 145, 114, 40, 253, 206, 185, 110, 246, 181, 59, 174, 34, 48, 98, 93, 222, 132, 141, 63, 225, + 106, 195, 109, 169, 163, 215, 107, 15, 127, 13, 230, 234, 28, 100, 247, 1, + ], + [ + 1, 78, 173, 130, 117, 131, 195, 47, 68, 164, 199, 102, 246, 170, 153, 112, 255, 101, 168, + 254, 23, 252, 124, 163, 121, 186, 116, 53, 22, 174, 208, 33, 4, 55, 178, 6, 211, 10, 9, 188, + 15, 142, 25, 151, 213, 166, 98, 191, 249, 147, 158, 245, 92, 237, 239, 138, 227, 230, 207, + 212, 88, 182, 61, 132, 16, 220, 198, 24, 73, 40, 36, 238, 60, 54, 100, 90, 81, 150, 135, + 250, 225, 74, 118, 209, 111, 177, 185, 38, 137, 149, 57, 77, 95, 214, 244, 14, 64, 109, 21, + 96, 35, 160, 144, 181, 240, 216, 143, 103, 67, 86, 26, 229, 129, 39, 215, 65, 187, 194, 226, + 152, 34, 82, 228, 51, 123, 85, 205, 56, 256, 179, 84, 127, 140, 126, 62, 210, 189, 93, 58, + 155, 11, 87, 104, 145, 2, 156, 89, 3, 234, 5, 133, 94, 136, 71, 141, 204, 235, 83, 49, 224, + 253, 202, 79, 251, 46, 247, 248, 69, 242, 115, 232, 106, 44, 91, 159, 66, 8, 110, 99, 12, + 165, 20, 18, 119, 30, 27, 50, 45, 169, 75, 196, 125, 241, 37, 59, 233, 184, 217, 221, 19, + 197, 203, 157, 167, 176, 107, 122, 7, 32, 183, 139, 48, 146, 80, 72, 219, 120, 108, 200, + 180, 162, 43, 13, 243, 193, 148, 236, 161, 222, 97, 113, 76, 17, 41, 114, 154, 190, 171, + 231, 28, 128, 218, 42, 192, 70, 63, 31, 105, 223, 175, 29, 206, 134, 172, 52, 201, 1, + ], + [ + 1, 79, 73, 113, 189, 25, 176, 26, 255, 99, 111, 31, 136, 207, 162, 205, 4, 59, 35, 195, 242, + 100, 190, 104, 249, 139, 187, 124, 30, 57, 134, 49, 16, 236, 140, 9, 197, 143, 246, 159, + 225, 42, 234, 239, 120, 228, 22, 196, 64, 173, 46, 36, 17, 58, 213, 122, 129, 168, 165, 185, + 223, 141, 88, 13, 256, 178, 184, 144, 68, 232, 81, 231, 2, 158, 146, 226, 121, 50, 95, 52, + 253, 198, 222, 62, 15, 157, 67, 153, 8, 118, 70, 133, 227, 200, 123, 208, 241, 21, 117, 248, + 60, 114, 11, 98, 32, 215, 23, 18, 137, 29, 235, 61, 193, 84, 211, 221, 240, 199, 44, 135, + 128, 89, 92, 72, 34, 116, 169, 244, 1, 79, 73, 113, 189, 25, 176, 26, 255, 99, 111, 31, 136, + 207, 162, 205, 4, 59, 35, 195, 242, 100, 190, 104, 249, 139, 187, 124, 30, 57, 134, 49, 16, + 236, 140, 9, 197, 143, 246, 159, 225, 42, 234, 239, 120, 228, 22, 196, 64, 173, 46, 36, 17, + 58, 213, 122, 129, 168, 165, 185, 223, 141, 88, 13, 256, 178, 184, 144, 68, 232, 81, 231, 2, + 158, 146, 226, 121, 50, 95, 52, 253, 198, 222, 62, 15, 157, 67, 153, 8, 118, 70, 133, 227, + 200, 123, 208, 241, 21, 117, 248, 60, 114, 11, 98, 32, 215, 23, 18, 137, 29, 235, 61, 193, + 84, 211, 221, 240, 199, 44, 135, 128, 89, 92, 72, 34, 116, 169, 244, 1, + ], + [ + 1, 80, 232, 56, 111, 142, 52, 48, 242, 85, 118, 188, 134, 183, 248, 51, 225, 10, 29, 7, 46, + 82, 135, 6, 223, 107, 79, 152, 81, 55, 31, 167, 253, 194, 100, 33, 70, 203, 49, 65, 60, 174, + 42, 19, 235, 39, 36, 53, 128, 217, 141, 229, 73, 186, 231, 233, 136, 86, 198, 163, 190, 37, + 133, 103, 16, 252, 114, 125, 234, 216, 61, 254, 17, 75, 89, 181, 88, 101, 113, 45, 2, 160, + 207, 112, 222, 27, 104, 96, 227, 170, 236, 119, 11, 109, 239, 102, 193, 20, 58, 14, 92, 164, + 13, 12, 189, 214, 158, 47, 162, 110, 62, 77, 249, 131, 200, 66, 140, 149, 98, 130, 120, 91, + 84, 38, 213, 78, 72, 106, 256, 177, 25, 201, 146, 115, 205, 209, 15, 172, 139, 69, 123, 74, + 9, 206, 32, 247, 228, 250, 211, 175, 122, 251, 34, 150, 178, 105, 176, 202, 226, 90, 4, 63, + 157, 224, 187, 54, 208, 192, 197, 83, 215, 238, 22, 218, 221, 204, 129, 40, 116, 28, 184, + 71, 26, 24, 121, 171, 59, 94, 67, 220, 124, 154, 241, 5, 143, 132, 23, 41, 196, 3, 240, 182, + 168, 76, 169, 156, 144, 212, 255, 97, 50, 145, 35, 230, 153, 161, 30, 87, 21, 138, 246, 148, + 18, 155, 64, 237, 199, 243, 165, 93, 244, 245, 68, 43, 99, 210, 95, 147, 195, 180, 8, 126, + 57, 191, 117, 108, 159, 127, 137, 166, 173, 219, 44, 179, 185, 151, 1, + ], + [ + 1, 81, 136, 222, 249, 123, 197, 23, 64, 44, 223, 73, 2, 162, 15, 187, 241, 246, 137, 46, + 128, 88, 189, 146, 4, 67, 30, 117, 225, 235, 17, 92, 256, 176, 121, 35, 8, 134, 60, 234, + 193, 213, 34, 184, 255, 95, 242, 70, 16, 11, 120, 211, 129, 169, 68, 111, 253, 190, 227, + 140, 32, 22, 240, 165, 1, 81, 136, 222, 249, 123, 197, 23, 64, 44, 223, 73, 2, 162, 15, 187, + 241, 246, 137, 46, 128, 88, 189, 146, 4, 67, 30, 117, 225, 235, 17, 92, 256, 176, 121, 35, + 8, 134, 60, 234, 193, 213, 34, 184, 255, 95, 242, 70, 16, 11, 120, 211, 129, 169, 68, 111, + 253, 190, 227, 140, 32, 22, 240, 165, 1, 81, 136, 222, 249, 123, 197, 23, 64, 44, 223, 73, + 2, 162, 15, 187, 241, 246, 137, 46, 128, 88, 189, 146, 4, 67, 30, 117, 225, 235, 17, 92, + 256, 176, 121, 35, 8, 134, 60, 234, 193, 213, 34, 184, 255, 95, 242, 70, 16, 11, 120, 211, + 129, 169, 68, 111, 253, 190, 227, 140, 32, 22, 240, 165, 1, 81, 136, 222, 249, 123, 197, 23, + 64, 44, 223, 73, 2, 162, 15, 187, 241, 246, 137, 46, 128, 88, 189, 146, 4, 67, 30, 117, 225, + 235, 17, 92, 256, 176, 121, 35, 8, 134, 60, 234, 193, 213, 34, 184, 255, 95, 242, 70, 16, + 11, 120, 211, 129, 169, 68, 111, 253, 190, 227, 140, 32, 22, 240, 165, 1, + ], + [ + 1, 82, 42, 103, 222, 214, 72, 250, 197, 220, 50, 245, 44, 10, 49, 163, 2, 164, 84, 206, 187, + 171, 144, 243, 137, 183, 100, 233, 88, 20, 98, 69, 4, 71, 168, 155, 117, 85, 31, 229, 17, + 109, 200, 209, 176, 40, 196, 138, 8, 142, 79, 53, 234, 170, 62, 201, 34, 218, 143, 161, 95, + 80, 135, 19, 16, 27, 158, 106, 211, 83, 124, 145, 68, 179, 29, 65, 190, 160, 13, 38, 32, 54, + 59, 212, 165, 166, 248, 33, 136, 101, 58, 130, 123, 63, 26, 76, 64, 108, 118, 167, 73, 75, + 239, 66, 15, 202, 116, 3, 246, 126, 52, 152, 128, 216, 236, 77, 146, 150, 221, 132, 30, 147, + 232, 6, 235, 252, 104, 47, 256, 175, 215, 154, 35, 43, 185, 7, 60, 37, 207, 12, 213, 247, + 208, 94, 255, 93, 173, 51, 70, 86, 113, 14, 120, 74, 157, 24, 169, 237, 159, 188, 253, 186, + 89, 102, 140, 172, 226, 28, 240, 148, 57, 48, 81, 217, 61, 119, 249, 115, 178, 204, 23, 87, + 195, 56, 223, 39, 114, 96, 162, 177, 122, 238, 241, 230, 99, 151, 46, 174, 133, 112, 189, + 78, 228, 192, 67, 97, 244, 219, 225, 203, 198, 45, 92, 91, 9, 224, 121, 156, 199, 127, 134, + 194, 231, 181, 193, 149, 139, 90, 184, 182, 18, 191, 242, 55, 141, 254, 11, 131, 205, 105, + 129, 41, 21, 180, 111, 107, 36, 125, 227, 110, 25, 251, 22, 5, 153, 210, 1, + ], + [ + 1, 83, 207, 219, 187, 101, 159, 90, 17, 126, 178, 125, 95, 175, 133, 245, 32, 86, 199, 69, + 73, 148, 205, 53, 30, 177, 42, 145, 213, 203, 144, 130, 253, 182, 200, 152, 23, 110, 135, + 154, 189, 10, 59, 14, 134, 71, 239, 48, 129, 170, 232, 238, 222, 179, 208, 45, 137, 63, 89, + 191, 176, 216, 195, 251, 16, 43, 228, 163, 165, 74, 231, 155, 15, 217, 21, 201, 235, 230, + 72, 65, 255, 91, 100, 76, 140, 55, 196, 77, 223, 5, 158, 7, 67, 164, 248, 24, 193, 85, 116, + 119, 111, 218, 104, 151, 197, 160, 173, 224, 88, 108, 226, 254, 8, 150, 114, 210, 211, 37, + 244, 206, 136, 237, 139, 229, 246, 115, 36, 161, 256, 174, 50, 38, 70, 156, 98, 167, 240, + 131, 79, 132, 162, 82, 124, 12, 225, 171, 58, 188, 184, 109, 52, 204, 227, 80, 215, 112, 44, + 54, 113, 127, 4, 75, 57, 105, 234, 147, 122, 103, 68, 247, 198, 243, 123, 186, 18, 209, 128, + 87, 25, 19, 35, 78, 49, 212, 120, 194, 168, 66, 81, 41, 62, 6, 241, 214, 29, 94, 92, 183, + 26, 102, 242, 40, 236, 56, 22, 27, 185, 192, 2, 166, 157, 181, 117, 202, 61, 180, 34, 252, + 99, 250, 190, 93, 9, 233, 64, 172, 141, 138, 146, 39, 153, 106, 60, 97, 84, 33, 169, 149, + 31, 3, 249, 107, 143, 47, 46, 220, 13, 51, 121, 20, 118, 28, 11, 142, 221, 96, 1, + ], + [ + 1, 84, 117, 62, 68, 58, 246, 104, 255, 89, 23, 133, 121, 141, 22, 49, 4, 79, 211, 248, 15, + 232, 213, 159, 249, 99, 92, 18, 227, 50, 88, 196, 16, 59, 73, 221, 60, 157, 81, 122, 225, + 139, 111, 72, 137, 200, 95, 13, 64, 236, 35, 113, 240, 114, 67, 231, 129, 42, 187, 31, 34, + 29, 123, 52, 256, 173, 140, 195, 189, 199, 11, 153, 2, 168, 234, 124, 136, 116, 235, 208, + 253, 178, 46, 9, 242, 25, 44, 98, 8, 158, 165, 239, 30, 207, 169, 61, 241, 198, 184, 36, + 197, 100, 176, 135, 32, 118, 146, 185, 120, 57, 162, 244, 193, 21, 222, 144, 17, 143, 190, + 26, 128, 215, 70, 226, 223, 228, 134, 205, 1, 84, 117, 62, 68, 58, 246, 104, 255, 89, 23, + 133, 121, 141, 22, 49, 4, 79, 211, 248, 15, 232, 213, 159, 249, 99, 92, 18, 227, 50, 88, + 196, 16, 59, 73, 221, 60, 157, 81, 122, 225, 139, 111, 72, 137, 200, 95, 13, 64, 236, 35, + 113, 240, 114, 67, 231, 129, 42, 187, 31, 34, 29, 123, 52, 256, 173, 140, 195, 189, 199, 11, + 153, 2, 168, 234, 124, 136, 116, 235, 208, 253, 178, 46, 9, 242, 25, 44, 98, 8, 158, 165, + 239, 30, 207, 169, 61, 241, 198, 184, 36, 197, 100, 176, 135, 32, 118, 146, 185, 120, 57, + 162, 244, 193, 21, 222, 144, 17, 143, 190, 26, 128, 215, 70, 226, 223, 228, 134, 205, 1, + ], + [ + 1, 85, 29, 152, 70, 39, 231, 103, 17, 160, 236, 14, 162, 149, 72, 209, 32, 150, 157, 238, + 184, 220, 196, 212, 30, 237, 99, 191, 44, 142, 248, 6, 253, 174, 141, 163, 234, 101, 104, + 102, 189, 131, 84, 201, 123, 175, 226, 192, 129, 171, 143, 76, 35, 148, 244, 180, 137, 80, + 118, 7, 81, 203, 36, 233, 16, 75, 207, 119, 92, 110, 98, 106, 15, 247, 178, 224, 22, 71, + 124, 3, 255, 87, 199, 210, 117, 179, 52, 51, 223, 194, 42, 229, 190, 216, 113, 96, 193, 214, + 200, 38, 146, 74, 122, 90, 197, 40, 59, 132, 169, 230, 18, 245, 8, 166, 232, 188, 46, 55, + 49, 53, 136, 252, 89, 112, 11, 164, 62, 130, 256, 172, 228, 105, 187, 218, 26, 154, 240, 97, + 21, 243, 95, 108, 185, 48, 225, 107, 100, 19, 73, 37, 61, 45, 227, 20, 158, 66, 213, 115, 9, + 251, 4, 83, 116, 94, 23, 156, 153, 155, 68, 126, 173, 56, 134, 82, 31, 65, 128, 86, 114, + 181, 222, 109, 13, 77, 120, 177, 139, 250, 176, 54, 221, 24, 241, 182, 50, 138, 165, 147, + 159, 151, 242, 10, 79, 33, 235, 186, 133, 254, 2, 170, 58, 47, 140, 78, 205, 206, 34, 63, + 215, 28, 67, 41, 144, 161, 64, 43, 57, 219, 111, 183, 135, 167, 60, 217, 198, 125, 88, 27, + 239, 12, 249, 91, 25, 69, 211, 202, 208, 204, 121, 5, 168, 145, 246, 93, 195, 127, 1, + ], + [ + 1, 86, 200, 238, 165, 55, 104, 206, 240, 80, 198, 66, 22, 93, 31, 96, 32, 182, 232, 163, + 140, 218, 244, 167, 227, 247, 168, 56, 190, 149, 221, 245, 253, 170, 228, 76, 111, 37, 98, + 204, 68, 194, 236, 250, 169, 142, 133, 130, 129, 43, 100, 119, 211, 156, 52, 103, 120, 40, + 99, 33, 11, 175, 144, 48, 16, 91, 116, 210, 70, 109, 122, 212, 242, 252, 84, 28, 95, 203, + 239, 251, 255, 85, 114, 38, 184, 147, 49, 102, 34, 97, 118, 125, 213, 71, 195, 65, 193, 150, + 50, 188, 234, 78, 26, 180, 60, 20, 178, 145, 134, 216, 72, 24, 8, 174, 58, 105, 35, 183, 61, + 106, 121, 126, 42, 14, 176, 230, 248, 254, 256, 171, 57, 19, 92, 202, 153, 51, 17, 177, 59, + 191, 235, 164, 226, 161, 225, 75, 25, 94, 117, 39, 13, 90, 30, 10, 89, 201, 67, 108, 36, 12, + 4, 87, 29, 181, 146, 220, 159, 53, 189, 63, 21, 7, 88, 115, 124, 127, 128, 214, 157, 138, + 46, 101, 205, 154, 137, 217, 158, 224, 246, 82, 113, 209, 241, 166, 141, 47, 187, 148, 135, + 45, 15, 5, 173, 229, 162, 54, 18, 6, 2, 172, 143, 219, 73, 110, 208, 155, 223, 160, 139, + 132, 44, 186, 62, 192, 64, 107, 207, 69, 23, 179, 231, 77, 197, 237, 79, 112, 123, 41, 185, + 233, 249, 83, 199, 152, 222, 74, 196, 151, 136, 131, 215, 243, 81, 27, 9, 3, 1, + ], + [ + 1, 87, 116, 69, 92, 37, 135, 180, 240, 63, 84, 112, 235, 142, 18, 24, 32, 214, 114, 152, + 117, 156, 208, 106, 227, 217, 118, 243, 67, 175, 62, 254, 253, 166, 50, 238, 146, 109, 231, + 51, 68, 5, 178, 66, 88, 203, 185, 161, 129, 172, 58, 163, 46, 147, 196, 90, 120, 160, 42, + 56, 246, 71, 9, 12, 16, 107, 57, 76, 187, 78, 104, 53, 242, 237, 59, 250, 162, 216, 31, 127, + 255, 83, 25, 119, 73, 183, 244, 154, 34, 131, 89, 33, 44, 230, 221, 209, 193, 86, 29, 210, + 23, 202, 98, 45, 60, 80, 21, 28, 123, 164, 133, 6, 8, 182, 157, 38, 222, 39, 52, 155, 121, + 247, 158, 125, 81, 108, 144, 192, 256, 170, 141, 188, 165, 220, 122, 77, 17, 194, 173, 145, + 22, 115, 239, 233, 225, 43, 143, 105, 140, 101, 49, 151, 30, 40, 139, 14, 190, 82, 195, 3, + 4, 91, 207, 19, 111, 148, 26, 206, 189, 252, 79, 191, 169, 54, 72, 96, 128, 85, 199, 94, + 211, 110, 61, 167, 137, 97, 215, 201, 11, 186, 248, 245, 241, 150, 200, 181, 70, 179, 153, + 204, 15, 20, 198, 7, 95, 41, 226, 130, 2, 174, 232, 138, 184, 74, 13, 103, 223, 126, 168, + 224, 213, 27, 36, 48, 64, 171, 228, 47, 234, 55, 159, 212, 197, 177, 236, 229, 134, 93, 124, + 251, 249, 75, 100, 219, 35, 218, 205, 102, 136, 10, 99, 132, 176, 149, 113, 65, 1, + ], + [ + 1, 88, 34, 165, 128, 213, 240, 46, 193, 22, 137, 234, 32, 246, 60, 140, 241, 134, 227, 187, + 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, 68, 73, 256, 169, 223, 92, 129, 44, 17, 211, 64, + 235, 120, 23, 225, 11, 197, 117, 16, 123, 30, 70, 249, 67, 242, 222, 4, 95, 136, 146, 255, + 81, 189, 184, 1, 88, 34, 165, 128, 213, 240, 46, 193, 22, 137, 234, 32, 246, 60, 140, 241, + 134, 227, 187, 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, 68, 73, 256, 169, 223, 92, 129, + 44, 17, 211, 64, 235, 120, 23, 225, 11, 197, 117, 16, 123, 30, 70, 249, 67, 242, 222, 4, 95, + 136, 146, 255, 81, 189, 184, 1, 88, 34, 165, 128, 213, 240, 46, 193, 22, 137, 234, 32, 246, + 60, 140, 241, 134, 227, 187, 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, 68, 73, 256, 169, + 223, 92, 129, 44, 17, 211, 64, 235, 120, 23, 225, 11, 197, 117, 16, 123, 30, 70, 249, 67, + 242, 222, 4, 95, 136, 146, 255, 81, 189, 184, 1, 88, 34, 165, 128, 213, 240, 46, 193, 22, + 137, 234, 32, 246, 60, 140, 241, 134, 227, 187, 8, 190, 15, 35, 253, 162, 121, 111, 2, 176, + 68, 73, 256, 169, 223, 92, 129, 44, 17, 211, 64, 235, 120, 23, 225, 11, 197, 117, 16, 123, + 30, 70, 249, 67, 242, 222, 4, 95, 136, 146, 255, 81, 189, 184, 1, + ], + [ + 1, 89, 211, 18, 60, 200, 67, 52, 2, 178, 165, 36, 120, 143, 134, 104, 4, 99, 73, 72, 240, + 29, 11, 208, 8, 198, 146, 144, 223, 58, 22, 159, 16, 139, 35, 31, 189, 116, 44, 61, 32, 21, + 70, 62, 121, 232, 88, 122, 64, 42, 140, 124, 242, 207, 176, 244, 128, 84, 23, 248, 227, 157, + 95, 231, 256, 168, 46, 239, 197, 57, 190, 205, 255, 79, 92, 221, 137, 114, 123, 153, 253, + 158, 184, 185, 17, 228, 246, 49, 249, 59, 111, 113, 34, 199, 235, 98, 241, 118, 222, 226, + 68, 141, 213, 196, 225, 236, 187, 195, 136, 25, 169, 135, 193, 215, 117, 133, 15, 50, 81, + 13, 129, 173, 234, 9, 30, 100, 162, 26, 1, 89, 211, 18, 60, 200, 67, 52, 2, 178, 165, 36, + 120, 143, 134, 104, 4, 99, 73, 72, 240, 29, 11, 208, 8, 198, 146, 144, 223, 58, 22, 159, 16, + 139, 35, 31, 189, 116, 44, 61, 32, 21, 70, 62, 121, 232, 88, 122, 64, 42, 140, 124, 242, + 207, 176, 244, 128, 84, 23, 248, 227, 157, 95, 231, 256, 168, 46, 239, 197, 57, 190, 205, + 255, 79, 92, 221, 137, 114, 123, 153, 253, 158, 184, 185, 17, 228, 246, 49, 249, 59, 111, + 113, 34, 199, 235, 98, 241, 118, 222, 226, 68, 141, 213, 196, 225, 236, 187, 195, 136, 25, + 169, 135, 193, 215, 117, 133, 15, 50, 81, 13, 129, 173, 234, 9, 30, 100, 162, 26, 1, + ], + [ + 1, 90, 133, 148, 213, 152, 59, 170, 137, 251, 231, 230, 140, 7, 116, 160, 8, 206, 36, 156, + 162, 188, 215, 75, 68, 209, 49, 41, 92, 56, 157, 252, 64, 106, 31, 220, 11, 219, 178, 86, + 30, 130, 135, 71, 222, 191, 228, 217, 255, 77, 248, 218, 88, 210, 139, 174, 240, 12, 52, 54, + 234, 243, 25, 194, 241, 102, 185, 202, 190, 138, 84, 107, 121, 96, 159, 175, 73, 145, 200, + 10, 129, 45, 195, 74, 235, 76, 158, 85, 197, 254, 244, 115, 70, 132, 58, 80, 4, 103, 18, 78, + 81, 94, 236, 166, 34, 233, 153, 149, 46, 28, 207, 126, 32, 53, 144, 110, 134, 238, 89, 43, + 15, 65, 196, 164, 111, 224, 114, 237, 256, 167, 124, 109, 44, 105, 198, 87, 120, 6, 26, 27, + 117, 250, 141, 97, 249, 51, 221, 101, 95, 69, 42, 182, 189, 48, 208, 216, 165, 201, 100, 5, + 193, 151, 226, 37, 246, 38, 79, 171, 227, 127, 122, 186, 35, 66, 29, 40, 2, 180, 9, 39, 169, + 47, 118, 83, 17, 245, 205, 203, 23, 14, 232, 63, 16, 155, 72, 55, 67, 119, 173, 150, 136, + 161, 98, 82, 184, 112, 57, 247, 128, 212, 62, 183, 22, 181, 99, 172, 60, 3, 13, 142, 187, + 125, 199, 177, 253, 154, 239, 179, 176, 163, 21, 91, 223, 24, 104, 108, 211, 229, 50, 131, + 225, 204, 113, 147, 123, 19, 168, 214, 242, 192, 61, 93, 146, 33, 143, 20, 1, + ], + [ + 1, 91, 57, 47, 165, 109, 153, 45, 240, 252, 59, 229, 22, 203, 226, 6, 32, 85, 25, 219, 140, + 147, 13, 155, 227, 97, 89, 132, 190, 71, 36, 192, 253, 150, 29, 69, 111, 78, 159, 77, 68, + 20, 21, 112, 169, 216, 124, 233, 129, 174, 157, 152, 211, 183, 205, 151, 120, 126, 158, 243, + 11, 230, 113, 3, 16, 171, 141, 238, 70, 202, 135, 206, 242, 177, 173, 66, 95, 164, 18, 96, + 255, 75, 143, 163, 184, 39, 208, 167, 34, 10, 139, 56, 213, 108, 62, 245, 193, 87, 207, 76, + 234, 220, 231, 204, 60, 63, 79, 250, 134, 115, 185, 130, 8, 214, 199, 119, 35, 101, 196, + 103, 121, 217, 215, 33, 176, 82, 9, 48, 256, 166, 200, 210, 92, 148, 104, 212, 17, 5, 198, + 28, 235, 54, 31, 251, 225, 172, 232, 38, 117, 110, 244, 102, 30, 160, 168, 125, 67, 186, + 221, 65, 4, 107, 228, 188, 146, 179, 98, 180, 189, 237, 236, 145, 88, 41, 133, 24, 128, 83, + 100, 105, 46, 74, 52, 106, 137, 131, 99, 14, 246, 27, 144, 254, 241, 86, 116, 19, 187, 55, + 122, 51, 15, 80, 84, 191, 162, 93, 239, 161, 2, 182, 114, 94, 73, 218, 49, 90, 223, 247, + 118, 201, 44, 149, 195, 12, 64, 170, 50, 181, 23, 37, 26, 53, 197, 194, 178, 7, 123, 142, + 72, 127, 249, 43, 58, 138, 222, 156, 61, 154, 136, 40, 42, 224, 81, 175, 248, 209, 1, + ], + [ + 1, 92, 240, 235, 32, 117, 227, 67, 253, 146, 68, 88, 129, 46, 120, 246, 16, 187, 242, 162, + 255, 73, 34, 44, 193, 23, 60, 123, 8, 222, 121, 81, 256, 165, 17, 22, 225, 140, 30, 190, 4, + 111, 189, 169, 128, 211, 137, 11, 241, 70, 15, 95, 2, 184, 223, 213, 64, 234, 197, 134, 249, + 35, 136, 176, 1, 92, 240, 235, 32, 117, 227, 67, 253, 146, 68, 88, 129, 46, 120, 246, 16, + 187, 242, 162, 255, 73, 34, 44, 193, 23, 60, 123, 8, 222, 121, 81, 256, 165, 17, 22, 225, + 140, 30, 190, 4, 111, 189, 169, 128, 211, 137, 11, 241, 70, 15, 95, 2, 184, 223, 213, 64, + 234, 197, 134, 249, 35, 136, 176, 1, 92, 240, 235, 32, 117, 227, 67, 253, 146, 68, 88, 129, + 46, 120, 246, 16, 187, 242, 162, 255, 73, 34, 44, 193, 23, 60, 123, 8, 222, 121, 81, 256, + 165, 17, 22, 225, 140, 30, 190, 4, 111, 189, 169, 128, 211, 137, 11, 241, 70, 15, 95, 2, + 184, 223, 213, 64, 234, 197, 134, 249, 35, 136, 176, 1, 92, 240, 235, 32, 117, 227, 67, 253, + 146, 68, 88, 129, 46, 120, 246, 16, 187, 242, 162, 255, 73, 34, 44, 193, 23, 60, 123, 8, + 222, 121, 81, 256, 165, 17, 22, 225, 140, 30, 190, 4, 111, 189, 169, 128, 211, 137, 11, 241, + 70, 15, 95, 2, 184, 223, 213, 64, 234, 197, 134, 249, 35, 136, 176, 1, + ], + [ + 1, 93, 168, 204, 211, 91, 239, 125, 60, 183, 57, 161, 67, 63, 205, 47, 2, 186, 79, 151, 165, + 182, 221, 250, 120, 109, 114, 65, 134, 126, 153, 94, 4, 115, 158, 45, 73, 107, 185, 243, + 240, 218, 228, 130, 11, 252, 49, 188, 8, 230, 59, 90, 146, 214, 113, 229, 223, 179, 199, 3, + 22, 247, 98, 119, 16, 203, 118, 180, 35, 171, 226, 201, 189, 101, 141, 6, 44, 237, 196, 238, + 32, 149, 236, 103, 70, 85, 195, 145, 121, 202, 25, 12, 88, 217, 135, 219, 64, 41, 215, 206, + 140, 170, 133, 33, 242, 147, 50, 24, 176, 177, 13, 181, 128, 82, 173, 155, 23, 83, 9, 66, + 227, 37, 100, 48, 95, 97, 26, 105, 256, 164, 89, 53, 46, 166, 18, 132, 197, 74, 200, 96, + 190, 194, 52, 210, 255, 71, 178, 106, 92, 75, 36, 7, 137, 148, 143, 192, 123, 131, 104, 163, + 253, 142, 99, 212, 184, 150, 72, 14, 17, 39, 29, 127, 246, 5, 208, 69, 249, 27, 198, 167, + 111, 43, 144, 28, 34, 78, 58, 254, 235, 10, 159, 138, 241, 54, 139, 77, 222, 86, 31, 56, 68, + 156, 116, 251, 213, 20, 61, 19, 225, 108, 21, 154, 187, 172, 62, 112, 136, 55, 232, 245, + 169, 40, 122, 38, 193, 216, 42, 51, 117, 87, 124, 224, 15, 110, 207, 233, 81, 80, 244, 76, + 129, 175, 84, 102, 234, 174, 248, 191, 30, 220, 157, 209, 162, 160, 231, 152, 1, + ], + [ + 1, 94, 98, 217, 95, 192, 58, 55, 30, 250, 113, 85, 23, 106, 198, 108, 129, 47, 49, 237, 176, + 96, 29, 156, 15, 125, 185, 171, 140, 53, 99, 54, 193, 152, 153, 247, 88, 48, 143, 78, 136, + 191, 221, 214, 70, 155, 178, 27, 225, 76, 205, 252, 44, 24, 200, 39, 68, 224, 239, 107, 35, + 206, 89, 142, 241, 38, 231, 126, 22, 12, 100, 148, 34, 112, 248, 182, 146, 103, 173, 71, + 249, 19, 244, 63, 11, 6, 50, 74, 17, 56, 124, 91, 73, 180, 215, 164, 253, 138, 122, 160, + 134, 3, 25, 37, 137, 28, 62, 174, 165, 90, 236, 82, 255, 69, 61, 80, 67, 130, 141, 147, 197, + 14, 31, 87, 211, 45, 118, 41, 256, 163, 159, 40, 162, 65, 199, 202, 227, 7, 144, 172, 234, + 151, 59, 149, 128, 210, 208, 20, 81, 161, 228, 101, 242, 132, 72, 86, 117, 204, 158, 203, + 64, 105, 104, 10, 169, 209, 114, 179, 121, 66, 36, 43, 187, 102, 79, 230, 32, 181, 52, 5, + 213, 233, 57, 218, 189, 33, 18, 150, 222, 51, 168, 115, 16, 219, 26, 131, 235, 245, 157, + 109, 223, 145, 9, 75, 111, 154, 84, 186, 8, 238, 13, 194, 246, 251, 207, 183, 240, 201, 133, + 166, 184, 77, 42, 93, 4, 119, 135, 97, 123, 254, 232, 220, 120, 229, 195, 83, 92, 167, 21, + 175, 2, 188, 196, 177, 190, 127, 116, 110, 60, 243, 226, 170, 46, 212, 139, 216, 1, + ], + [ + 1, 95, 30, 23, 129, 176, 15, 140, 193, 88, 136, 70, 225, 44, 68, 35, 241, 22, 34, 146, 249, + 11, 17, 73, 253, 134, 137, 165, 255, 67, 197, 211, 256, 162, 227, 234, 128, 81, 242, 117, + 64, 169, 121, 187, 32, 213, 189, 222, 16, 235, 223, 111, 8, 246, 240, 184, 4, 123, 120, 92, + 2, 190, 60, 46, 1, 95, 30, 23, 129, 176, 15, 140, 193, 88, 136, 70, 225, 44, 68, 35, 241, + 22, 34, 146, 249, 11, 17, 73, 253, 134, 137, 165, 255, 67, 197, 211, 256, 162, 227, 234, + 128, 81, 242, 117, 64, 169, 121, 187, 32, 213, 189, 222, 16, 235, 223, 111, 8, 246, 240, + 184, 4, 123, 120, 92, 2, 190, 60, 46, 1, 95, 30, 23, 129, 176, 15, 140, 193, 88, 136, 70, + 225, 44, 68, 35, 241, 22, 34, 146, 249, 11, 17, 73, 253, 134, 137, 165, 255, 67, 197, 211, + 256, 162, 227, 234, 128, 81, 242, 117, 64, 169, 121, 187, 32, 213, 189, 222, 16, 235, 223, + 111, 8, 246, 240, 184, 4, 123, 120, 92, 2, 190, 60, 46, 1, 95, 30, 23, 129, 176, 15, 140, + 193, 88, 136, 70, 225, 44, 68, 35, 241, 22, 34, 146, 249, 11, 17, 73, 253, 134, 137, 165, + 255, 67, 197, 211, 256, 162, 227, 234, 128, 81, 242, 117, 64, 169, 121, 187, 32, 213, 189, + 222, 16, 235, 223, 111, 8, 246, 240, 184, 4, 123, 120, 92, 2, 190, 60, 46, 1, + ], + [ + 1, 96, 221, 142, 11, 28, 118, 20, 121, 51, 13, 220, 46, 47, 143, 107, 249, 3, 31, 149, 169, + 33, 84, 97, 60, 106, 153, 39, 146, 138, 141, 172, 64, 233, 9, 93, 190, 250, 99, 252, 34, + 180, 61, 202, 117, 181, 157, 166, 2, 192, 185, 27, 22, 56, 236, 40, 242, 102, 26, 183, 92, + 94, 29, 214, 241, 6, 62, 41, 81, 66, 168, 194, 120, 212, 49, 78, 35, 19, 25, 87, 128, 209, + 18, 186, 123, 243, 198, 247, 68, 103, 122, 147, 234, 105, 57, 75, 4, 127, 113, 54, 44, 112, + 215, 80, 227, 204, 52, 109, 184, 188, 58, 171, 225, 12, 124, 82, 162, 132, 79, 131, 240, + 167, 98, 156, 70, 38, 50, 174, 256, 161, 36, 115, 246, 229, 139, 237, 136, 206, 244, 37, + 211, 210, 114, 150, 8, 254, 226, 108, 88, 224, 173, 160, 197, 151, 104, 218, 111, 119, 116, + 85, 193, 24, 248, 164, 67, 7, 158, 5, 223, 77, 196, 55, 140, 76, 100, 91, 255, 65, 72, 230, + 235, 201, 21, 217, 15, 155, 231, 74, 165, 163, 228, 43, 16, 251, 195, 216, 176, 191, 89, 63, + 137, 45, 208, 179, 222, 238, 232, 170, 129, 48, 239, 71, 134, 14, 59, 10, 189, 154, 135, + 110, 23, 152, 200, 182, 253, 130, 144, 203, 213, 145, 42, 177, 30, 53, 205, 148, 73, 69, + 199, 86, 32, 245, 133, 175, 95, 125, 178, 126, 17, 90, 159, 101, 187, 219, 207, 83, 1, + ], + [ + 1, 97, 157, 66, 234, 82, 244, 24, 15, 170, 42, 219, 169, 202, 62, 103, 225, 237, 116, 201, + 222, 203, 159, 3, 34, 214, 198, 188, 246, 218, 72, 45, 253, 126, 143, 250, 92, 186, 52, 161, + 197, 91, 89, 152, 95, 220, 9, 102, 128, 80, 50, 224, 140, 216, 135, 245, 121, 172, 236, 19, + 44, 156, 226, 77, 16, 10, 199, 28, 146, 27, 49, 127, 240, 150, 158, 163, 134, 148, 221, 106, + 2, 194, 57, 132, 211, 164, 231, 48, 30, 83, 84, 181, 81, 147, 124, 206, 193, 217, 232, 145, + 187, 149, 61, 6, 68, 171, 139, 119, 235, 179, 144, 90, 249, 252, 29, 243, 184, 115, 104, 65, + 137, 182, 178, 47, 190, 183, 18, 204, 256, 160, 100, 191, 23, 175, 13, 233, 242, 87, 215, + 38, 88, 55, 195, 154, 32, 20, 141, 56, 35, 54, 98, 254, 223, 43, 59, 69, 11, 39, 185, 212, + 4, 131, 114, 7, 165, 71, 205, 96, 60, 166, 168, 105, 162, 37, 248, 155, 129, 177, 207, 33, + 117, 41, 122, 12, 136, 85, 21, 238, 213, 101, 31, 180, 241, 247, 58, 229, 111, 230, 208, + 130, 17, 107, 99, 94, 123, 109, 36, 151, 255, 63, 200, 125, 46, 93, 26, 209, 227, 174, 173, + 76, 176, 110, 133, 51, 64, 40, 25, 112, 70, 108, 196, 251, 189, 86, 118, 138, 22, 78, 113, + 167, 8, 5, 228, 14, 73, 142, 153, 192, 120, 75, 79, 210, 67, 74, 239, 53, 1, + ], + [ + 1, 98, 95, 58, 30, 113, 23, 198, 129, 49, 176, 29, 15, 185, 140, 99, 193, 153, 88, 143, 136, + 221, 70, 178, 225, 205, 44, 200, 68, 239, 35, 89, 241, 231, 22, 100, 34, 248, 146, 173, 249, + 244, 11, 50, 17, 124, 73, 215, 253, 122, 134, 25, 137, 62, 165, 236, 255, 61, 67, 141, 197, + 31, 211, 118, 256, 159, 162, 199, 227, 144, 234, 59, 128, 208, 81, 228, 242, 72, 117, 158, + 64, 104, 169, 114, 121, 36, 187, 79, 32, 52, 213, 57, 189, 18, 222, 168, 16, 26, 235, 157, + 223, 9, 111, 84, 8, 13, 246, 207, 240, 133, 184, 42, 4, 135, 123, 232, 120, 195, 92, 21, 2, + 196, 190, 116, 60, 226, 46, 139, 1, 98, 95, 58, 30, 113, 23, 198, 129, 49, 176, 29, 15, 185, + 140, 99, 193, 153, 88, 143, 136, 221, 70, 178, 225, 205, 44, 200, 68, 239, 35, 89, 241, 231, + 22, 100, 34, 248, 146, 173, 249, 244, 11, 50, 17, 124, 73, 215, 253, 122, 134, 25, 137, 62, + 165, 236, 255, 61, 67, 141, 197, 31, 211, 118, 256, 159, 162, 199, 227, 144, 234, 59, 128, + 208, 81, 228, 242, 72, 117, 158, 64, 104, 169, 114, 121, 36, 187, 79, 32, 52, 213, 57, 189, + 18, 222, 168, 16, 26, 235, 157, 223, 9, 111, 84, 8, 13, 246, 207, 240, 133, 184, 42, 4, 135, + 123, 232, 120, 195, 92, 21, 2, 196, 190, 116, 60, 226, 46, 139, 1, + ], + [ + 1, 99, 35, 124, 197, 228, 213, 13, 2, 198, 70, 248, 137, 199, 169, 26, 4, 139, 140, 239, 17, + 141, 81, 52, 8, 21, 23, 221, 34, 25, 162, 104, 16, 42, 46, 185, 68, 50, 67, 208, 32, 84, 92, + 113, 136, 100, 134, 159, 64, 168, 184, 226, 15, 200, 11, 61, 128, 79, 111, 195, 30, 143, 22, + 122, 256, 158, 222, 133, 60, 29, 44, 244, 255, 59, 187, 9, 120, 58, 88, 231, 253, 118, 117, + 18, 240, 116, 176, 205, 249, 236, 234, 36, 223, 232, 95, 153, 241, 215, 211, 72, 189, 207, + 190, 49, 225, 173, 165, 144, 121, 157, 123, 98, 193, 89, 73, 31, 242, 57, 246, 196, 129, + 178, 146, 62, 227, 114, 235, 135, 1, 99, 35, 124, 197, 228, 213, 13, 2, 198, 70, 248, 137, + 199, 169, 26, 4, 139, 140, 239, 17, 141, 81, 52, 8, 21, 23, 221, 34, 25, 162, 104, 16, 42, + 46, 185, 68, 50, 67, 208, 32, 84, 92, 113, 136, 100, 134, 159, 64, 168, 184, 226, 15, 200, + 11, 61, 128, 79, 111, 195, 30, 143, 22, 122, 256, 158, 222, 133, 60, 29, 44, 244, 255, 59, + 187, 9, 120, 58, 88, 231, 253, 118, 117, 18, 240, 116, 176, 205, 249, 236, 234, 36, 223, + 232, 95, 153, 241, 215, 211, 72, 189, 207, 190, 49, 225, 173, 165, 144, 121, 157, 123, 98, + 193, 89, 73, 31, 242, 57, 246, 196, 129, 178, 146, 62, 227, 114, 235, 135, 1, + ], + [ + 1, 100, 234, 13, 15, 215, 169, 195, 225, 141, 222, 98, 34, 59, 246, 185, 253, 114, 92, 205, + 197, 168, 95, 248, 128, 207, 140, 122, 121, 21, 44, 31, 16, 58, 146, 208, 240, 99, 134, 36, + 2, 200, 211, 26, 30, 173, 81, 133, 193, 25, 187, 196, 68, 118, 235, 113, 249, 228, 184, 153, + 137, 79, 190, 239, 256, 157, 23, 244, 242, 42, 88, 62, 32, 116, 35, 159, 223, 198, 11, 72, + 4, 143, 165, 52, 60, 89, 162, 9, 129, 50, 117, 135, 136, 236, 213, 226, 241, 199, 111, 49, + 17, 158, 123, 221, 255, 57, 46, 231, 227, 84, 176, 124, 64, 232, 70, 61, 189, 139, 22, 144, + 8, 29, 73, 104, 120, 178, 67, 18, 1, 100, 234, 13, 15, 215, 169, 195, 225, 141, 222, 98, 34, + 59, 246, 185, 253, 114, 92, 205, 197, 168, 95, 248, 128, 207, 140, 122, 121, 21, 44, 31, 16, + 58, 146, 208, 240, 99, 134, 36, 2, 200, 211, 26, 30, 173, 81, 133, 193, 25, 187, 196, 68, + 118, 235, 113, 249, 228, 184, 153, 137, 79, 190, 239, 256, 157, 23, 244, 242, 42, 88, 62, + 32, 116, 35, 159, 223, 198, 11, 72, 4, 143, 165, 52, 60, 89, 162, 9, 129, 50, 117, 135, 136, + 236, 213, 226, 241, 199, 111, 49, 17, 158, 123, 221, 255, 57, 46, 231, 227, 84, 176, 124, + 64, 232, 70, 61, 189, 139, 22, 144, 8, 29, 73, 104, 120, 178, 67, 18, 1, + ], + [ + 1, 101, 178, 245, 73, 177, 144, 152, 189, 71, 232, 45, 176, 43, 231, 201, 255, 55, 158, 24, + 111, 160, 226, 210, 136, 115, 50, 167, 162, 171, 52, 112, 4, 147, 198, 209, 35, 194, 62, 94, + 242, 27, 157, 180, 190, 172, 153, 33, 249, 220, 118, 96, 187, 126, 133, 69, 30, 203, 200, + 154, 134, 170, 208, 191, 16, 74, 21, 65, 140, 5, 248, 119, 197, 108, 114, 206, 246, 174, 98, + 132, 225, 109, 215, 127, 234, 247, 18, 19, 120, 41, 29, 102, 22, 166, 61, 250, 64, 39, 84, + 3, 46, 20, 221, 219, 17, 175, 199, 53, 213, 182, 135, 14, 129, 179, 89, 251, 165, 217, 72, + 76, 223, 164, 116, 151, 88, 150, 244, 229, 256, 156, 79, 12, 184, 80, 113, 105, 68, 186, 25, + 212, 81, 214, 26, 56, 2, 202, 99, 233, 146, 97, 31, 47, 121, 142, 207, 90, 95, 86, 205, 145, + 253, 110, 59, 48, 222, 63, 195, 163, 15, 230, 100, 77, 67, 85, 104, 224, 8, 37, 139, 161, + 70, 131, 124, 188, 227, 54, 57, 103, 123, 87, 49, 66, 241, 183, 236, 192, 117, 252, 9, 138, + 60, 149, 143, 51, 11, 83, 159, 125, 32, 148, 42, 130, 23, 10, 239, 238, 137, 216, 228, 155, + 235, 91, 196, 7, 193, 218, 173, 254, 211, 237, 36, 38, 240, 82, 58, 204, 44, 75, 122, 243, + 128, 78, 168, 6, 92, 40, 185, 181, 34, 93, 141, 106, 169, 107, 13, 28, 1, + ], + [ + 1, 102, 124, 55, 213, 138, 198, 150, 137, 96, 26, 82, 140, 145, 141, 247, 8, 45, 221, 183, + 162, 76, 42, 172, 68, 254, 208, 142, 92, 132, 100, 177, 64, 103, 226, 179, 11, 94, 79, 91, + 30, 233, 122, 108, 222, 28, 29, 131, 255, 53, 9, 147, 88, 238, 118, 214, 240, 65, 205, 93, + 234, 224, 232, 20, 241, 167, 72, 148, 190, 105, 173, 170, 121, 6, 98, 230, 73, 250, 57, 160, + 129, 51, 62, 156, 235, 69, 99, 75, 197, 48, 13, 41, 70, 201, 199, 252, 4, 151, 239, 220, 81, + 38, 21, 86, 34, 127, 104, 71, 46, 66, 50, 217, 32, 180, 113, 218, 134, 47, 168, 174, 15, + 245, 61, 54, 111, 14, 143, 194, 256, 155, 133, 202, 44, 119, 59, 107, 120, 161, 231, 175, + 117, 112, 116, 10, 249, 212, 36, 74, 95, 181, 215, 85, 189, 3, 49, 115, 165, 125, 157, 80, + 193, 154, 31, 78, 246, 163, 178, 166, 227, 24, 135, 149, 35, 229, 228, 126, 2, 204, 248, + 110, 169, 19, 139, 43, 17, 192, 52, 164, 23, 33, 25, 237, 16, 90, 185, 109, 67, 152, 84, 87, + 136, 251, 159, 27, 184, 7, 200, 97, 128, 206, 195, 101, 22, 188, 158, 182, 60, 209, 244, + 216, 187, 56, 58, 5, 253, 106, 18, 37, 176, 219, 236, 171, 223, 130, 153, 186, 211, 191, + 207, 40, 225, 77, 144, 39, 123, 210, 89, 83, 242, 12, 196, 203, 146, 243, 114, 63, 1, + ], + [ + 1, 103, 72, 220, 44, 163, 84, 171, 137, 233, 98, 71, 117, 229, 200, 40, 8, 53, 62, 218, 95, + 19, 158, 83, 68, 65, 13, 54, 165, 33, 58, 63, 64, 167, 239, 202, 246, 152, 236, 150, 30, 6, + 104, 175, 35, 7, 207, 247, 255, 51, 113, 74, 169, 188, 89, 172, 240, 48, 61, 115, 23, 56, + 114, 177, 241, 151, 133, 78, 67, 219, 198, 91, 121, 127, 231, 149, 184, 191, 141, 131, 129, + 180, 36, 110, 22, 210, 42, 214, 197, 245, 49, 164, 187, 243, 100, 20, 4, 155, 31, 109, 176, + 138, 79, 170, 34, 161, 135, 27, 211, 145, 29, 160, 32, 212, 248, 101, 123, 76, 118, 75, 15, + 3, 52, 216, 146, 132, 232, 252, 256, 154, 185, 37, 213, 94, 173, 86, 120, 24, 159, 186, 140, + 28, 57, 217, 249, 204, 195, 39, 162, 238, 99, 174, 189, 192, 244, 203, 92, 224, 199, 194, + 193, 90, 18, 55, 11, 105, 21, 107, 227, 251, 153, 82, 222, 250, 50, 10, 2, 206, 144, 183, + 88, 69, 168, 85, 17, 209, 196, 142, 234, 201, 143, 80, 16, 106, 124, 179, 190, 38, 59, 166, + 136, 130, 26, 108, 73, 66, 116, 126, 128, 77, 221, 147, 235, 47, 215, 43, 60, 12, 208, 93, + 70, 14, 157, 237, 253, 102, 226, 148, 81, 119, 178, 87, 223, 96, 122, 230, 46, 112, 228, 97, + 225, 45, 9, 156, 134, 181, 139, 182, 242, 254, 205, 41, 111, 125, 25, 5, 1, + ], + [ + 1, 104, 22, 232, 227, 221, 111, 236, 129, 52, 11, 116, 242, 239, 184, 118, 193, 26, 134, 58, + 121, 248, 92, 59, 225, 13, 67, 29, 189, 124, 46, 158, 241, 135, 162, 143, 223, 62, 23, 79, + 249, 196, 81, 200, 240, 31, 140, 168, 253, 98, 169, 100, 120, 144, 70, 84, 255, 49, 213, 50, + 60, 72, 35, 42, 256, 153, 235, 25, 30, 36, 146, 21, 128, 205, 246, 141, 15, 18, 73, 139, 64, + 231, 123, 199, 136, 9, 165, 198, 32, 244, 190, 228, 68, 133, 211, 99, 16, 122, 95, 114, 34, + 195, 234, 178, 8, 61, 176, 57, 17, 226, 117, 89, 4, 159, 88, 157, 137, 113, 187, 173, 2, + 208, 44, 207, 197, 185, 222, 215, 1, 104, 22, 232, 227, 221, 111, 236, 129, 52, 11, 116, + 242, 239, 184, 118, 193, 26, 134, 58, 121, 248, 92, 59, 225, 13, 67, 29, 189, 124, 46, 158, + 241, 135, 162, 143, 223, 62, 23, 79, 249, 196, 81, 200, 240, 31, 140, 168, 253, 98, 169, + 100, 120, 144, 70, 84, 255, 49, 213, 50, 60, 72, 35, 42, 256, 153, 235, 25, 30, 36, 146, 21, + 128, 205, 246, 141, 15, 18, 73, 139, 64, 231, 123, 199, 136, 9, 165, 198, 32, 244, 190, 228, + 68, 133, 211, 99, 16, 122, 95, 114, 34, 195, 234, 178, 8, 61, 176, 57, 17, 226, 117, 89, 4, + 159, 88, 157, 137, 113, 187, 173, 2, 208, 44, 207, 197, 185, 222, 215, 1, + ], + [ + 1, 105, 231, 97, 162, 48, 157, 37, 30, 66, 248, 83, 234, 155, 84, 82, 129, 181, 244, 177, + 81, 24, 207, 147, 15, 33, 124, 170, 117, 206, 42, 41, 193, 219, 122, 217, 169, 12, 232, 202, + 136, 145, 62, 85, 187, 103, 21, 149, 225, 238, 61, 237, 213, 6, 116, 101, 68, 201, 31, 171, + 222, 180, 139, 203, 241, 119, 159, 247, 235, 3, 58, 179, 34, 229, 144, 214, 111, 90, 198, + 230, 249, 188, 208, 252, 246, 130, 29, 218, 17, 243, 72, 107, 184, 45, 99, 115, 253, 94, + 104, 126, 123, 65, 143, 109, 137, 250, 36, 182, 92, 151, 178, 186, 255, 47, 52, 63, 190, + 161, 200, 183, 197, 125, 18, 91, 46, 204, 89, 93, 256, 152, 26, 160, 95, 209, 100, 220, 227, + 191, 9, 174, 23, 102, 173, 175, 128, 76, 13, 80, 176, 233, 50, 110, 242, 224, 133, 87, 140, + 51, 215, 216, 64, 38, 135, 40, 88, 245, 25, 55, 121, 112, 195, 172, 70, 154, 236, 108, 32, + 19, 196, 20, 44, 251, 141, 156, 189, 56, 226, 86, 35, 77, 118, 54, 16, 138, 98, 10, 22, 254, + 199, 78, 223, 28, 113, 43, 146, 167, 59, 27, 8, 69, 49, 5, 11, 127, 228, 39, 240, 14, 185, + 150, 73, 212, 158, 142, 4, 163, 153, 131, 134, 192, 114, 148, 120, 7, 221, 75, 165, 106, 79, + 71, 2, 210, 205, 194, 67, 96, 57, 74, 60, 132, 239, 166, 211, 53, 168, 164, 1, + ], + [ + 1, 106, 185, 78, 44, 38, 173, 91, 137, 130, 159, 149, 117, 66, 57, 131, 8, 77, 195, 110, 95, + 47, 99, 214, 68, 12, 244, 164, 165, 14, 199, 20, 64, 102, 18, 109, 246, 119, 21, 170, 30, + 96, 153, 27, 35, 112, 50, 160, 255, 45, 144, 101, 169, 181, 168, 75, 240, 254, 196, 216, 23, + 125, 143, 252, 241, 103, 124, 37, 67, 163, 59, 86, 121, 233, 26, 186, 184, 229, 116, 217, + 129, 53, 221, 39, 22, 19, 215, 174, 197, 65, 208, 203, 187, 33, 157, 194, 4, 167, 226, 55, + 176, 152, 178, 107, 34, 6, 122, 82, 211, 7, 228, 10, 32, 51, 9, 183, 123, 188, 139, 85, 15, + 48, 205, 142, 146, 56, 25, 80, 256, 151, 72, 179, 213, 219, 84, 166, 120, 127, 98, 108, 140, + 191, 200, 126, 249, 180, 62, 147, 162, 210, 158, 43, 189, 245, 13, 93, 92, 243, 58, 237, + 193, 155, 239, 148, 11, 138, 236, 87, 227, 161, 104, 230, 222, 145, 207, 97, 2, 212, 113, + 156, 88, 76, 89, 182, 17, 3, 61, 41, 234, 132, 114, 5, 16, 154, 133, 220, 190, 94, 198, 171, + 136, 24, 231, 71, 73, 28, 141, 40, 128, 204, 36, 218, 235, 238, 42, 83, 60, 192, 49, 54, 70, + 224, 100, 63, 253, 90, 31, 202, 81, 105, 79, 150, 223, 251, 135, 175, 46, 250, 29, 247, 225, + 206, 248, 74, 134, 69, 118, 172, 242, 209, 52, 115, 111, 201, 232, 177, 1, + ], + [ + 1, 107, 141, 181, 92, 78, 122, 204, 240, 237, 173, 7, 235, 216, 239, 130, 32, 83, 143, 138, + 117, 183, 49, 103, 227, 131, 139, 224, 67, 230, 195, 48, 253, 86, 207, 47, 146, 202, 26, + 212, 68, 80, 79, 229, 88, 164, 72, 251, 129, 182, 199, 219, 46, 39, 61, 102, 120, 247, 215, + 132, 246, 108, 248, 65, 16, 170, 200, 69, 187, 220, 153, 180, 242, 194, 198, 112, 162, 115, + 226, 24, 255, 43, 232, 152, 73, 101, 13, 106, 34, 40, 168, 243, 44, 82, 36, 254, 193, 91, + 228, 238, 23, 148, 159, 51, 60, 252, 236, 66, 123, 54, 124, 161, 8, 85, 100, 163, 222, 110, + 205, 90, 121, 97, 99, 56, 81, 186, 113, 12, 256, 150, 116, 76, 165, 179, 135, 53, 17, 20, + 84, 250, 22, 41, 18, 127, 225, 174, 114, 119, 140, 74, 208, 154, 30, 126, 118, 33, 190, 27, + 62, 209, 4, 171, 50, 210, 111, 55, 231, 45, 189, 177, 178, 28, 169, 93, 185, 6, 128, 75, 58, + 38, 211, 218, 196, 155, 137, 10, 42, 125, 11, 149, 9, 192, 241, 87, 57, 188, 70, 37, 104, + 77, 15, 63, 59, 145, 95, 142, 31, 233, 2, 214, 25, 105, 184, 156, 244, 151, 223, 217, 89, + 14, 213, 175, 221, 3, 64, 166, 29, 19, 234, 109, 98, 206, 197, 5, 21, 191, 134, 203, 133, + 96, 249, 172, 157, 94, 35, 147, 52, 167, 136, 160, 158, 201, 176, 71, 144, 245, 1, + ], + [ + 1, 108, 99, 155, 35, 182, 124, 28, 197, 202, 228, 209, 213, 131, 13, 119, 2, 216, 198, 53, + 70, 107, 248, 56, 137, 147, 199, 161, 169, 5, 26, 238, 4, 175, 139, 106, 140, 214, 239, 112, + 17, 37, 141, 65, 81, 10, 52, 219, 8, 93, 21, 212, 23, 171, 221, 224, 34, 74, 25, 130, 162, + 20, 104, 181, 16, 186, 42, 167, 46, 85, 185, 191, 68, 148, 50, 3, 67, 40, 208, 105, 32, 115, + 84, 77, 92, 170, 113, 125, 136, 39, 100, 6, 134, 80, 159, 210, 64, 230, 168, 154, 184, 83, + 226, 250, 15, 78, 200, 12, 11, 160, 61, 163, 128, 203, 79, 51, 111, 166, 195, 243, 30, 156, + 143, 24, 22, 63, 122, 69, 256, 149, 158, 102, 222, 75, 133, 229, 60, 55, 29, 48, 44, 126, + 244, 138, 255, 41, 59, 204, 187, 150, 9, 201, 120, 110, 58, 96, 88, 252, 231, 19, 253, 82, + 118, 151, 117, 43, 18, 145, 240, 220, 116, 192, 176, 247, 205, 38, 249, 164, 236, 45, 234, + 86, 36, 33, 223, 183, 232, 127, 95, 237, 153, 76, 241, 71, 215, 90, 211, 172, 72, 66, 189, + 109, 207, 254, 190, 217, 49, 152, 225, 142, 173, 180, 165, 87, 144, 132, 121, 218, 157, 251, + 123, 177, 98, 47, 193, 27, 89, 103, 73, 174, 31, 7, 242, 179, 57, 245, 246, 97, 196, 94, + 129, 54, 178, 206, 146, 91, 62, 14, 227, 101, 114, 233, 235, 194, 135, 188, 1, + ], + [ + 1, 109, 59, 6, 140, 97, 36, 69, 68, 216, 157, 151, 11, 171, 135, 66, 255, 39, 139, 245, 234, + 63, 185, 119, 121, 82, 200, 212, 235, 172, 244, 125, 4, 179, 236, 24, 46, 131, 144, 19, 15, + 93, 114, 90, 44, 170, 26, 7, 249, 156, 42, 209, 165, 252, 226, 219, 227, 71, 29, 77, 169, + 174, 205, 243, 16, 202, 173, 96, 184, 10, 62, 76, 60, 115, 199, 103, 176, 166, 104, 28, 225, + 110, 168, 65, 146, 237, 133, 105, 137, 27, 116, 51, 162, 182, 49, 201, 64, 37, 178, 127, + 222, 40, 248, 47, 240, 203, 25, 155, 190, 150, 159, 112, 129, 183, 158, 3, 70, 177, 18, 163, + 34, 108, 207, 204, 134, 214, 196, 33, 256, 148, 198, 251, 117, 160, 221, 188, 189, 41, 100, + 106, 246, 86, 122, 191, 2, 218, 118, 12, 23, 194, 72, 138, 136, 175, 57, 45, 22, 85, 13, + 132, 253, 78, 21, 233, 211, 126, 113, 238, 242, 164, 143, 167, 213, 87, 231, 250, 8, 101, + 215, 48, 92, 5, 31, 38, 30, 186, 228, 180, 88, 83, 52, 14, 241, 55, 84, 161, 73, 247, 195, + 181, 197, 142, 58, 154, 81, 91, 153, 229, 32, 147, 89, 192, 111, 20, 124, 152, 120, 230, + 141, 206, 95, 75, 208, 56, 193, 220, 79, 130, 35, 217, 9, 210, 17, 54, 232, 102, 67, 107, + 98, 145, 128, 74, 99, 254, 187, 80, 239, 94, 223, 149, 50, 53, 123, 43, 61, 224, 1, + ], + [ + 1, 110, 21, 254, 184, 194, 9, 219, 189, 230, 114, 204, 81, 172, 159, 14, 255, 37, 215, 6, + 146, 126, 239, 76, 136, 54, 29, 106, 95, 170, 196, 229, 4, 183, 84, 245, 222, 5, 36, 105, + 242, 149, 199, 45, 67, 174, 122, 56, 249, 148, 89, 24, 70, 247, 185, 47, 30, 216, 116, 167, + 123, 166, 13, 145, 16, 218, 79, 209, 117, 20, 144, 163, 197, 82, 25, 180, 11, 182, 231, 224, + 225, 78, 99, 96, 23, 217, 226, 188, 120, 93, 207, 154, 235, 150, 52, 66, 64, 101, 59, 65, + 211, 80, 62, 138, 17, 71, 100, 206, 44, 214, 153, 125, 129, 55, 139, 127, 92, 97, 133, 238, + 223, 115, 57, 102, 169, 86, 208, 7, 256, 147, 236, 3, 73, 63, 248, 38, 68, 27, 143, 53, 176, + 85, 98, 243, 2, 220, 42, 251, 111, 131, 18, 181, 121, 203, 228, 151, 162, 87, 61, 28, 253, + 74, 173, 12, 35, 252, 221, 152, 15, 108, 58, 212, 190, 83, 135, 201, 8, 109, 168, 233, 187, + 10, 72, 210, 227, 41, 141, 90, 134, 91, 244, 112, 241, 39, 178, 48, 140, 237, 113, 94, 60, + 175, 232, 77, 246, 75, 26, 33, 32, 179, 158, 161, 234, 40, 31, 69, 137, 164, 50, 103, 22, + 107, 205, 191, 193, 156, 198, 192, 46, 177, 195, 119, 240, 186, 157, 51, 213, 43, 104, 132, + 128, 202, 118, 130, 165, 160, 124, 19, 34, 142, 200, 155, 88, 171, 49, 250, 1, + ], + [ + 1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, 235, 128, 73, 136, 190, 16, 234, 17, 88, 2, + 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, 213, 256, 146, 15, 123, 32, 211, 34, 176, 4, + 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, 169, 255, 35, 30, 246, 64, 165, 68, 95, 8, + 117, 137, 44, 1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, 235, 128, 73, 136, 190, 16, + 234, 17, 88, 2, 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, 213, 256, 146, 15, 123, 32, + 211, 34, 176, 4, 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, 169, 255, 35, 30, 246, 64, + 165, 68, 95, 8, 117, 137, 44, 1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, 235, 128, 73, + 136, 190, 16, 234, 17, 88, 2, 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, 213, 256, 146, + 15, 123, 32, 211, 34, 176, 4, 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, 169, 255, 35, + 30, 246, 64, 165, 68, 95, 8, 117, 137, 44, 1, 111, 242, 134, 225, 46, 223, 81, 253, 70, 60, + 235, 128, 73, 136, 190, 16, 234, 17, 88, 2, 222, 227, 11, 193, 92, 189, 162, 249, 140, 120, + 213, 256, 146, 15, 123, 32, 211, 34, 176, 4, 187, 197, 22, 129, 184, 121, 67, 241, 23, 240, + 169, 255, 35, 30, 246, 64, 165, 68, 95, 8, 117, 137, 44, 1, + ], + [ + 1, 112, 208, 166, 88, 90, 57, 216, 34, 210, 133, 247, 165, 233, 139, 148, 128, 201, 153, + 174, 213, 212, 100, 149, 240, 152, 62, 5, 46, 12, 59, 183, 193, 28, 52, 170, 22, 151, 207, + 54, 137, 181, 226, 126, 234, 251, 99, 37, 32, 243, 231, 172, 246, 53, 25, 230, 60, 38, 144, + 194, 140, 3, 79, 110, 241, 7, 13, 171, 134, 102, 116, 142, 227, 238, 185, 160, 187, 127, 89, + 202, 8, 125, 122, 43, 190, 206, 199, 186, 15, 138, 36, 177, 35, 65, 84, 156, 253, 66, 196, + 107, 162, 154, 29, 164, 121, 188, 239, 40, 111, 96, 215, 179, 2, 224, 159, 75, 176, 180, + 114, 175, 68, 163, 9, 237, 73, 209, 21, 39, 256, 145, 49, 91, 169, 167, 200, 41, 223, 47, + 124, 10, 92, 24, 118, 109, 129, 56, 104, 83, 44, 45, 157, 108, 17, 105, 195, 252, 211, 245, + 198, 74, 64, 229, 205, 87, 235, 106, 50, 203, 120, 76, 31, 131, 23, 6, 158, 220, 225, 14, + 26, 85, 11, 204, 232, 27, 197, 219, 113, 63, 117, 254, 178, 147, 16, 250, 244, 86, 123, 155, + 141, 115, 30, 19, 72, 97, 70, 130, 168, 55, 249, 132, 135, 214, 67, 51, 58, 71, 242, 119, + 221, 80, 222, 192, 173, 101, 4, 191, 61, 150, 95, 103, 228, 93, 136, 69, 18, 217, 146, 161, + 42, 78, 255, 33, 98, 182, 81, 77, 143, 82, 189, 94, 248, 20, 184, 48, 236, 218, 1, + ], + [ + 1, 113, 176, 99, 136, 205, 35, 100, 249, 124, 134, 236, 197, 159, 234, 228, 64, 36, 213, + 168, 223, 13, 184, 232, 2, 226, 95, 198, 15, 153, 70, 200, 241, 248, 11, 215, 137, 61, 211, + 199, 128, 72, 169, 79, 189, 26, 111, 207, 4, 195, 190, 139, 30, 49, 140, 143, 225, 239, 22, + 173, 17, 122, 165, 141, 256, 144, 81, 158, 121, 52, 222, 157, 8, 133, 123, 21, 60, 98, 23, + 29, 193, 221, 44, 89, 34, 244, 73, 25, 255, 31, 162, 59, 242, 104, 187, 57, 16, 9, 246, 42, + 120, 196, 46, 58, 129, 185, 88, 178, 68, 231, 146, 50, 253, 62, 67, 118, 227, 208, 117, 114, + 32, 18, 235, 84, 240, 135, 92, 116, 1, 113, 176, 99, 136, 205, 35, 100, 249, 124, 134, 236, + 197, 159, 234, 228, 64, 36, 213, 168, 223, 13, 184, 232, 2, 226, 95, 198, 15, 153, 70, 200, + 241, 248, 11, 215, 137, 61, 211, 199, 128, 72, 169, 79, 189, 26, 111, 207, 4, 195, 190, 139, + 30, 49, 140, 143, 225, 239, 22, 173, 17, 122, 165, 141, 256, 144, 81, 158, 121, 52, 222, + 157, 8, 133, 123, 21, 60, 98, 23, 29, 193, 221, 44, 89, 34, 244, 73, 25, 255, 31, 162, 59, + 242, 104, 187, 57, 16, 9, 246, 42, 120, 196, 46, 58, 129, 185, 88, 178, 68, 231, 146, 50, + 253, 62, 67, 118, 227, 208, 117, 114, 32, 18, 235, 84, 240, 135, 92, 116, 1, + ], + [ + 1, 114, 146, 196, 242, 89, 123, 144, 225, 207, 211, 153, 223, 236, 176, 18, 253, 58, 187, + 244, 60, 158, 22, 195, 128, 200, 184, 159, 136, 84, 67, 185, 16, 25, 23, 52, 17, 139, 169, + 248, 2, 228, 35, 135, 227, 178, 246, 31, 193, 157, 165, 49, 189, 215, 95, 36, 249, 116, 117, + 231, 120, 59, 44, 133, 256, 143, 111, 61, 15, 168, 134, 113, 32, 50, 46, 104, 34, 21, 81, + 239, 4, 199, 70, 13, 197, 99, 235, 62, 129, 57, 73, 98, 121, 173, 190, 72, 241, 232, 234, + 205, 240, 118, 88, 9, 255, 29, 222, 122, 30, 79, 11, 226, 64, 100, 92, 208, 68, 42, 162, + 221, 8, 141, 140, 26, 137, 198, 213, 124, 1, 114, 146, 196, 242, 89, 123, 144, 225, 207, + 211, 153, 223, 236, 176, 18, 253, 58, 187, 244, 60, 158, 22, 195, 128, 200, 184, 159, 136, + 84, 67, 185, 16, 25, 23, 52, 17, 139, 169, 248, 2, 228, 35, 135, 227, 178, 246, 31, 193, + 157, 165, 49, 189, 215, 95, 36, 249, 116, 117, 231, 120, 59, 44, 133, 256, 143, 111, 61, 15, + 168, 134, 113, 32, 50, 46, 104, 34, 21, 81, 239, 4, 199, 70, 13, 197, 99, 235, 62, 129, 57, + 73, 98, 121, 173, 190, 72, 241, 232, 234, 205, 240, 118, 88, 9, 255, 29, 222, 122, 30, 79, + 11, 226, 64, 100, 92, 208, 68, 42, 162, 221, 8, 141, 140, 26, 137, 198, 213, 124, 1, + ], + [ + 1, 115, 118, 206, 46, 150, 31, 224, 60, 218, 141, 24, 190, 5, 61, 76, 2, 230, 236, 155, 92, + 43, 62, 191, 120, 179, 25, 48, 123, 10, 122, 152, 4, 203, 215, 53, 184, 86, 124, 125, 240, + 101, 50, 96, 246, 20, 244, 47, 8, 149, 173, 106, 111, 172, 248, 250, 223, 202, 100, 192, + 235, 40, 231, 94, 16, 41, 89, 212, 222, 87, 239, 243, 189, 147, 200, 127, 213, 80, 205, 188, + 32, 82, 178, 167, 187, 174, 221, 229, 121, 37, 143, 254, 169, 160, 153, 119, 64, 164, 99, + 77, 117, 91, 185, 201, 242, 74, 29, 251, 81, 63, 49, 238, 128, 71, 198, 154, 234, 182, 113, + 145, 227, 148, 58, 245, 162, 126, 98, 219, 256, 142, 139, 51, 211, 107, 226, 33, 197, 39, + 116, 233, 67, 252, 196, 181, 255, 27, 21, 102, 165, 214, 195, 66, 137, 78, 232, 209, 134, + 247, 135, 105, 253, 54, 42, 204, 73, 171, 133, 132, 17, 156, 207, 161, 11, 237, 13, 210, + 249, 108, 84, 151, 146, 85, 9, 7, 34, 55, 157, 65, 22, 217, 26, 163, 241, 216, 168, 45, 35, + 170, 18, 14, 68, 110, 57, 130, 44, 177, 52, 69, 225, 175, 79, 90, 70, 83, 36, 28, 136, 220, + 114, 3, 88, 97, 104, 138, 193, 93, 158, 180, 140, 166, 72, 56, 15, 183, 228, 6, 176, 194, + 208, 19, 129, 186, 59, 103, 23, 75, 144, 112, 30, 109, 199, 12, 95, 131, 159, 38, 1, + ], + [ + 1, 116, 92, 135, 240, 84, 235, 18, 32, 114, 117, 208, 227, 118, 67, 62, 253, 50, 146, 231, + 68, 178, 88, 185, 129, 58, 46, 196, 120, 42, 246, 9, 16, 57, 187, 104, 242, 59, 162, 31, + 255, 25, 73, 244, 34, 89, 44, 221, 193, 29, 23, 98, 60, 21, 123, 133, 8, 157, 222, 52, 121, + 158, 81, 144, 256, 141, 165, 122, 17, 173, 22, 239, 225, 143, 140, 49, 30, 139, 190, 195, 4, + 207, 111, 26, 189, 79, 169, 72, 128, 199, 211, 61, 137, 215, 11, 248, 241, 200, 70, 153, 15, + 198, 95, 226, 2, 232, 184, 13, 223, 168, 213, 36, 64, 228, 234, 159, 197, 236, 134, 124, + 249, 100, 35, 205, 136, 99, 176, 113, 1, 116, 92, 135, 240, 84, 235, 18, 32, 114, 117, 208, + 227, 118, 67, 62, 253, 50, 146, 231, 68, 178, 88, 185, 129, 58, 46, 196, 120, 42, 246, 9, + 16, 57, 187, 104, 242, 59, 162, 31, 255, 25, 73, 244, 34, 89, 44, 221, 193, 29, 23, 98, 60, + 21, 123, 133, 8, 157, 222, 52, 121, 158, 81, 144, 256, 141, 165, 122, 17, 173, 22, 239, 225, + 143, 140, 49, 30, 139, 190, 195, 4, 207, 111, 26, 189, 79, 169, 72, 128, 199, 211, 61, 137, + 215, 11, 248, 241, 200, 70, 153, 15, 198, 95, 226, 2, 232, 184, 13, 223, 168, 213, 36, 64, + 228, 234, 159, 197, 236, 134, 124, 249, 100, 35, 205, 136, 99, 176, 113, 1, + ], + [ + 1, 117, 68, 246, 255, 23, 121, 22, 4, 211, 15, 213, 249, 92, 227, 88, 16, 73, 60, 81, 225, + 111, 137, 95, 64, 35, 240, 67, 129, 187, 34, 123, 256, 140, 189, 11, 2, 234, 136, 235, 253, + 46, 242, 44, 8, 165, 30, 169, 241, 184, 197, 176, 32, 146, 120, 162, 193, 222, 17, 190, 128, + 70, 223, 134, 1, 117, 68, 246, 255, 23, 121, 22, 4, 211, 15, 213, 249, 92, 227, 88, 16, 73, + 60, 81, 225, 111, 137, 95, 64, 35, 240, 67, 129, 187, 34, 123, 256, 140, 189, 11, 2, 234, + 136, 235, 253, 46, 242, 44, 8, 165, 30, 169, 241, 184, 197, 176, 32, 146, 120, 162, 193, + 222, 17, 190, 128, 70, 223, 134, 1, 117, 68, 246, 255, 23, 121, 22, 4, 211, 15, 213, 249, + 92, 227, 88, 16, 73, 60, 81, 225, 111, 137, 95, 64, 35, 240, 67, 129, 187, 34, 123, 256, + 140, 189, 11, 2, 234, 136, 235, 253, 46, 242, 44, 8, 165, 30, 169, 241, 184, 197, 176, 32, + 146, 120, 162, 193, 222, 17, 190, 128, 70, 223, 134, 1, 117, 68, 246, 255, 23, 121, 22, 4, + 211, 15, 213, 249, 92, 227, 88, 16, 73, 60, 81, 225, 111, 137, 95, 64, 35, 240, 67, 129, + 187, 34, 123, 256, 140, 189, 11, 2, 234, 136, 235, 253, 46, 242, 44, 8, 165, 30, 169, 241, + 184, 197, 176, 32, 146, 120, 162, 193, 222, 17, 190, 128, 70, 223, 134, 1, + ], + [ + 1, 118, 46, 31, 60, 141, 190, 61, 2, 236, 92, 62, 120, 25, 123, 122, 4, 215, 184, 124, 240, + 50, 246, 244, 8, 173, 111, 248, 223, 100, 235, 231, 16, 89, 222, 239, 189, 200, 213, 205, + 32, 178, 187, 221, 121, 143, 169, 153, 64, 99, 117, 185, 242, 29, 81, 49, 128, 198, 234, + 113, 227, 58, 162, 98, 256, 139, 211, 226, 197, 116, 67, 196, 255, 21, 165, 195, 137, 232, + 134, 135, 253, 42, 73, 133, 17, 207, 11, 13, 249, 84, 146, 9, 34, 157, 22, 26, 241, 168, 35, + 18, 68, 57, 44, 52, 225, 79, 70, 36, 136, 114, 88, 104, 193, 158, 140, 72, 15, 228, 176, + 208, 129, 59, 23, 144, 30, 199, 95, 159, 1, 118, 46, 31, 60, 141, 190, 61, 2, 236, 92, 62, + 120, 25, 123, 122, 4, 215, 184, 124, 240, 50, 246, 244, 8, 173, 111, 248, 223, 100, 235, + 231, 16, 89, 222, 239, 189, 200, 213, 205, 32, 178, 187, 221, 121, 143, 169, 153, 64, 99, + 117, 185, 242, 29, 81, 49, 128, 198, 234, 113, 227, 58, 162, 98, 256, 139, 211, 226, 197, + 116, 67, 196, 255, 21, 165, 195, 137, 232, 134, 135, 253, 42, 73, 133, 17, 207, 11, 13, 249, + 84, 146, 9, 34, 157, 22, 26, 241, 168, 35, 18, 68, 57, 44, 52, 225, 79, 70, 36, 136, 114, + 88, 104, 193, 158, 140, 72, 15, 228, 176, 208, 129, 59, 23, 144, 30, 199, 95, 159, 1, + ], + [ + 1, 119, 26, 10, 162, 3, 100, 78, 30, 229, 9, 43, 234, 90, 173, 27, 129, 188, 13, 5, 81, 130, + 50, 39, 15, 243, 133, 150, 117, 45, 215, 142, 193, 94, 135, 131, 169, 65, 25, 148, 136, 250, + 195, 75, 187, 151, 236, 71, 225, 47, 196, 194, 213, 161, 141, 74, 68, 125, 226, 166, 222, + 204, 118, 164, 241, 152, 98, 97, 235, 209, 199, 37, 34, 191, 113, 83, 111, 102, 59, 82, 249, + 76, 49, 177, 246, 233, 228, 147, 17, 224, 185, 170, 184, 51, 158, 41, 253, 38, 153, 217, + 123, 245, 114, 202, 137, 112, 221, 85, 92, 154, 79, 149, 255, 19, 205, 237, 190, 251, 57, + 101, 197, 56, 239, 171, 46, 77, 168, 203, 256, 138, 231, 247, 95, 254, 157, 179, 227, 28, + 248, 214, 23, 167, 84, 230, 128, 69, 244, 252, 176, 127, 207, 218, 242, 14, 124, 107, 140, + 212, 42, 115, 64, 163, 122, 126, 88, 192, 232, 109, 121, 7, 62, 182, 70, 106, 21, 186, 32, + 210, 61, 63, 44, 96, 116, 183, 189, 132, 31, 91, 35, 53, 139, 93, 16, 105, 159, 160, 22, 48, + 58, 220, 223, 66, 144, 174, 146, 155, 198, 175, 8, 181, 208, 80, 11, 24, 29, 110, 240, 33, + 72, 87, 73, 206, 99, 216, 4, 219, 104, 40, 134, 12, 143, 55, 120, 145, 36, 172, 165, 103, + 178, 108, 2, 238, 52, 20, 67, 6, 200, 156, 60, 201, 18, 86, 211, 180, 89, 54, 1, + ], + [ + 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, + 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, + 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, + 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, + 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, + 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, + 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, + 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, + 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, + 121, 128, 197, 253, 34, 225, 15, 1, 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, + 223, 32, 242, 256, 137, 249, 68, 193, 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, + 120, 8, 189, 64, 227, 255, 17, 241, 136, 129, 60, 4, 223, 32, 242, 256, 137, 249, 68, 193, + 30, 2, 240, 16, 121, 128, 197, 253, 34, 225, 15, 1, + ], + [ + 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, + 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, + 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, + 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, + 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, + 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, + 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, + 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, + 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, + 129, 189, 253, 30, 32, 17, 1, 121, 249, 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, + 240, 256, 136, 8, 197, 193, 223, 255, 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, 121, 249, + 60, 64, 34, 2, 242, 241, 120, 128, 68, 4, 227, 225, 240, 256, 136, 8, 197, 193, 223, 255, + 15, 16, 137, 129, 189, 253, 30, 32, 17, 1, + ], + [ + 1, 122, 235, 143, 227, 195, 146, 79, 129, 61, 246, 200, 242, 226, 73, 168, 193, 159, 123, + 100, 121, 113, 165, 84, 225, 208, 190, 50, 189, 185, 211, 42, 241, 104, 95, 25, 223, 221, + 234, 21, 249, 52, 176, 141, 240, 239, 117, 139, 253, 26, 88, 199, 120, 248, 187, 198, 255, + 13, 44, 228, 60, 124, 222, 99, 256, 135, 22, 114, 30, 62, 111, 178, 128, 196, 11, 57, 15, + 31, 184, 89, 64, 98, 134, 157, 136, 144, 92, 173, 32, 49, 67, 207, 68, 72, 46, 215, 16, 153, + 162, 232, 34, 36, 23, 236, 8, 205, 81, 116, 17, 18, 140, 118, 4, 231, 169, 58, 137, 9, 70, + 59, 2, 244, 213, 29, 197, 133, 35, 158, 1, 122, 235, 143, 227, 195, 146, 79, 129, 61, 246, + 200, 242, 226, 73, 168, 193, 159, 123, 100, 121, 113, 165, 84, 225, 208, 190, 50, 189, 185, + 211, 42, 241, 104, 95, 25, 223, 221, 234, 21, 249, 52, 176, 141, 240, 239, 117, 139, 253, + 26, 88, 199, 120, 248, 187, 198, 255, 13, 44, 228, 60, 124, 222, 99, 256, 135, 22, 114, 30, + 62, 111, 178, 128, 196, 11, 57, 15, 31, 184, 89, 64, 98, 134, 157, 136, 144, 92, 173, 32, + 49, 67, 207, 68, 72, 46, 215, 16, 153, 162, 232, 34, 36, 23, 236, 8, 205, 81, 116, 17, 18, + 140, 118, 4, 231, 169, 58, 137, 9, 70, 59, 2, 244, 213, 29, 197, 133, 35, 158, 1, + ], + [ + 1, 123, 223, 187, 128, 67, 17, 35, 193, 95, 120, 111, 32, 81, 197, 73, 241, 88, 30, 92, 8, + 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, 117, 256, 134, 34, 70, 129, 190, 240, 222, 64, + 162, 137, 146, 225, 176, 60, 184, 16, 169, 227, 165, 249, 44, 15, 46, 4, 235, 121, 234, 255, + 11, 68, 140, 1, 123, 223, 187, 128, 67, 17, 35, 193, 95, 120, 111, 32, 81, 197, 73, 241, 88, + 30, 92, 8, 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, 117, 256, 134, 34, 70, 129, 190, + 240, 222, 64, 162, 137, 146, 225, 176, 60, 184, 16, 169, 227, 165, 249, 44, 15, 46, 4, 235, + 121, 234, 255, 11, 68, 140, 1, 123, 223, 187, 128, 67, 17, 35, 193, 95, 120, 111, 32, 81, + 197, 73, 241, 88, 30, 92, 8, 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, 117, 256, 134, + 34, 70, 129, 190, 240, 222, 64, 162, 137, 146, 225, 176, 60, 184, 16, 169, 227, 165, 249, + 44, 15, 46, 4, 235, 121, 234, 255, 11, 68, 140, 1, 123, 223, 187, 128, 67, 17, 35, 193, 95, + 120, 111, 32, 81, 197, 73, 241, 88, 30, 92, 8, 213, 242, 211, 253, 22, 136, 23, 2, 246, 189, + 117, 256, 134, 34, 70, 129, 190, 240, 222, 64, 162, 137, 146, 225, 176, 60, 184, 16, 169, + 227, 165, 249, 44, 15, 46, 4, 235, 121, 234, 255, 11, 68, 140, 1, + ], + [ + 1, 124, 213, 198, 137, 26, 140, 141, 8, 221, 162, 42, 68, 208, 92, 100, 64, 226, 11, 79, 30, + 122, 222, 29, 255, 9, 88, 118, 240, 205, 234, 232, 241, 72, 190, 173, 121, 98, 73, 57, 129, + 62, 235, 99, 197, 13, 70, 199, 4, 239, 81, 21, 34, 104, 46, 50, 32, 113, 134, 168, 15, 61, + 111, 143, 256, 133, 44, 59, 120, 231, 117, 116, 249, 36, 95, 215, 189, 49, 165, 157, 193, + 31, 246, 178, 227, 135, 35, 228, 2, 248, 169, 139, 17, 52, 23, 25, 16, 185, 67, 84, 136, + 159, 184, 200, 128, 195, 22, 158, 60, 244, 187, 58, 253, 18, 176, 236, 223, 153, 211, 207, + 225, 144, 123, 89, 242, 196, 146, 114, 1, 124, 213, 198, 137, 26, 140, 141, 8, 221, 162, 42, + 68, 208, 92, 100, 64, 226, 11, 79, 30, 122, 222, 29, 255, 9, 88, 118, 240, 205, 234, 232, + 241, 72, 190, 173, 121, 98, 73, 57, 129, 62, 235, 99, 197, 13, 70, 199, 4, 239, 81, 21, 34, + 104, 46, 50, 32, 113, 134, 168, 15, 61, 111, 143, 256, 133, 44, 59, 120, 231, 117, 116, 249, + 36, 95, 215, 189, 49, 165, 157, 193, 31, 246, 178, 227, 135, 35, 228, 2, 248, 169, 139, 17, + 52, 23, 25, 16, 185, 67, 84, 136, 159, 184, 200, 128, 195, 22, 158, 60, 244, 187, 58, 253, + 18, 176, 236, 223, 153, 211, 207, 225, 144, 123, 89, 242, 196, 146, 114, 1, + ], + [ + 1, 125, 205, 182, 134, 45, 228, 230, 223, 119, 226, 237, 70, 12, 215, 147, 128, 66, 26, 166, + 190, 106, 143, 142, 17, 69, 144, 10, 222, 251, 21, 55, 193, 224, 244, 174, 162, 204, 57, + 186, 120, 94, 185, 252, 146, 3, 118, 101, 32, 145, 135, 170, 176, 155, 100, 164, 197, 210, + 36, 131, 184, 127, 198, 78, 241, 56, 61, 172, 169, 51, 207, 175, 30, 152, 239, 63, 165, 65, + 158, 218, 8, 229, 98, 171, 44, 103, 25, 41, 242, 181, 9, 97, 46, 96, 178, 148, 253, 14, 208, + 43, 235, 77, 116, 108, 136, 38, 124, 80, 234, 209, 168, 183, 2, 250, 153, 107, 11, 90, 199, + 203, 189, 238, 195, 217, 140, 24, 173, 37, 256, 132, 52, 75, 123, 212, 29, 27, 34, 138, 31, + 20, 187, 245, 42, 110, 129, 191, 231, 91, 67, 151, 114, 115, 240, 188, 113, 247, 35, 6, 236, + 202, 64, 33, 13, 83, 95, 53, 200, 71, 137, 163, 72, 5, 111, 254, 139, 156, 225, 112, 122, + 87, 81, 102, 157, 93, 60, 47, 221, 126, 73, 130, 59, 179, 16, 201, 196, 85, 88, 206, 50, 82, + 227, 105, 18, 194, 92, 192, 99, 39, 249, 28, 159, 86, 213, 154, 232, 216, 15, 76, 248, 160, + 211, 161, 79, 109, 4, 243, 49, 214, 22, 180, 141, 149, 121, 219, 133, 177, 23, 48, 89, 74, + 255, 7, 104, 150, 246, 167, 58, 54, 68, 19, 62, 40, 117, 233, 84, 220, 1, + ], + [ + 1, 126, 199, 145, 23, 71, 208, 251, 15, 91, 158, 119, 88, 37, 36, 167, 225, 80, 57, 243, 35, + 41, 26, 192, 34, 172, 84, 47, 11, 101, 133, 53, 253, 10, 232, 191, 165, 230, 196, 24, 197, + 150, 139, 38, 162, 109, 113, 103, 128, 194, 29, 56, 117, 93, 153, 3, 121, 83, 178, 69, 213, + 110, 239, 45, 16, 217, 100, 7, 111, 108, 244, 161, 240, 171, 215, 105, 123, 78, 62, 102, 2, + 252, 141, 33, 46, 142, 159, 245, 30, 182, 59, 238, 176, 74, 72, 77, 193, 160, 114, 229, 70, + 82, 52, 127, 68, 87, 168, 94, 22, 202, 9, 106, 249, 20, 207, 125, 73, 203, 135, 48, 137, 43, + 21, 76, 67, 218, 226, 206, 256, 131, 58, 112, 234, 186, 49, 6, 242, 166, 99, 138, 169, 220, + 221, 90, 32, 177, 200, 14, 222, 216, 231, 65, 223, 85, 173, 210, 246, 156, 124, 204, 4, 247, + 25, 66, 92, 27, 61, 233, 60, 107, 118, 219, 95, 148, 144, 154, 129, 63, 228, 201, 140, 164, + 104, 254, 136, 174, 79, 188, 44, 147, 18, 212, 241, 40, 157, 250, 146, 149, 13, 96, 17, 86, + 42, 152, 134, 179, 195, 155, 255, 5, 116, 224, 211, 115, 98, 12, 227, 75, 198, 19, 81, 183, + 185, 180, 64, 97, 143, 28, 187, 175, 205, 130, 189, 170, 89, 163, 235, 55, 248, 151, 8, 237, + 50, 132, 184, 54, 122, 209, 120, 214, 236, 181, 190, 39, 31, 51, 1, + ], + [ + 1, 127, 195, 93, 246, 145, 168, 5, 121, 204, 208, 202, 211, 69, 25, 91, 249, 12, 239, 27, + 88, 125, 198, 217, 60, 167, 135, 183, 111, 219, 57, 43, 64, 161, 144, 41, 67, 28, 215, 63, + 34, 206, 205, 78, 140, 47, 58, 170, 2, 254, 133, 186, 235, 33, 79, 10, 242, 151, 159, 147, + 165, 138, 50, 182, 241, 24, 221, 54, 176, 250, 139, 177, 120, 77, 13, 109, 222, 181, 114, + 86, 128, 65, 31, 82, 134, 56, 173, 126, 68, 155, 153, 156, 23, 94, 116, 83, 4, 251, 9, 115, + 213, 66, 158, 20, 227, 45, 61, 37, 73, 19, 100, 107, 225, 48, 185, 108, 95, 243, 21, 97, + 240, 154, 26, 218, 187, 105, 228, 172, 256, 130, 62, 164, 11, 112, 89, 252, 136, 53, 49, 55, + 46, 188, 232, 166, 8, 245, 18, 230, 169, 132, 59, 40, 197, 90, 122, 74, 146, 38, 200, 214, + 193, 96, 113, 216, 190, 229, 42, 194, 223, 51, 52, 179, 117, 210, 199, 87, 255, 3, 124, 71, + 22, 224, 178, 247, 15, 106, 98, 110, 92, 119, 207, 75, 16, 233, 36, 203, 81, 7, 118, 80, + 137, 180, 244, 148, 35, 76, 143, 171, 129, 192, 226, 175, 123, 201, 84, 131, 189, 102, 104, + 101, 234, 163, 141, 174, 253, 6, 248, 142, 44, 191, 99, 237, 30, 212, 196, 220, 184, 238, + 157, 150, 32, 209, 72, 149, 162, 14, 236, 160, 17, 103, 231, 39, 70, 152, 29, 85, 1, + ], + [ + 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, + 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, + 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, + 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, + 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, + 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, + 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, + 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, + 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, + 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, + 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, + 2, 256, 129, 64, 225, 16, 249, 4, 255, 1, 128, 193, 32, 241, 8, 253, 2, 256, 129, 64, 225, + 16, 249, 4, 255, 1, + ], + [ + 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, + 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, + 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, + 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, + 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, + 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, + 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, + 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, + 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, + 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, + 193, 225, 241, 249, 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, + 253, 255, 256, 128, 64, 32, 16, 8, 4, 2, 1, 129, 193, 225, 241, 249, 253, 255, 256, 128, 64, + 32, 16, 8, 4, 2, 1, + ], + [ + 1, 130, 195, 164, 246, 112, 168, 252, 121, 53, 208, 55, 211, 188, 25, 166, 249, 245, 239, + 230, 88, 132, 198, 40, 60, 90, 135, 74, 111, 38, 57, 214, 64, 96, 144, 216, 67, 229, 215, + 194, 34, 51, 205, 179, 140, 210, 58, 87, 2, 3, 133, 71, 235, 224, 79, 247, 242, 106, 159, + 110, 165, 119, 50, 75, 241, 233, 221, 203, 176, 7, 139, 80, 120, 180, 13, 148, 222, 76, 114, + 171, 128, 192, 31, 175, 134, 201, 173, 131, 68, 102, 153, 101, 23, 163, 116, 174, 4, 6, 9, + 142, 213, 191, 158, 237, 227, 212, 61, 220, 73, 238, 100, 150, 225, 209, 185, 149, 95, 14, + 21, 160, 240, 103, 26, 39, 187, 152, 228, 85, 256, 127, 62, 93, 11, 145, 89, 5, 136, 204, + 49, 202, 46, 69, 232, 91, 8, 12, 18, 27, 169, 125, 59, 217, 197, 167, 122, 183, 146, 219, + 200, 43, 193, 161, 113, 41, 190, 28, 42, 63, 223, 206, 52, 78, 117, 47, 199, 170, 255, 254, + 124, 186, 22, 33, 178, 10, 15, 151, 98, 147, 92, 138, 207, 182, 16, 24, 36, 54, 81, 250, + 118, 177, 137, 77, 244, 109, 35, 181, 143, 86, 129, 65, 226, 82, 123, 56, 84, 126, 189, 155, + 104, 156, 234, 94, 141, 83, 253, 251, 248, 115, 44, 66, 99, 20, 30, 45, 196, 37, 184, 19, + 157, 107, 32, 48, 72, 108, 162, 243, 236, 97, 17, 154, 231, 218, 70, 105, 29, 172, 1, + ], + [ + 1, 131, 199, 112, 23, 186, 208, 6, 15, 166, 158, 138, 88, 220, 36, 90, 225, 177, 57, 14, 35, + 216, 26, 65, 34, 85, 84, 210, 11, 156, 133, 204, 253, 247, 232, 66, 165, 27, 196, 233, 197, + 107, 139, 219, 162, 148, 113, 154, 128, 63, 29, 201, 117, 164, 153, 254, 121, 174, 178, 188, + 213, 147, 239, 212, 16, 40, 100, 250, 111, 149, 244, 96, 240, 86, 215, 152, 123, 179, 62, + 155, 2, 5, 141, 224, 46, 115, 159, 12, 30, 75, 59, 19, 176, 183, 72, 180, 193, 97, 114, 28, + 70, 175, 52, 130, 68, 170, 168, 163, 22, 55, 9, 151, 249, 237, 207, 132, 73, 54, 135, 209, + 137, 214, 21, 181, 67, 39, 226, 51, 256, 126, 58, 145, 234, 71, 49, 251, 242, 91, 99, 119, + 169, 37, 221, 167, 32, 80, 200, 243, 222, 41, 231, 192, 223, 172, 173, 47, 246, 101, 124, + 53, 4, 10, 25, 191, 92, 230, 61, 24, 60, 150, 118, 38, 95, 109, 144, 103, 129, 194, 228, 56, + 140, 93, 104, 3, 136, 83, 79, 69, 44, 110, 18, 45, 241, 217, 157, 7, 146, 108, 13, 161, 17, + 171, 42, 105, 134, 78, 195, 102, 255, 252, 116, 33, 211, 142, 98, 245, 227, 182, 198, 238, + 81, 74, 185, 77, 64, 160, 143, 229, 187, 82, 205, 127, 189, 87, 89, 94, 235, 202, 248, 106, + 8, 20, 50, 125, 184, 203, 122, 48, 120, 43, 236, 76, 190, 218, 31, 206, 1, + ], + [ + 1, 132, 205, 75, 134, 212, 228, 27, 223, 138, 226, 20, 70, 245, 215, 110, 128, 191, 26, 91, + 190, 151, 143, 115, 17, 188, 144, 247, 222, 6, 21, 202, 193, 33, 244, 83, 162, 53, 57, 71, + 120, 163, 185, 5, 146, 254, 118, 156, 32, 112, 135, 87, 176, 102, 100, 93, 197, 47, 36, 126, + 184, 130, 198, 179, 241, 201, 61, 85, 169, 206, 207, 82, 30, 105, 239, 194, 165, 192, 158, + 39, 8, 28, 98, 86, 44, 154, 25, 216, 242, 76, 9, 160, 46, 161, 178, 109, 253, 243, 208, 214, + 235, 180, 116, 149, 136, 219, 124, 177, 234, 48, 168, 74, 2, 7, 153, 150, 11, 167, 199, 54, + 189, 19, 195, 40, 140, 233, 173, 220, 256, 125, 52, 182, 123, 45, 29, 230, 34, 119, 31, 237, + 187, 12, 42, 147, 129, 66, 231, 166, 67, 106, 114, 142, 240, 69, 113, 10, 35, 251, 236, 55, + 64, 224, 13, 174, 95, 204, 200, 186, 137, 94, 72, 252, 111, 3, 139, 101, 225, 145, 122, 170, + 81, 155, 157, 164, 60, 210, 221, 131, 73, 127, 59, 78, 16, 56, 196, 172, 88, 51, 50, 175, + 227, 152, 18, 63, 92, 65, 99, 218, 249, 229, 159, 171, 213, 103, 232, 41, 15, 181, 248, 97, + 211, 96, 79, 148, 4, 14, 49, 43, 22, 77, 141, 108, 121, 38, 133, 80, 23, 209, 89, 183, 255, + 250, 104, 107, 246, 90, 58, 203, 68, 238, 62, 217, 117, 24, 84, 37, 1, + ], + [ + 1, 133, 213, 59, 137, 231, 140, 116, 8, 36, 162, 215, 68, 49, 92, 157, 64, 31, 11, 178, 30, + 135, 222, 228, 255, 248, 88, 139, 240, 52, 234, 25, 241, 185, 190, 84, 121, 159, 73, 200, + 129, 195, 235, 158, 197, 244, 70, 58, 4, 18, 81, 236, 34, 153, 46, 207, 32, 144, 134, 89, + 15, 196, 111, 114, 256, 124, 44, 198, 120, 26, 117, 141, 249, 221, 95, 42, 189, 208, 165, + 100, 193, 226, 246, 79, 227, 122, 35, 29, 2, 9, 169, 118, 17, 205, 23, 232, 16, 72, 67, 173, + 136, 98, 184, 57, 128, 62, 22, 99, 60, 13, 187, 199, 253, 239, 176, 21, 223, 104, 211, 50, + 225, 113, 123, 168, 242, 61, 146, 143, 1, 133, 213, 59, 137, 231, 140, 116, 8, 36, 162, 215, + 68, 49, 92, 157, 64, 31, 11, 178, 30, 135, 222, 228, 255, 248, 88, 139, 240, 52, 234, 25, + 241, 185, 190, 84, 121, 159, 73, 200, 129, 195, 235, 158, 197, 244, 70, 58, 4, 18, 81, 236, + 34, 153, 46, 207, 32, 144, 134, 89, 15, 196, 111, 114, 256, 124, 44, 198, 120, 26, 117, 141, + 249, 221, 95, 42, 189, 208, 165, 100, 193, 226, 246, 79, 227, 122, 35, 29, 2, 9, 169, 118, + 17, 205, 23, 232, 16, 72, 67, 173, 136, 98, 184, 57, 128, 62, 22, 99, 60, 13, 187, 199, 253, + 239, 176, 21, 223, 104, 211, 50, 225, 113, 123, 168, 242, 61, 146, 143, 1, + ], + [ + 1, 134, 223, 70, 128, 190, 17, 222, 193, 162, 120, 146, 32, 176, 197, 184, 241, 169, 30, + 165, 8, 44, 242, 46, 253, 235, 136, 234, 2, 11, 189, 140, 256, 123, 34, 187, 129, 67, 240, + 35, 64, 95, 137, 111, 225, 81, 60, 73, 16, 88, 227, 92, 249, 213, 15, 211, 4, 22, 121, 23, + 255, 246, 68, 117, 1, 134, 223, 70, 128, 190, 17, 222, 193, 162, 120, 146, 32, 176, 197, + 184, 241, 169, 30, 165, 8, 44, 242, 46, 253, 235, 136, 234, 2, 11, 189, 140, 256, 123, 34, + 187, 129, 67, 240, 35, 64, 95, 137, 111, 225, 81, 60, 73, 16, 88, 227, 92, 249, 213, 15, + 211, 4, 22, 121, 23, 255, 246, 68, 117, 1, 134, 223, 70, 128, 190, 17, 222, 193, 162, 120, + 146, 32, 176, 197, 184, 241, 169, 30, 165, 8, 44, 242, 46, 253, 235, 136, 234, 2, 11, 189, + 140, 256, 123, 34, 187, 129, 67, 240, 35, 64, 95, 137, 111, 225, 81, 60, 73, 16, 88, 227, + 92, 249, 213, 15, 211, 4, 22, 121, 23, 255, 246, 68, 117, 1, 134, 223, 70, 128, 190, 17, + 222, 193, 162, 120, 146, 32, 176, 197, 184, 241, 169, 30, 165, 8, 44, 242, 46, 253, 235, + 136, 234, 2, 11, 189, 140, 256, 123, 34, 187, 129, 67, 240, 35, 64, 95, 137, 111, 225, 81, + 60, 73, 16, 88, 227, 92, 249, 213, 15, 211, 4, 22, 121, 23, 255, 246, 68, 117, 1, + ], + [ + 1, 135, 235, 114, 227, 62, 146, 178, 129, 196, 246, 57, 242, 31, 73, 89, 193, 98, 123, 157, + 121, 144, 165, 173, 225, 49, 190, 207, 189, 72, 211, 215, 241, 153, 95, 232, 223, 36, 234, + 236, 249, 205, 176, 116, 240, 18, 117, 118, 253, 231, 88, 58, 120, 9, 187, 59, 255, 244, 44, + 29, 60, 133, 222, 158, 256, 122, 22, 143, 30, 195, 111, 79, 128, 61, 11, 200, 15, 226, 184, + 168, 64, 159, 134, 100, 136, 113, 92, 84, 32, 208, 67, 50, 68, 185, 46, 42, 16, 104, 162, + 25, 34, 221, 23, 21, 8, 52, 81, 141, 17, 239, 140, 139, 4, 26, 169, 199, 137, 248, 70, 198, + 2, 13, 213, 228, 197, 124, 35, 99, 1, 135, 235, 114, 227, 62, 146, 178, 129, 196, 246, 57, + 242, 31, 73, 89, 193, 98, 123, 157, 121, 144, 165, 173, 225, 49, 190, 207, 189, 72, 211, + 215, 241, 153, 95, 232, 223, 36, 234, 236, 249, 205, 176, 116, 240, 18, 117, 118, 253, 231, + 88, 58, 120, 9, 187, 59, 255, 244, 44, 29, 60, 133, 222, 158, 256, 122, 22, 143, 30, 195, + 111, 79, 128, 61, 11, 200, 15, 226, 184, 168, 64, 159, 134, 100, 136, 113, 92, 84, 32, 208, + 67, 50, 68, 185, 46, 42, 16, 104, 162, 25, 34, 221, 23, 21, 8, 52, 81, 141, 17, 239, 140, + 139, 4, 26, 169, 199, 137, 248, 70, 198, 2, 13, 213, 228, 197, 124, 35, 99, 1, + ], + [ + 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, + 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, + 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, + 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, + 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, + 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, + 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, + 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, + 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, + 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, + 189, 4, 30, 225, 17, 256, 121, 8, 60, 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, + 240, 1, 136, 249, 197, 64, 223, 2, 15, 241, 137, 128, 189, 4, 30, 225, 17, 256, 121, 8, 60, + 193, 34, 255, 242, 16, 120, 129, 68, 253, 227, 32, 240, 1, + ], + [ + 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, + 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, + 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, + 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, + 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, + 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, + 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, + 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, + 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, + 128, 60, 253, 223, 225, 242, 1, 137, 8, 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, + 15, 256, 120, 249, 189, 193, 227, 2, 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, 137, 8, + 68, 64, 30, 255, 240, 241, 121, 129, 197, 4, 34, 32, 15, 256, 120, 249, 189, 193, 227, 2, + 17, 16, 136, 128, 60, 253, 223, 225, 242, 1, + ], + [ + 1, 138, 26, 247, 162, 254, 100, 179, 30, 28, 9, 214, 234, 167, 173, 230, 129, 69, 13, 252, + 81, 127, 50, 218, 15, 14, 133, 107, 117, 212, 215, 115, 193, 163, 135, 126, 169, 192, 25, + 109, 136, 7, 195, 182, 187, 106, 236, 186, 225, 210, 196, 63, 213, 96, 141, 183, 68, 132, + 226, 91, 222, 53, 118, 93, 241, 105, 98, 160, 235, 48, 199, 220, 34, 66, 113, 174, 111, 155, + 59, 175, 249, 181, 49, 80, 246, 24, 228, 110, 17, 33, 185, 87, 184, 206, 158, 216, 253, 219, + 153, 40, 123, 12, 114, 55, 137, 145, 221, 172, 92, 103, 79, 108, 255, 238, 205, 20, 190, 6, + 57, 156, 197, 201, 239, 86, 46, 180, 168, 54, 256, 119, 231, 10, 95, 3, 157, 78, 227, 229, + 248, 43, 23, 90, 84, 27, 128, 188, 244, 5, 176, 130, 207, 39, 242, 243, 124, 150, 140, 45, + 42, 142, 64, 94, 122, 131, 88, 65, 232, 148, 121, 250, 62, 75, 70, 151, 21, 71, 32, 47, 61, + 194, 44, 161, 116, 74, 189, 125, 31, 166, 35, 204, 139, 164, 16, 152, 159, 97, 22, 209, 58, + 37, 223, 191, 144, 83, 146, 102, 198, 82, 8, 76, 208, 177, 11, 233, 29, 147, 240, 224, 72, + 170, 73, 51, 99, 41, 4, 38, 104, 217, 134, 245, 143, 202, 120, 112, 36, 85, 165, 154, 178, + 149, 2, 19, 52, 237, 67, 251, 200, 101, 60, 56, 18, 171, 211, 77, 89, 203, 1, + ], + [ + 1, 139, 46, 226, 60, 116, 190, 196, 2, 21, 92, 195, 120, 232, 123, 135, 4, 42, 184, 133, + 240, 207, 246, 13, 8, 84, 111, 9, 223, 157, 235, 26, 16, 168, 222, 18, 189, 57, 213, 52, 32, + 79, 187, 36, 121, 114, 169, 104, 64, 158, 117, 72, 242, 228, 81, 208, 128, 59, 234, 144, + 227, 199, 162, 159, 256, 118, 211, 31, 197, 141, 67, 61, 255, 236, 165, 62, 137, 25, 134, + 122, 253, 215, 73, 124, 17, 50, 11, 244, 249, 173, 146, 248, 34, 100, 22, 231, 241, 89, 35, + 239, 68, 200, 44, 205, 225, 178, 70, 221, 136, 143, 88, 153, 193, 99, 140, 185, 15, 29, 176, + 49, 129, 198, 23, 113, 30, 58, 95, 98, 1, 139, 46, 226, 60, 116, 190, 196, 2, 21, 92, 195, + 120, 232, 123, 135, 4, 42, 184, 133, 240, 207, 246, 13, 8, 84, 111, 9, 223, 157, 235, 26, + 16, 168, 222, 18, 189, 57, 213, 52, 32, 79, 187, 36, 121, 114, 169, 104, 64, 158, 117, 72, + 242, 228, 81, 208, 128, 59, 234, 144, 227, 199, 162, 159, 256, 118, 211, 31, 197, 141, 67, + 61, 255, 236, 165, 62, 137, 25, 134, 122, 253, 215, 73, 124, 17, 50, 11, 244, 249, 173, 146, + 248, 34, 100, 22, 231, 241, 89, 35, 239, 68, 200, 44, 205, 225, 178, 70, 221, 136, 143, 88, + 153, 193, 99, 140, 185, 15, 29, 176, 49, 129, 198, 23, 113, 30, 58, 95, 98, 1, + ], + [ + 1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, 44, 249, 165, 227, 169, 16, 184, 60, 176, + 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, 34, 134, 256, 117, 189, 246, 2, 23, 136, 22, + 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, 197, 81, 32, 111, 120, 95, 193, 35, 17, 67, 128, + 187, 223, 123, 1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, 44, 249, 165, 227, 169, 16, + 184, 60, 176, 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, 34, 134, 256, 117, 189, 246, + 2, 23, 136, 22, 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, 197, 81, 32, 111, 120, 95, 193, + 35, 17, 67, 128, 187, 223, 123, 1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, 44, 249, 165, + 227, 169, 16, 184, 60, 176, 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, 34, 134, 256, + 117, 189, 246, 2, 23, 136, 22, 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, 197, 81, 32, 111, + 120, 95, 193, 35, 17, 67, 128, 187, 223, 123, 1, 140, 68, 11, 255, 234, 121, 235, 4, 46, 15, + 44, 249, 165, 227, 169, 16, 184, 60, 176, 225, 146, 137, 162, 64, 222, 240, 190, 129, 70, + 34, 134, 256, 117, 189, 246, 2, 23, 136, 22, 253, 211, 242, 213, 8, 92, 30, 88, 241, 73, + 197, 81, 32, 111, 120, 95, 193, 35, 17, 67, 128, 187, 223, 123, 1, + ], + [ + 1, 141, 92, 122, 240, 173, 235, 239, 32, 143, 117, 49, 227, 139, 67, 195, 253, 207, 146, 26, + 68, 79, 88, 72, 129, 199, 46, 61, 120, 215, 246, 248, 16, 200, 187, 153, 242, 198, 162, 226, + 255, 232, 73, 13, 34, 168, 44, 36, 193, 228, 23, 159, 60, 236, 123, 124, 8, 100, 222, 205, + 121, 99, 81, 113, 256, 116, 165, 135, 17, 84, 22, 18, 225, 114, 140, 208, 30, 118, 190, 62, + 4, 50, 111, 231, 189, 178, 169, 185, 128, 58, 211, 196, 137, 42, 11, 9, 241, 57, 70, 104, + 15, 59, 95, 31, 2, 25, 184, 244, 223, 89, 213, 221, 64, 29, 234, 98, 197, 21, 134, 133, 249, + 157, 35, 52, 136, 158, 176, 144, 1, 141, 92, 122, 240, 173, 235, 239, 32, 143, 117, 49, 227, + 139, 67, 195, 253, 207, 146, 26, 68, 79, 88, 72, 129, 199, 46, 61, 120, 215, 246, 248, 16, + 200, 187, 153, 242, 198, 162, 226, 255, 232, 73, 13, 34, 168, 44, 36, 193, 228, 23, 159, 60, + 236, 123, 124, 8, 100, 222, 205, 121, 99, 81, 113, 256, 116, 165, 135, 17, 84, 22, 18, 225, + 114, 140, 208, 30, 118, 190, 62, 4, 50, 111, 231, 189, 178, 169, 185, 128, 58, 211, 196, + 137, 42, 11, 9, 241, 57, 70, 104, 15, 59, 95, 31, 2, 25, 184, 244, 223, 89, 213, 221, 64, + 29, 234, 98, 197, 21, 134, 133, 249, 157, 35, 52, 136, 158, 176, 144, 1, + ], + [ + 1, 142, 118, 51, 46, 107, 31, 33, 60, 39, 141, 233, 190, 252, 61, 181, 2, 27, 236, 102, 92, + 214, 62, 66, 120, 78, 25, 209, 123, 247, 122, 105, 4, 54, 215, 204, 184, 171, 124, 132, 240, + 156, 50, 161, 246, 237, 244, 210, 8, 108, 173, 151, 111, 85, 248, 7, 223, 55, 100, 65, 235, + 217, 231, 163, 16, 216, 89, 45, 222, 170, 239, 14, 189, 110, 200, 130, 213, 177, 205, 69, + 32, 175, 178, 90, 187, 83, 221, 28, 121, 220, 143, 3, 169, 97, 153, 138, 64, 93, 99, 180, + 117, 166, 185, 56, 242, 183, 29, 6, 81, 194, 49, 19, 128, 186, 198, 103, 234, 75, 113, 112, + 227, 109, 58, 12, 162, 131, 98, 38, 256, 115, 139, 206, 211, 150, 226, 224, 197, 218, 116, + 24, 67, 5, 196, 76, 255, 230, 21, 155, 165, 43, 195, 191, 137, 179, 232, 48, 134, 10, 135, + 152, 253, 203, 42, 53, 73, 86, 133, 125, 17, 101, 207, 96, 11, 20, 13, 47, 249, 149, 84, + 106, 146, 172, 9, 250, 34, 202, 157, 192, 22, 40, 26, 94, 241, 41, 168, 212, 35, 87, 18, + 243, 68, 147, 57, 127, 44, 80, 52, 188, 225, 82, 79, 167, 70, 174, 36, 229, 136, 37, 114, + 254, 88, 160, 104, 119, 193, 164, 158, 77, 140, 91, 72, 201, 15, 74, 228, 251, 176, 63, 208, + 238, 129, 71, 59, 154, 23, 182, 144, 145, 30, 148, 199, 245, 95, 126, 159, 219, 1, + ], + [ + 1, 143, 146, 61, 242, 168, 123, 113, 225, 50, 211, 104, 223, 21, 176, 239, 253, 199, 187, + 13, 60, 99, 22, 62, 128, 57, 184, 98, 136, 173, 67, 72, 16, 232, 23, 205, 17, 118, 169, 9, + 2, 29, 35, 122, 227, 79, 246, 226, 193, 100, 165, 208, 189, 42, 95, 221, 249, 141, 117, 26, + 120, 198, 44, 124, 256, 114, 111, 196, 15, 89, 134, 144, 32, 207, 46, 153, 34, 236, 81, 18, + 4, 58, 70, 244, 197, 158, 235, 195, 129, 200, 73, 159, 121, 84, 190, 185, 241, 25, 234, 52, + 240, 139, 88, 248, 255, 228, 222, 135, 30, 178, 11, 31, 64, 157, 92, 49, 68, 215, 162, 36, + 8, 116, 140, 231, 137, 59, 213, 133, 1, 143, 146, 61, 242, 168, 123, 113, 225, 50, 211, 104, + 223, 21, 176, 239, 253, 199, 187, 13, 60, 99, 22, 62, 128, 57, 184, 98, 136, 173, 67, 72, + 16, 232, 23, 205, 17, 118, 169, 9, 2, 29, 35, 122, 227, 79, 246, 226, 193, 100, 165, 208, + 189, 42, 95, 221, 249, 141, 117, 26, 120, 198, 44, 124, 256, 114, 111, 196, 15, 89, 134, + 144, 32, 207, 46, 153, 34, 236, 81, 18, 4, 58, 70, 244, 197, 158, 235, 195, 129, 200, 73, + 159, 121, 84, 190, 185, 241, 25, 234, 52, 240, 139, 88, 248, 255, 228, 222, 135, 30, 178, + 11, 31, 64, 157, 92, 49, 68, 215, 162, 36, 8, 116, 140, 231, 137, 59, 213, 133, 1, + ], + [ + 1, 144, 176, 158, 136, 52, 35, 157, 249, 133, 134, 21, 197, 98, 234, 29, 64, 221, 213, 89, + 223, 244, 184, 25, 2, 31, 95, 59, 15, 104, 70, 57, 241, 9, 11, 42, 137, 196, 211, 58, 128, + 185, 169, 178, 189, 231, 111, 50, 4, 62, 190, 118, 30, 208, 140, 114, 225, 18, 22, 84, 17, + 135, 165, 116, 256, 113, 81, 99, 121, 205, 222, 100, 8, 124, 123, 236, 60, 159, 23, 228, + 193, 36, 44, 168, 34, 13, 73, 232, 255, 226, 162, 198, 242, 153, 187, 200, 16, 248, 246, + 215, 120, 61, 46, 199, 129, 72, 88, 79, 68, 26, 146, 207, 253, 195, 67, 139, 227, 49, 117, + 143, 32, 239, 235, 173, 240, 122, 92, 141, 1, 144, 176, 158, 136, 52, 35, 157, 249, 133, + 134, 21, 197, 98, 234, 29, 64, 221, 213, 89, 223, 244, 184, 25, 2, 31, 95, 59, 15, 104, 70, + 57, 241, 9, 11, 42, 137, 196, 211, 58, 128, 185, 169, 178, 189, 231, 111, 50, 4, 62, 190, + 118, 30, 208, 140, 114, 225, 18, 22, 84, 17, 135, 165, 116, 256, 113, 81, 99, 121, 205, 222, + 100, 8, 124, 123, 236, 60, 159, 23, 228, 193, 36, 44, 168, 34, 13, 73, 232, 255, 226, 162, + 198, 242, 153, 187, 200, 16, 248, 246, 215, 120, 61, 46, 199, 129, 72, 88, 79, 68, 26, 146, + 207, 253, 195, 67, 139, 227, 49, 117, 143, 32, 239, 235, 173, 240, 122, 92, 141, 1, + ], + [ + 1, 145, 208, 91, 88, 167, 57, 41, 34, 47, 133, 10, 165, 24, 139, 109, 128, 56, 153, 83, 213, + 45, 100, 108, 240, 105, 62, 252, 46, 245, 59, 74, 193, 229, 52, 87, 22, 106, 207, 203, 137, + 76, 226, 131, 234, 6, 99, 220, 32, 14, 231, 85, 246, 204, 25, 27, 60, 219, 144, 63, 140, + 254, 79, 147, 241, 250, 13, 86, 134, 155, 116, 115, 227, 19, 185, 97, 187, 130, 89, 55, 8, + 132, 122, 214, 190, 51, 199, 71, 15, 119, 36, 80, 35, 192, 84, 101, 253, 191, 196, 150, 162, + 103, 29, 93, 121, 69, 239, 217, 111, 161, 215, 78, 2, 33, 159, 182, 176, 77, 114, 82, 68, + 94, 9, 20, 73, 48, 21, 218, 256, 112, 49, 166, 169, 90, 200, 216, 223, 210, 124, 247, 92, + 233, 118, 148, 129, 201, 104, 174, 44, 212, 157, 149, 17, 152, 195, 5, 211, 12, 198, 183, + 64, 28, 205, 170, 235, 151, 50, 54, 120, 181, 31, 126, 23, 251, 158, 37, 225, 243, 26, 172, + 11, 53, 232, 230, 197, 38, 113, 194, 117, 3, 178, 110, 16, 7, 244, 171, 123, 102, 141, 142, + 30, 238, 72, 160, 70, 127, 168, 202, 249, 125, 135, 43, 67, 206, 58, 186, 242, 138, 221, + 177, 222, 65, 173, 156, 4, 66, 61, 107, 95, 154, 228, 164, 136, 188, 18, 40, 146, 96, 42, + 179, 255, 224, 98, 75, 81, 180, 143, 175, 189, 163, 248, 237, 184, 209, 236, 39, 1, + ], + [ + 1, 146, 242, 123, 225, 211, 223, 176, 253, 187, 60, 22, 128, 184, 136, 67, 16, 23, 17, 169, + 2, 35, 227, 246, 193, 165, 189, 95, 249, 117, 120, 44, 256, 111, 15, 134, 32, 46, 34, 81, 4, + 70, 197, 235, 129, 73, 121, 190, 241, 234, 240, 88, 255, 222, 30, 11, 64, 92, 68, 162, 8, + 140, 137, 213, 1, 146, 242, 123, 225, 211, 223, 176, 253, 187, 60, 22, 128, 184, 136, 67, + 16, 23, 17, 169, 2, 35, 227, 246, 193, 165, 189, 95, 249, 117, 120, 44, 256, 111, 15, 134, + 32, 46, 34, 81, 4, 70, 197, 235, 129, 73, 121, 190, 241, 234, 240, 88, 255, 222, 30, 11, 64, + 92, 68, 162, 8, 140, 137, 213, 1, 146, 242, 123, 225, 211, 223, 176, 253, 187, 60, 22, 128, + 184, 136, 67, 16, 23, 17, 169, 2, 35, 227, 246, 193, 165, 189, 95, 249, 117, 120, 44, 256, + 111, 15, 134, 32, 46, 34, 81, 4, 70, 197, 235, 129, 73, 121, 190, 241, 234, 240, 88, 255, + 222, 30, 11, 64, 92, 68, 162, 8, 140, 137, 213, 1, 146, 242, 123, 225, 211, 223, 176, 253, + 187, 60, 22, 128, 184, 136, 67, 16, 23, 17, 169, 2, 35, 227, 246, 193, 165, 189, 95, 249, + 117, 120, 44, 256, 111, 15, 134, 32, 46, 34, 81, 4, 70, 197, 235, 129, 73, 121, 190, 241, + 234, 240, 88, 255, 222, 30, 11, 64, 92, 68, 162, 8, 140, 137, 213, 1, + ], + [ + 1, 147, 21, 3, 184, 63, 9, 38, 189, 27, 114, 53, 81, 85, 159, 243, 255, 220, 215, 251, 146, + 131, 239, 181, 136, 203, 29, 151, 95, 87, 196, 28, 4, 74, 84, 12, 222, 252, 36, 152, 242, + 108, 199, 212, 67, 83, 122, 201, 249, 109, 89, 233, 70, 10, 185, 210, 30, 41, 116, 90, 123, + 91, 13, 112, 16, 39, 79, 48, 117, 237, 144, 94, 197, 175, 25, 77, 11, 75, 231, 33, 225, 179, + 99, 161, 23, 40, 226, 69, 120, 164, 207, 103, 235, 107, 52, 191, 64, 156, 59, 192, 211, 177, + 62, 119, 17, 186, 100, 51, 44, 43, 153, 132, 129, 202, 139, 130, 92, 160, 133, 19, 223, 142, + 57, 155, 169, 171, 208, 250, 256, 110, 236, 254, 73, 194, 248, 219, 68, 230, 143, 204, 176, + 172, 98, 14, 2, 37, 42, 6, 111, 126, 18, 76, 121, 54, 228, 106, 162, 170, 61, 229, 253, 183, + 173, 245, 35, 5, 221, 105, 15, 149, 58, 45, 190, 174, 135, 56, 8, 148, 168, 24, 187, 247, + 72, 47, 227, 216, 141, 167, 134, 166, 244, 145, 241, 218, 178, 209, 140, 20, 113, 163, 60, + 82, 232, 180, 246, 182, 26, 224, 32, 78, 158, 96, 234, 217, 31, 188, 137, 93, 50, 154, 22, + 150, 205, 66, 193, 101, 198, 65, 46, 80, 195, 138, 240, 71, 157, 206, 213, 214, 104, 125, + 128, 55, 118, 127, 165, 97, 124, 238, 34, 115, 200, 102, 88, 86, 49, 7, 1, + ], + [ + 1, 148, 59, 251, 140, 160, 36, 188, 68, 41, 157, 106, 11, 86, 135, 191, 255, 218, 139, 12, + 234, 194, 185, 138, 121, 175, 200, 45, 235, 85, 244, 132, 4, 78, 236, 233, 46, 126, 144, + 238, 15, 164, 114, 167, 44, 87, 26, 250, 249, 101, 42, 48, 165, 5, 226, 38, 227, 186, 29, + 180, 169, 83, 205, 14, 16, 55, 173, 161, 184, 247, 62, 181, 60, 142, 199, 154, 176, 91, 104, + 229, 225, 147, 168, 192, 146, 20, 133, 152, 137, 230, 116, 206, 162, 75, 49, 56, 64, 220, + 178, 130, 222, 217, 248, 210, 240, 54, 25, 102, 190, 107, 159, 145, 129, 74, 158, 254, 70, + 80, 18, 94, 34, 149, 207, 53, 134, 43, 196, 224, 256, 109, 198, 6, 117, 97, 221, 69, 189, + 216, 100, 151, 246, 171, 122, 66, 2, 39, 118, 245, 23, 63, 72, 119, 136, 82, 57, 212, 22, + 172, 13, 125, 253, 179, 21, 24, 211, 131, 113, 19, 242, 93, 143, 90, 213, 170, 231, 7, 8, + 156, 215, 209, 92, 252, 31, 219, 30, 71, 228, 77, 88, 174, 52, 243, 241, 202, 84, 96, 73, + 10, 195, 76, 197, 115, 58, 103, 81, 166, 153, 28, 32, 110, 89, 65, 111, 237, 124, 105, 120, + 27, 141, 51, 95, 182, 208, 201, 193, 37, 79, 127, 35, 40, 9, 47, 17, 203, 232, 155, 67, 150, + 98, 112, 128, 183, 99, 3, 187, 177, 239, 163, 223, 108, 50, 204, 123, 214, 61, 33, 1, + ], + [ + 1, 149, 99, 102, 35, 75, 124, 229, 197, 55, 228, 48, 213, 126, 13, 138, 2, 41, 198, 204, 70, + 150, 248, 201, 137, 110, 199, 96, 169, 252, 26, 19, 4, 82, 139, 151, 140, 43, 239, 145, 17, + 220, 141, 192, 81, 247, 52, 38, 8, 164, 21, 45, 23, 86, 221, 33, 34, 183, 25, 127, 162, 237, + 104, 76, 16, 71, 42, 90, 46, 172, 185, 66, 68, 109, 50, 254, 67, 217, 208, 152, 32, 142, 84, + 180, 92, 87, 113, 132, 136, 218, 100, 251, 134, 177, 159, 47, 64, 27, 168, 103, 184, 174, + 226, 7, 15, 179, 200, 245, 11, 97, 61, 94, 128, 54, 79, 206, 111, 91, 195, 14, 30, 101, 143, + 233, 22, 194, 122, 188, 256, 108, 158, 155, 222, 182, 133, 28, 60, 202, 29, 209, 44, 131, + 244, 119, 255, 216, 59, 53, 187, 107, 9, 56, 120, 147, 58, 161, 88, 5, 231, 238, 253, 175, + 118, 106, 117, 214, 18, 112, 240, 37, 116, 65, 176, 10, 205, 219, 249, 93, 236, 212, 234, + 171, 36, 224, 223, 74, 232, 130, 95, 20, 153, 181, 241, 186, 215, 167, 211, 85, 72, 191, + 189, 148, 207, 3, 190, 40, 49, 105, 225, 115, 173, 77, 165, 170, 144, 125, 121, 39, 157, 6, + 123, 80, 98, 210, 193, 230, 89, 154, 73, 83, 31, 250, 242, 78, 57, 12, 246, 160, 196, 163, + 129, 203, 178, 51, 146, 166, 62, 243, 227, 156, 114, 24, 235, 63, 135, 69, 1, + ], + [ + 1, 150, 141, 76, 92, 179, 122, 53, 240, 20, 173, 250, 235, 41, 239, 127, 32, 174, 143, 119, + 117, 74, 49, 154, 227, 126, 139, 33, 67, 27, 195, 209, 253, 171, 207, 210, 146, 55, 26, 45, + 68, 177, 79, 28, 88, 93, 72, 6, 129, 75, 199, 38, 46, 218, 61, 155, 120, 10, 215, 125, 246, + 149, 248, 192, 16, 87, 200, 188, 187, 37, 153, 77, 242, 63, 198, 145, 162, 142, 226, 233, + 255, 214, 232, 105, 73, 156, 13, 151, 34, 217, 168, 14, 44, 175, 36, 3, 193, 166, 228, 19, + 23, 109, 159, 206, 60, 5, 236, 191, 123, 203, 124, 96, 8, 172, 100, 94, 222, 147, 205, 167, + 121, 160, 99, 201, 81, 71, 113, 245, 256, 107, 116, 181, 165, 78, 135, 204, 17, 237, 84, 7, + 22, 216, 18, 130, 225, 83, 114, 138, 140, 183, 208, 103, 30, 131, 118, 224, 190, 230, 62, + 48, 4, 86, 50, 47, 111, 202, 231, 212, 189, 80, 178, 229, 169, 164, 185, 251, 128, 182, 58, + 219, 211, 39, 196, 102, 137, 247, 42, 132, 11, 108, 9, 65, 241, 170, 57, 69, 70, 220, 104, + 180, 15, 194, 59, 112, 95, 115, 31, 24, 2, 43, 25, 152, 184, 101, 244, 106, 223, 40, 89, + 243, 213, 82, 221, 254, 64, 91, 29, 238, 234, 148, 98, 51, 197, 252, 21, 66, 134, 54, 133, + 161, 249, 85, 157, 163, 35, 110, 52, 90, 136, 97, 158, 56, 176, 186, 144, 12, 1, + ], + [ + 1, 151, 185, 179, 44, 219, 173, 166, 137, 127, 159, 108, 117, 191, 57, 126, 8, 180, 195, + 147, 95, 210, 99, 43, 68, 245, 244, 93, 165, 243, 199, 237, 64, 155, 18, 148, 246, 138, 21, + 87, 30, 161, 153, 230, 35, 145, 50, 97, 255, 212, 144, 156, 169, 76, 168, 182, 240, 3, 196, + 41, 23, 132, 143, 5, 241, 154, 124, 220, 67, 94, 59, 171, 121, 24, 26, 71, 184, 28, 116, 40, + 129, 204, 221, 218, 22, 238, 215, 83, 197, 192, 208, 54, 187, 224, 157, 63, 4, 90, 226, 202, + 176, 105, 178, 150, 34, 251, 122, 175, 211, 250, 228, 247, 32, 206, 9, 74, 123, 69, 139, + 172, 15, 209, 205, 115, 146, 201, 25, 177, 256, 106, 72, 78, 213, 38, 84, 91, 120, 130, 98, + 149, 140, 66, 200, 131, 249, 77, 62, 110, 162, 47, 158, 214, 189, 12, 13, 164, 92, 14, 58, + 20, 193, 102, 239, 109, 11, 119, 236, 170, 227, 96, 104, 27, 222, 112, 207, 160, 2, 45, 113, + 101, 88, 181, 89, 75, 17, 254, 61, 216, 234, 125, 114, 252, 16, 103, 133, 37, 190, 163, 198, + 86, 136, 233, 231, 186, 73, 229, 141, 217, 128, 53, 36, 39, 235, 19, 42, 174, 60, 65, 49, + 203, 70, 33, 100, 194, 253, 167, 31, 55, 81, 152, 79, 107, 223, 6, 135, 82, 46, 7, 29, 10, + 225, 51, 248, 183, 134, 188, 118, 85, 242, 48, 52, 142, 111, 56, 232, 80, 1, + ], + [ + 1, 152, 231, 160, 162, 209, 157, 220, 30, 191, 248, 174, 234, 102, 84, 175, 129, 76, 244, + 80, 81, 233, 207, 110, 15, 224, 124, 87, 117, 51, 42, 216, 193, 38, 122, 40, 169, 245, 232, + 55, 136, 112, 62, 172, 187, 154, 21, 108, 225, 19, 61, 20, 213, 251, 116, 156, 68, 56, 31, + 86, 222, 77, 139, 54, 241, 138, 159, 10, 235, 254, 58, 78, 34, 28, 144, 43, 111, 167, 198, + 27, 249, 69, 208, 5, 246, 127, 29, 39, 17, 14, 72, 150, 184, 212, 99, 142, 253, 163, 104, + 131, 123, 192, 143, 148, 137, 7, 36, 75, 92, 106, 178, 71, 255, 210, 52, 194, 190, 96, 200, + 74, 197, 132, 18, 166, 46, 53, 89, 164, 256, 105, 26, 97, 95, 48, 100, 37, 227, 66, 9, 83, + 23, 155, 173, 82, 128, 181, 13, 177, 176, 24, 50, 147, 242, 33, 133, 170, 140, 206, 215, 41, + 64, 219, 135, 217, 88, 12, 25, 202, 121, 145, 195, 85, 70, 103, 236, 149, 32, 238, 196, 237, + 44, 6, 141, 101, 189, 201, 226, 171, 35, 180, 118, 203, 16, 119, 98, 247, 22, 3, 199, 179, + 223, 229, 113, 214, 146, 90, 59, 230, 8, 188, 49, 252, 11, 130, 228, 218, 240, 243, 185, + 107, 73, 45, 158, 115, 4, 94, 153, 126, 134, 65, 114, 109, 120, 250, 221, 182, 165, 151, 79, + 186, 2, 47, 205, 63, 67, 161, 57, 183, 60, 125, 239, 91, 211, 204, 168, 93, 1, + ], + [ + 1, 153, 22, 25, 227, 36, 111, 21, 129, 205, 11, 141, 242, 18, 184, 139, 193, 231, 134, 199, + 121, 9, 92, 198, 225, 244, 67, 228, 189, 133, 46, 99, 241, 122, 162, 114, 223, 195, 23, 178, + 249, 61, 81, 57, 240, 226, 140, 89, 253, 159, 169, 157, 120, 113, 70, 173, 255, 208, 213, + 207, 60, 185, 35, 215, 256, 104, 235, 232, 30, 221, 146, 236, 128, 52, 246, 116, 15, 239, + 73, 118, 64, 26, 123, 58, 136, 248, 165, 59, 32, 13, 190, 29, 68, 124, 211, 158, 16, 135, + 95, 143, 34, 62, 234, 79, 8, 196, 176, 200, 17, 31, 117, 168, 4, 98, 88, 100, 137, 144, 187, + 84, 2, 49, 44, 50, 197, 72, 222, 42, 1, 153, 22, 25, 227, 36, 111, 21, 129, 205, 11, 141, + 242, 18, 184, 139, 193, 231, 134, 199, 121, 9, 92, 198, 225, 244, 67, 228, 189, 133, 46, 99, + 241, 122, 162, 114, 223, 195, 23, 178, 249, 61, 81, 57, 240, 226, 140, 89, 253, 159, 169, + 157, 120, 113, 70, 173, 255, 208, 213, 207, 60, 185, 35, 215, 256, 104, 235, 232, 30, 221, + 146, 236, 128, 52, 246, 116, 15, 239, 73, 118, 64, 26, 123, 58, 136, 248, 165, 59, 32, 13, + 190, 29, 68, 124, 211, 158, 16, 135, 95, 143, 34, 62, 234, 79, 8, 196, 176, 200, 17, 31, + 117, 168, 4, 98, 88, 100, 137, 144, 187, 84, 2, 49, 44, 50, 197, 72, 222, 42, 1, + ], + [ + 1, 154, 72, 37, 44, 94, 84, 86, 137, 24, 98, 186, 117, 28, 200, 217, 8, 204, 62, 39, 95, + 238, 158, 174, 68, 192, 13, 203, 165, 224, 58, 194, 64, 90, 239, 55, 246, 105, 236, 107, 30, + 251, 104, 82, 35, 250, 207, 10, 255, 206, 113, 183, 169, 69, 89, 85, 240, 209, 61, 142, 23, + 201, 114, 80, 241, 106, 133, 179, 67, 38, 198, 166, 121, 130, 231, 108, 184, 66, 141, 126, + 129, 77, 36, 147, 22, 47, 42, 43, 197, 12, 49, 93, 187, 14, 100, 237, 4, 102, 31, 148, 176, + 119, 79, 87, 34, 96, 135, 230, 211, 112, 29, 97, 32, 45, 248, 156, 123, 181, 118, 182, 15, + 254, 52, 41, 146, 125, 232, 5, 256, 103, 185, 220, 213, 163, 173, 171, 120, 233, 159, 71, + 140, 229, 57, 40, 249, 53, 195, 218, 162, 19, 99, 83, 189, 65, 244, 54, 92, 33, 199, 63, + 193, 167, 18, 202, 11, 152, 21, 150, 227, 6, 153, 175, 222, 7, 50, 247, 2, 51, 144, 74, 88, + 188, 168, 172, 17, 48, 196, 115, 234, 56, 143, 177, 16, 151, 124, 78, 190, 219, 59, 91, 136, + 127, 26, 149, 73, 191, 116, 131, 128, 180, 221, 110, 235, 210, 215, 214, 60, 245, 208, 164, + 70, 243, 157, 20, 253, 155, 226, 109, 81, 138, 178, 170, 223, 161, 122, 27, 46, 145, 228, + 160, 225, 212, 9, 101, 134, 76, 139, 75, 242, 3, 205, 216, 111, 132, 25, 252, 1, + ], + [ + 1, 155, 124, 202, 213, 119, 198, 107, 137, 161, 26, 175, 140, 112, 141, 10, 8, 212, 221, 74, + 162, 181, 42, 85, 68, 3, 208, 115, 92, 125, 100, 80, 64, 154, 226, 78, 11, 163, 79, 166, 30, + 24, 122, 149, 222, 229, 29, 126, 255, 204, 9, 110, 88, 19, 118, 43, 240, 192, 205, 164, 234, + 33, 232, 237, 241, 90, 72, 109, 190, 152, 173, 87, 121, 251, 98, 27, 73, 7, 57, 97, 129, + 206, 62, 101, 235, 188, 99, 182, 197, 209, 13, 216, 70, 56, 199, 5, 4, 106, 239, 37, 81, + 219, 21, 171, 34, 130, 104, 186, 46, 191, 50, 40, 32, 77, 113, 39, 134, 210, 168, 83, 15, + 12, 61, 203, 111, 243, 143, 63, 256, 102, 133, 55, 44, 138, 59, 150, 120, 96, 231, 82, 117, + 145, 116, 247, 249, 45, 36, 183, 95, 76, 215, 172, 189, 254, 49, 142, 165, 132, 157, 177, + 193, 103, 31, 179, 246, 94, 178, 91, 227, 233, 135, 108, 35, 28, 228, 131, 2, 53, 248, 147, + 169, 238, 139, 214, 17, 65, 52, 93, 23, 224, 25, 20, 16, 167, 185, 148, 67, 105, 84, 170, + 136, 6, 159, 230, 184, 250, 200, 160, 128, 51, 195, 156, 22, 69, 158, 75, 60, 48, 244, 41, + 187, 201, 58, 252, 253, 151, 18, 220, 176, 38, 236, 86, 223, 127, 153, 71, 211, 66, 207, + 217, 225, 180, 144, 218, 123, 47, 89, 174, 242, 245, 196, 54, 146, 14, 114, 194, 1, + ], + [ + 1, 156, 178, 12, 73, 80, 144, 105, 189, 186, 232, 212, 176, 214, 231, 56, 255, 202, 158, + 233, 111, 97, 226, 47, 136, 142, 50, 90, 162, 86, 52, 145, 4, 110, 198, 48, 35, 63, 62, 163, + 242, 230, 157, 77, 190, 85, 153, 224, 249, 37, 118, 161, 187, 131, 133, 188, 30, 54, 200, + 103, 134, 87, 208, 66, 16, 183, 21, 192, 140, 252, 248, 138, 197, 149, 114, 51, 246, 83, 98, + 125, 225, 148, 215, 130, 234, 10, 18, 238, 120, 216, 29, 155, 22, 91, 61, 7, 64, 218, 84, + 254, 46, 237, 221, 38, 17, 82, 199, 204, 213, 75, 135, 243, 129, 78, 89, 6, 165, 40, 72, + 181, 223, 93, 116, 106, 88, 107, 244, 28, 256, 101, 79, 245, 184, 177, 113, 152, 68, 71, 25, + 45, 81, 43, 26, 201, 2, 55, 99, 24, 146, 160, 31, 210, 121, 115, 207, 167, 95, 171, 205, + 112, 253, 147, 59, 209, 222, 194, 195, 94, 15, 27, 100, 180, 67, 172, 104, 33, 8, 220, 139, + 96, 70, 126, 124, 69, 227, 203, 57, 154, 123, 170, 49, 191, 241, 74, 236, 65, 117, 5, 9, + 119, 60, 108, 143, 206, 11, 174, 159, 132, 32, 109, 42, 127, 23, 247, 239, 19, 137, 41, 228, + 102, 235, 166, 196, 250, 193, 39, 173, 3, 211, 20, 36, 219, 240, 175, 58, 53, 44, 182, 122, + 14, 128, 179, 168, 251, 92, 217, 185, 76, 34, 164, 141, 151, 169, 150, 13, 229, 1, + ], + [ + 1, 157, 234, 244, 15, 42, 169, 62, 225, 116, 222, 159, 34, 198, 246, 72, 253, 143, 92, 52, + 197, 89, 95, 9, 128, 50, 140, 135, 121, 236, 44, 226, 16, 199, 146, 49, 240, 158, 134, 221, + 2, 57, 211, 231, 30, 84, 81, 124, 193, 232, 187, 61, 68, 139, 235, 144, 249, 29, 184, 104, + 137, 178, 190, 18, 256, 100, 23, 13, 242, 215, 88, 195, 32, 141, 35, 98, 223, 59, 11, 185, + 4, 114, 165, 205, 60, 168, 162, 248, 129, 207, 117, 122, 136, 21, 213, 31, 241, 58, 111, + 208, 17, 99, 123, 36, 255, 200, 46, 26, 227, 173, 176, 133, 64, 25, 70, 196, 189, 118, 22, + 113, 8, 228, 73, 153, 120, 79, 67, 239, 1, 157, 234, 244, 15, 42, 169, 62, 225, 116, 222, + 159, 34, 198, 246, 72, 253, 143, 92, 52, 197, 89, 95, 9, 128, 50, 140, 135, 121, 236, 44, + 226, 16, 199, 146, 49, 240, 158, 134, 221, 2, 57, 211, 231, 30, 84, 81, 124, 193, 232, 187, + 61, 68, 139, 235, 144, 249, 29, 184, 104, 137, 178, 190, 18, 256, 100, 23, 13, 242, 215, 88, + 195, 32, 141, 35, 98, 223, 59, 11, 185, 4, 114, 165, 205, 60, 168, 162, 248, 129, 207, 117, + 122, 136, 21, 213, 31, 241, 58, 111, 208, 17, 99, 123, 36, 255, 200, 46, 26, 227, 173, 176, + 133, 64, 25, 70, 196, 189, 118, 22, 113, 8, 228, 73, 153, 120, 79, 67, 239, 1, + ], + [ + 1, 158, 35, 133, 197, 29, 213, 244, 2, 59, 70, 9, 137, 58, 169, 231, 4, 118, 140, 18, 17, + 116, 81, 205, 8, 236, 23, 36, 34, 232, 162, 153, 16, 215, 46, 72, 68, 207, 67, 49, 32, 173, + 92, 144, 136, 157, 134, 98, 64, 89, 184, 31, 15, 57, 11, 196, 128, 178, 111, 62, 30, 114, + 22, 135, 256, 99, 222, 124, 60, 228, 44, 13, 255, 198, 187, 248, 120, 199, 88, 26, 253, 139, + 117, 239, 240, 141, 176, 52, 249, 21, 234, 221, 223, 25, 95, 104, 241, 42, 211, 185, 189, + 50, 190, 208, 225, 84, 165, 113, 121, 100, 123, 159, 193, 168, 73, 226, 242, 200, 246, 61, + 129, 79, 146, 195, 227, 143, 235, 122, 1, 158, 35, 133, 197, 29, 213, 244, 2, 59, 70, 9, + 137, 58, 169, 231, 4, 118, 140, 18, 17, 116, 81, 205, 8, 236, 23, 36, 34, 232, 162, 153, 16, + 215, 46, 72, 68, 207, 67, 49, 32, 173, 92, 144, 136, 157, 134, 98, 64, 89, 184, 31, 15, 57, + 11, 196, 128, 178, 111, 62, 30, 114, 22, 135, 256, 99, 222, 124, 60, 228, 44, 13, 255, 198, + 187, 248, 120, 199, 88, 26, 253, 139, 117, 239, 240, 141, 176, 52, 249, 21, 234, 221, 223, + 25, 95, 104, 241, 42, 211, 185, 189, 50, 190, 208, 225, 84, 165, 113, 121, 100, 123, 159, + 193, 168, 73, 226, 242, 200, 246, 61, 129, 79, 146, 195, 227, 143, 235, 122, 1, + ], + [ + 1, 159, 95, 199, 30, 144, 23, 59, 129, 208, 176, 228, 15, 72, 140, 158, 193, 104, 88, 114, + 136, 36, 70, 79, 225, 52, 44, 57, 68, 18, 35, 168, 241, 26, 22, 157, 34, 9, 146, 84, 249, + 13, 11, 207, 17, 133, 73, 42, 253, 135, 134, 232, 137, 195, 165, 21, 255, 196, 67, 116, 197, + 226, 211, 139, 256, 98, 162, 58, 227, 113, 234, 198, 128, 49, 81, 29, 242, 185, 117, 99, 64, + 153, 169, 143, 121, 221, 187, 178, 32, 205, 213, 200, 189, 239, 222, 89, 16, 231, 235, 100, + 223, 248, 111, 173, 8, 244, 246, 50, 240, 124, 184, 215, 4, 122, 123, 25, 120, 62, 92, 236, + 2, 61, 190, 141, 60, 31, 46, 118, 1, 159, 95, 199, 30, 144, 23, 59, 129, 208, 176, 228, 15, + 72, 140, 158, 193, 104, 88, 114, 136, 36, 70, 79, 225, 52, 44, 57, 68, 18, 35, 168, 241, 26, + 22, 157, 34, 9, 146, 84, 249, 13, 11, 207, 17, 133, 73, 42, 253, 135, 134, 232, 137, 195, + 165, 21, 255, 196, 67, 116, 197, 226, 211, 139, 256, 98, 162, 58, 227, 113, 234, 198, 128, + 49, 81, 29, 242, 185, 117, 99, 64, 153, 169, 143, 121, 221, 187, 178, 32, 205, 213, 200, + 189, 239, 222, 89, 16, 231, 235, 100, 223, 248, 111, 173, 8, 244, 246, 50, 240, 124, 184, + 215, 4, 122, 123, 25, 120, 62, 92, 236, 2, 61, 190, 141, 60, 31, 46, 118, 1, + ], + [ + 1, 160, 157, 191, 234, 175, 244, 233, 15, 87, 42, 38, 169, 55, 62, 154, 225, 20, 116, 56, + 222, 54, 159, 254, 34, 43, 198, 69, 246, 39, 72, 212, 253, 131, 143, 7, 92, 71, 52, 96, 197, + 166, 89, 105, 95, 37, 9, 155, 128, 177, 50, 33, 140, 41, 135, 12, 121, 85, 236, 238, 44, + 101, 226, 180, 16, 247, 199, 229, 146, 230, 49, 130, 240, 107, 158, 94, 134, 109, 221, 151, + 2, 63, 57, 125, 211, 93, 231, 209, 30, 174, 84, 76, 81, 110, 124, 51, 193, 40, 232, 112, + 187, 108, 61, 251, 68, 86, 139, 138, 235, 78, 144, 167, 249, 5, 29, 14, 184, 142, 104, 192, + 137, 75, 178, 210, 190, 74, 18, 53, 256, 97, 100, 66, 23, 82, 13, 24, 242, 170, 215, 219, + 88, 202, 195, 103, 32, 237, 141, 201, 35, 203, 98, 3, 223, 214, 59, 188, 11, 218, 185, 45, + 4, 126, 114, 250, 165, 186, 205, 161, 60, 91, 168, 152, 162, 220, 248, 102, 129, 80, 207, + 224, 117, 216, 122, 245, 136, 172, 21, 19, 213, 156, 31, 77, 241, 10, 58, 28, 111, 27, 208, + 127, 17, 150, 99, 163, 123, 148, 36, 106, 255, 194, 200, 132, 46, 164, 26, 48, 227, 83, 173, + 181, 176, 147, 133, 206, 64, 217, 25, 145, 70, 149, 196, 6, 189, 171, 118, 119, 22, 179, + 113, 90, 8, 252, 228, 243, 73, 115, 153, 65, 120, 182, 79, 47, 67, 183, 239, 204, 1, + ], + [ + 1, 161, 221, 115, 11, 229, 118, 237, 121, 206, 13, 37, 46, 210, 143, 150, 249, 254, 31, 108, + 169, 224, 84, 160, 60, 151, 153, 218, 146, 119, 141, 85, 64, 24, 9, 164, 190, 7, 99, 5, 34, + 77, 61, 55, 117, 76, 157, 91, 2, 65, 185, 230, 22, 201, 236, 217, 242, 155, 26, 74, 92, 163, + 29, 43, 241, 251, 62, 216, 81, 191, 168, 63, 120, 45, 49, 179, 35, 238, 25, 170, 128, 48, + 18, 71, 123, 14, 198, 10, 68, 154, 122, 110, 234, 152, 57, 182, 4, 130, 113, 203, 44, 145, + 215, 177, 227, 53, 52, 148, 184, 69, 58, 86, 225, 245, 124, 175, 162, 125, 79, 126, 240, 90, + 98, 101, 70, 219, 50, 83, 256, 96, 36, 142, 246, 28, 139, 20, 136, 51, 244, 220, 211, 47, + 114, 107, 8, 3, 226, 149, 88, 33, 173, 97, 197, 106, 104, 39, 111, 138, 116, 172, 193, 233, + 248, 93, 67, 250, 158, 252, 223, 180, 196, 202, 140, 181, 100, 166, 255, 192, 72, 27, 235, + 56, 21, 40, 15, 102, 231, 183, 165, 94, 228, 214, 16, 6, 195, 41, 176, 66, 89, 194, 137, + 212, 208, 78, 222, 19, 232, 87, 129, 209, 239, 186, 134, 243, 59, 247, 189, 103, 135, 147, + 23, 105, 200, 75, 253, 127, 144, 54, 213, 112, 42, 80, 30, 204, 205, 109, 73, 188, 199, 171, + 32, 12, 133, 82, 95, 132, 178, 131, 17, 167, 159, 156, 187, 38, 207, 174, 1, + ], + [ + 1, 162, 30, 234, 129, 81, 15, 117, 193, 169, 136, 187, 225, 213, 68, 222, 241, 235, 34, 111, + 249, 246, 17, 184, 253, 123, 137, 92, 255, 190, 197, 46, 256, 95, 227, 23, 128, 176, 242, + 140, 64, 88, 121, 70, 32, 44, 189, 35, 16, 22, 223, 146, 8, 11, 240, 73, 4, 134, 120, 165, + 2, 67, 60, 211, 1, 162, 30, 234, 129, 81, 15, 117, 193, 169, 136, 187, 225, 213, 68, 222, + 241, 235, 34, 111, 249, 246, 17, 184, 253, 123, 137, 92, 255, 190, 197, 46, 256, 95, 227, + 23, 128, 176, 242, 140, 64, 88, 121, 70, 32, 44, 189, 35, 16, 22, 223, 146, 8, 11, 240, 73, + 4, 134, 120, 165, 2, 67, 60, 211, 1, 162, 30, 234, 129, 81, 15, 117, 193, 169, 136, 187, + 225, 213, 68, 222, 241, 235, 34, 111, 249, 246, 17, 184, 253, 123, 137, 92, 255, 190, 197, + 46, 256, 95, 227, 23, 128, 176, 242, 140, 64, 88, 121, 70, 32, 44, 189, 35, 16, 22, 223, + 146, 8, 11, 240, 73, 4, 134, 120, 165, 2, 67, 60, 211, 1, 162, 30, 234, 129, 81, 15, 117, + 193, 169, 136, 187, 225, 213, 68, 222, 241, 235, 34, 111, 249, 246, 17, 184, 253, 123, 137, + 92, 255, 190, 197, 46, 256, 95, 227, 23, 128, 176, 242, 140, 64, 88, 121, 70, 32, 44, 189, + 35, 16, 22, 223, 146, 8, 11, 240, 73, 4, 134, 120, 165, 2, 67, 60, 211, 1, + ], + [ + 1, 163, 98, 40, 95, 65, 58, 202, 30, 7, 113, 172, 23, 151, 198, 149, 129, 210, 49, 20, 176, + 161, 29, 101, 15, 132, 185, 86, 140, 204, 99, 203, 193, 105, 153, 10, 88, 209, 143, 179, + 136, 66, 221, 43, 70, 102, 178, 230, 225, 181, 205, 5, 44, 233, 200, 218, 68, 33, 239, 150, + 35, 51, 89, 115, 241, 219, 231, 131, 22, 245, 100, 109, 34, 145, 248, 75, 146, 154, 173, + 186, 249, 238, 244, 194, 11, 251, 50, 183, 17, 201, 124, 166, 73, 77, 215, 93, 253, 119, + 122, 97, 134, 254, 25, 220, 137, 229, 62, 83, 165, 167, 236, 175, 255, 188, 61, 177, 67, + 127, 141, 110, 197, 243, 31, 170, 211, 212, 118, 216, 256, 94, 159, 217, 162, 192, 199, 55, + 227, 250, 144, 85, 234, 106, 59, 108, 128, 47, 208, 237, 81, 96, 228, 156, 242, 125, 72, + 171, 117, 53, 158, 54, 64, 152, 104, 247, 169, 48, 114, 78, 121, 191, 36, 214, 187, 155, 79, + 27, 32, 76, 52, 252, 213, 24, 57, 39, 189, 224, 18, 107, 222, 206, 168, 142, 16, 38, 26, + 126, 235, 12, 157, 148, 223, 112, 9, 182, 111, 103, 84, 71, 8, 19, 13, 63, 246, 6, 207, 74, + 240, 56, 133, 91, 184, 180, 42, 164, 4, 138, 135, 160, 123, 3, 232, 37, 120, 28, 195, 174, + 92, 90, 21, 82, 2, 69, 196, 80, 190, 130, 116, 147, 60, 14, 226, 87, 46, 45, 139, 41, 1, + ], + [ + 1, 164, 168, 53, 211, 166, 239, 132, 60, 74, 57, 96, 67, 194, 205, 210, 2, 71, 79, 106, 165, + 75, 221, 7, 120, 148, 114, 192, 134, 131, 153, 163, 4, 142, 158, 212, 73, 150, 185, 14, 240, + 39, 228, 127, 11, 5, 49, 69, 8, 27, 59, 167, 146, 43, 113, 28, 223, 78, 199, 254, 22, 10, + 98, 138, 16, 54, 118, 77, 35, 86, 226, 56, 189, 156, 141, 251, 44, 20, 196, 19, 32, 108, + 236, 154, 70, 172, 195, 112, 121, 55, 25, 245, 88, 40, 135, 38, 64, 216, 215, 51, 140, 87, + 133, 224, 242, 110, 50, 233, 176, 80, 13, 76, 128, 175, 173, 102, 23, 174, 9, 191, 227, 220, + 100, 209, 95, 160, 26, 152, 256, 93, 89, 204, 46, 91, 18, 125, 197, 183, 200, 161, 190, 63, + 52, 47, 255, 186, 178, 151, 92, 182, 36, 250, 137, 109, 143, 65, 123, 126, 104, 94, 253, + 115, 99, 45, 184, 107, 72, 243, 17, 218, 29, 130, 246, 252, 208, 188, 249, 230, 198, 90, + 111, 214, 144, 229, 34, 179, 58, 3, 235, 247, 159, 119, 241, 203, 139, 180, 222, 171, 31, + 201, 68, 101, 116, 6, 213, 237, 61, 238, 225, 149, 21, 103, 187, 85, 62, 145, 136, 202, 232, + 12, 169, 217, 122, 219, 193, 41, 42, 206, 117, 170, 124, 33, 15, 147, 207, 24, 81, 177, 244, + 181, 129, 82, 84, 155, 234, 83, 248, 66, 30, 37, 157, 48, 162, 97, 231, 105, 1, + ], + [ + 1, 165, 240, 22, 32, 140, 227, 190, 253, 111, 68, 169, 129, 211, 120, 11, 16, 70, 242, 95, + 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, 121, 176, 256, 92, 17, 235, 225, 117, 30, 67, + 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, 15, 162, 2, 73, 223, 44, 64, 23, 197, 123, + 249, 222, 136, 81, 1, 165, 240, 22, 32, 140, 227, 190, 253, 111, 68, 169, 129, 211, 120, 11, + 16, 70, 242, 95, 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, 121, 176, 256, 92, 17, 235, + 225, 117, 30, 67, 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, 15, 162, 2, 73, 223, 44, 64, + 23, 197, 123, 249, 222, 136, 81, 1, 165, 240, 22, 32, 140, 227, 190, 253, 111, 68, 169, 129, + 211, 120, 11, 16, 70, 242, 95, 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, 121, 176, 256, + 92, 17, 235, 225, 117, 30, 67, 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, 15, 162, 2, 73, + 223, 44, 64, 23, 197, 123, 249, 222, 136, 81, 1, 165, 240, 22, 32, 140, 227, 190, 253, 111, + 68, 169, 129, 211, 120, 11, 16, 70, 242, 95, 255, 184, 34, 213, 193, 234, 60, 134, 8, 35, + 121, 176, 256, 92, 17, 235, 225, 117, 30, 67, 4, 146, 189, 88, 128, 46, 137, 246, 241, 187, + 15, 162, 2, 73, 223, 44, 64, 23, 197, 123, 249, 222, 136, 81, 1, + ], + [ + 1, 166, 57, 210, 165, 148, 153, 212, 240, 5, 59, 28, 22, 54, 226, 251, 32, 172, 25, 38, 140, + 110, 13, 102, 227, 160, 89, 125, 190, 186, 36, 65, 253, 107, 29, 188, 111, 179, 159, 180, + 68, 237, 21, 145, 169, 41, 124, 24, 129, 83, 157, 105, 211, 74, 205, 106, 120, 131, 158, 14, + 11, 27, 113, 254, 16, 86, 141, 19, 70, 55, 135, 51, 242, 80, 173, 191, 95, 93, 18, 161, 255, + 182, 143, 94, 184, 218, 208, 90, 34, 247, 139, 201, 213, 149, 62, 12, 193, 170, 207, 181, + 234, 37, 231, 53, 60, 194, 79, 7, 134, 142, 185, 127, 8, 43, 199, 138, 35, 156, 196, 154, + 121, 40, 215, 224, 176, 175, 9, 209, 256, 91, 200, 47, 92, 109, 104, 45, 17, 252, 198, 229, + 235, 203, 31, 6, 225, 85, 232, 219, 117, 147, 244, 155, 30, 97, 168, 132, 67, 71, 221, 192, + 4, 150, 228, 69, 146, 78, 98, 77, 189, 20, 236, 112, 88, 216, 133, 233, 128, 174, 100, 152, + 46, 183, 52, 151, 137, 126, 99, 243, 246, 230, 144, 3, 241, 171, 116, 238, 187, 202, 122, + 206, 15, 177, 84, 66, 162, 164, 239, 96, 2, 75, 114, 163, 73, 39, 49, 167, 223, 10, 118, 56, + 44, 108, 195, 245, 64, 87, 50, 76, 23, 220, 26, 204, 197, 63, 178, 250, 123, 115, 72, 130, + 249, 214, 58, 119, 222, 101, 61, 103, 136, 217, 42, 33, 81, 82, 248, 48, 1, + ], + [ + 1, 167, 133, 109, 213, 105, 59, 87, 137, 6, 231, 27, 140, 250, 116, 97, 8, 51, 36, 101, 162, + 69, 215, 182, 68, 48, 49, 216, 92, 201, 157, 5, 64, 151, 31, 37, 11, 38, 178, 171, 30, 127, + 135, 186, 222, 66, 228, 40, 255, 180, 248, 39, 88, 47, 139, 83, 240, 245, 52, 203, 234, 14, + 25, 63, 241, 155, 185, 55, 190, 119, 84, 150, 121, 161, 159, 82, 73, 112, 200, 247, 129, + 212, 195, 183, 235, 181, 158, 172, 197, 3, 244, 142, 70, 125, 58, 177, 4, 154, 18, 179, 81, + 163, 236, 91, 34, 24, 153, 108, 46, 229, 207, 131, 32, 204, 144, 147, 134, 19, 89, 214, 15, + 192, 196, 93, 111, 33, 114, 20, 256, 90, 124, 148, 44, 152, 198, 170, 120, 251, 26, 230, + 117, 7, 141, 160, 249, 206, 221, 156, 95, 188, 42, 75, 189, 209, 208, 41, 165, 56, 100, 252, + 193, 106, 226, 220, 246, 219, 79, 86, 227, 130, 122, 71, 35, 191, 29, 217, 2, 77, 9, 218, + 169, 210, 118, 174, 17, 12, 205, 54, 23, 243, 232, 194, 16, 102, 72, 202, 67, 138, 173, 107, + 136, 96, 98, 175, 184, 145, 57, 10, 128, 45, 62, 74, 22, 76, 99, 85, 60, 254, 13, 115, 187, + 132, 199, 80, 253, 103, 239, 78, 176, 94, 21, 166, 223, 233, 104, 149, 211, 28, 50, 126, + 225, 53, 113, 110, 123, 238, 168, 43, 242, 65, 61, 164, 146, 224, 143, 237, 1, + ], + [ + 1, 168, 211, 239, 60, 57, 67, 205, 2, 79, 165, 221, 120, 114, 134, 153, 4, 158, 73, 185, + 240, 228, 11, 49, 8, 59, 146, 113, 223, 199, 22, 98, 16, 118, 35, 226, 189, 141, 44, 196, + 32, 236, 70, 195, 121, 25, 88, 135, 64, 215, 140, 133, 242, 50, 176, 13, 128, 173, 23, 9, + 227, 100, 95, 26, 256, 89, 46, 18, 197, 200, 190, 52, 255, 178, 92, 36, 137, 143, 123, 104, + 253, 99, 184, 72, 17, 29, 246, 208, 249, 198, 111, 144, 34, 58, 235, 159, 241, 139, 222, 31, + 68, 116, 213, 61, 225, 21, 187, 62, 136, 232, 169, 122, 193, 42, 117, 124, 15, 207, 81, 244, + 129, 84, 234, 248, 30, 157, 162, 231, 1, 168, 211, 239, 60, 57, 67, 205, 2, 79, 165, 221, + 120, 114, 134, 153, 4, 158, 73, 185, 240, 228, 11, 49, 8, 59, 146, 113, 223, 199, 22, 98, + 16, 118, 35, 226, 189, 141, 44, 196, 32, 236, 70, 195, 121, 25, 88, 135, 64, 215, 140, 133, + 242, 50, 176, 13, 128, 173, 23, 9, 227, 100, 95, 26, 256, 89, 46, 18, 197, 200, 190, 52, + 255, 178, 92, 36, 137, 143, 123, 104, 253, 99, 184, 72, 17, 29, 246, 208, 249, 198, 111, + 144, 34, 58, 235, 159, 241, 139, 222, 31, 68, 116, 213, 61, 225, 21, 187, 62, 136, 232, 169, + 122, 193, 42, 117, 124, 15, 207, 81, 244, 129, 84, 234, 248, 30, 157, 162, 231, 1, + ], + [ + 1, 169, 34, 92, 128, 44, 240, 211, 193, 235, 137, 23, 32, 11, 60, 117, 241, 123, 227, 70, 8, + 67, 15, 222, 253, 95, 121, 146, 2, 81, 68, 184, 256, 88, 223, 165, 129, 213, 17, 46, 64, 22, + 120, 234, 225, 246, 197, 140, 16, 134, 30, 187, 249, 190, 242, 35, 4, 162, 136, 111, 255, + 176, 189, 73, 1, 169, 34, 92, 128, 44, 240, 211, 193, 235, 137, 23, 32, 11, 60, 117, 241, + 123, 227, 70, 8, 67, 15, 222, 253, 95, 121, 146, 2, 81, 68, 184, 256, 88, 223, 165, 129, + 213, 17, 46, 64, 22, 120, 234, 225, 246, 197, 140, 16, 134, 30, 187, 249, 190, 242, 35, 4, + 162, 136, 111, 255, 176, 189, 73, 1, 169, 34, 92, 128, 44, 240, 211, 193, 235, 137, 23, 32, + 11, 60, 117, 241, 123, 227, 70, 8, 67, 15, 222, 253, 95, 121, 146, 2, 81, 68, 184, 256, 88, + 223, 165, 129, 213, 17, 46, 64, 22, 120, 234, 225, 246, 197, 140, 16, 134, 30, 187, 249, + 190, 242, 35, 4, 162, 136, 111, 255, 176, 189, 73, 1, 169, 34, 92, 128, 44, 240, 211, 193, + 235, 137, 23, 32, 11, 60, 117, 241, 123, 227, 70, 8, 67, 15, 222, 253, 95, 121, 146, 2, 81, + 68, 184, 256, 88, 223, 165, 129, 213, 17, 46, 64, 22, 120, 234, 225, 246, 197, 140, 16, 134, + 30, 187, 249, 190, 242, 35, 4, 162, 136, 111, 255, 176, 189, 73, 1, + ], + [ + 1, 170, 116, 188, 92, 220, 135, 77, 240, 194, 84, 145, 235, 115, 18, 233, 32, 43, 114, 105, + 117, 101, 208, 151, 227, 40, 118, 14, 67, 82, 62, 3, 253, 91, 50, 19, 146, 148, 231, 206, + 68, 252, 178, 191, 88, 54, 185, 96, 129, 85, 58, 94, 46, 110, 196, 167, 120, 97, 42, 201, + 246, 186, 9, 245, 16, 150, 57, 181, 187, 179, 104, 204, 242, 20, 59, 7, 162, 41, 31, 130, + 255, 174, 25, 138, 73, 74, 244, 103, 34, 126, 89, 224, 44, 27, 221, 48, 193, 171, 29, 47, + 23, 55, 98, 212, 60, 177, 21, 229, 123, 93, 133, 251, 8, 75, 157, 219, 222, 218, 52, 102, + 121, 10, 158, 132, 81, 149, 144, 65, 256, 87, 141, 69, 165, 37, 122, 180, 17, 63, 173, 112, + 22, 142, 239, 24, 225, 214, 143, 152, 140, 156, 49, 106, 30, 217, 139, 243, 190, 175, 195, + 254, 4, 166, 207, 238, 111, 109, 26, 51, 189, 5, 79, 66, 169, 203, 72, 161, 128, 172, 199, + 163, 211, 147, 61, 90, 137, 160, 215, 56, 11, 71, 248, 12, 241, 107, 200, 76, 70, 78, 153, + 53, 15, 237, 198, 250, 95, 216, 226, 127, 2, 83, 232, 119, 184, 183, 13, 154, 223, 131, 168, + 33, 213, 230, 36, 209, 64, 86, 228, 210, 234, 202, 159, 45, 197, 80, 236, 28, 134, 164, 124, + 6, 249, 182, 100, 38, 35, 39, 205, 155, 136, 247, 99, 125, 176, 108, 113, 192, 1, + ], + [ + 1, 171, 200, 19, 165, 202, 104, 51, 240, 177, 198, 191, 22, 164, 31, 161, 32, 75, 232, 94, + 140, 39, 244, 90, 227, 10, 168, 201, 190, 108, 221, 12, 253, 87, 228, 181, 111, 220, 98, 53, + 68, 63, 236, 7, 169, 115, 133, 127, 129, 214, 100, 138, 211, 101, 52, 154, 120, 217, 99, + 224, 11, 82, 144, 209, 16, 166, 116, 47, 70, 148, 122, 45, 242, 5, 84, 229, 95, 54, 239, 6, + 255, 172, 114, 219, 184, 110, 49, 155, 34, 160, 118, 132, 213, 186, 195, 192, 193, 107, 50, + 69, 234, 179, 26, 77, 60, 237, 178, 112, 134, 41, 72, 233, 8, 83, 58, 152, 35, 74, 61, 151, + 121, 131, 42, 243, 176, 27, 248, 3, 256, 86, 57, 238, 92, 55, 153, 206, 17, 80, 59, 66, 235, + 93, 226, 96, 225, 182, 25, 163, 117, 218, 13, 167, 30, 247, 89, 56, 67, 149, 36, 245, 4, + 170, 29, 76, 146, 37, 159, 204, 189, 194, 21, 250, 88, 142, 124, 130, 128, 43, 157, 119, 46, + 156, 205, 103, 137, 40, 158, 33, 246, 175, 113, 48, 241, 91, 141, 210, 187, 109, 135, 212, + 15, 252, 173, 28, 162, 203, 18, 251, 2, 85, 143, 38, 73, 147, 208, 102, 223, 97, 139, 125, + 44, 71, 62, 65, 64, 150, 207, 188, 23, 78, 231, 180, 197, 20, 79, 145, 123, 216, 185, 24, + 249, 174, 199, 105, 222, 183, 196, 106, 136, 126, 215, 14, 81, 230, 9, 254, 1, + ], + [ + 1, 172, 29, 105, 70, 218, 231, 154, 17, 97, 236, 243, 162, 108, 72, 48, 32, 107, 157, 19, + 184, 37, 196, 45, 30, 20, 99, 66, 44, 115, 248, 251, 253, 83, 141, 94, 234, 156, 104, 155, + 189, 126, 84, 56, 123, 82, 226, 65, 129, 86, 143, 181, 35, 109, 244, 77, 137, 177, 118, 250, + 81, 54, 36, 24, 16, 182, 207, 138, 92, 147, 98, 151, 15, 10, 178, 33, 22, 186, 124, 254, + 255, 170, 199, 47, 117, 78, 52, 206, 223, 63, 42, 28, 190, 41, 113, 161, 193, 43, 200, 219, + 146, 183, 122, 167, 197, 217, 59, 125, 169, 27, 18, 12, 8, 91, 232, 69, 46, 202, 49, 204, + 136, 5, 89, 145, 11, 93, 62, 127, 256, 85, 228, 152, 187, 39, 26, 103, 240, 160, 21, 14, 95, + 149, 185, 209, 225, 150, 100, 238, 73, 220, 61, 212, 227, 237, 158, 191, 213, 142, 9, 6, 4, + 174, 116, 163, 23, 101, 153, 102, 68, 131, 173, 201, 134, 175, 31, 192, 128, 171, 114, 76, + 222, 148, 13, 180, 120, 80, 139, 7, 176, 203, 221, 233, 241, 75, 50, 119, 165, 110, 159, + 106, 242, 247, 79, 224, 235, 71, 133, 3, 2, 87, 58, 210, 140, 179, 205, 51, 34, 194, 215, + 229, 67, 216, 144, 96, 64, 214, 57, 38, 111, 74, 135, 90, 60, 40, 198, 132, 88, 230, 239, + 245, 249, 166, 25, 188, 211, 55, 208, 53, 121, 252, 168, 112, 246, 164, 195, 130, 1, + ], + [ + 1, 173, 117, 195, 68, 199, 246, 153, 255, 168, 23, 124, 121, 116, 22, 208, 4, 178, 211, 9, + 15, 25, 213, 98, 249, 158, 92, 239, 227, 207, 88, 61, 16, 198, 73, 36, 60, 100, 81, 135, + 225, 118, 111, 185, 137, 57, 95, 244, 64, 21, 35, 144, 240, 143, 67, 26, 129, 215, 187, 226, + 34, 228, 123, 205, 256, 84, 140, 62, 189, 58, 11, 104, 2, 89, 234, 133, 136, 141, 235, 49, + 253, 79, 46, 248, 242, 232, 44, 159, 8, 99, 165, 18, 30, 50, 169, 196, 241, 59, 184, 221, + 197, 157, 176, 122, 32, 139, 146, 72, 120, 200, 162, 13, 193, 236, 222, 113, 17, 114, 190, + 231, 128, 42, 70, 31, 223, 29, 134, 52, 1, 173, 117, 195, 68, 199, 246, 153, 255, 168, 23, + 124, 121, 116, 22, 208, 4, 178, 211, 9, 15, 25, 213, 98, 249, 158, 92, 239, 227, 207, 88, + 61, 16, 198, 73, 36, 60, 100, 81, 135, 225, 118, 111, 185, 137, 57, 95, 244, 64, 21, 35, + 144, 240, 143, 67, 26, 129, 215, 187, 226, 34, 228, 123, 205, 256, 84, 140, 62, 189, 58, 11, + 104, 2, 89, 234, 133, 136, 141, 235, 49, 253, 79, 46, 248, 242, 232, 44, 159, 8, 99, 165, + 18, 30, 50, 169, 196, 241, 59, 184, 221, 197, 157, 176, 122, 32, 139, 146, 72, 120, 200, + 162, 13, 193, 236, 222, 113, 17, 114, 190, 231, 128, 42, 70, 31, 223, 29, 134, 52, 1, + ], + [ + 1, 174, 207, 38, 187, 156, 159, 167, 17, 131, 178, 132, 95, 82, 133, 12, 32, 171, 199, 188, + 73, 109, 205, 204, 30, 80, 42, 112, 213, 54, 144, 127, 253, 75, 200, 105, 23, 147, 135, 103, + 189, 247, 59, 243, 134, 186, 239, 209, 129, 87, 232, 19, 222, 78, 208, 212, 137, 194, 89, + 66, 176, 41, 195, 6, 16, 214, 228, 94, 165, 183, 231, 102, 15, 40, 21, 56, 235, 27, 72, 192, + 255, 166, 100, 181, 140, 202, 196, 180, 223, 252, 158, 250, 67, 93, 248, 233, 193, 172, 116, + 138, 111, 39, 104, 106, 197, 97, 173, 33, 88, 149, 226, 3, 8, 107, 114, 47, 211, 220, 244, + 51, 136, 20, 139, 28, 246, 142, 36, 96, 256, 83, 50, 219, 70, 101, 98, 90, 240, 126, 79, + 125, 162, 175, 124, 245, 225, 86, 58, 69, 184, 148, 52, 53, 227, 177, 215, 145, 44, 203, + 113, 130, 4, 182, 57, 152, 234, 110, 122, 154, 68, 10, 198, 14, 123, 71, 18, 48, 128, 170, + 25, 238, 35, 179, 49, 45, 120, 63, 168, 191, 81, 216, 62, 251, 241, 43, 29, 163, 92, 74, 26, + 155, 242, 217, 236, 201, 22, 230, 185, 65, 2, 91, 157, 76, 117, 55, 61, 77, 34, 5, 99, 7, + 190, 164, 9, 24, 64, 85, 141, 119, 146, 218, 153, 151, 60, 160, 84, 224, 169, 108, 31, 254, + 249, 150, 143, 210, 46, 37, 13, 206, 121, 237, 118, 229, 11, 115, 221, 161, 1, + ], + [ + 1, 175, 42, 154, 222, 43, 72, 7, 197, 37, 50, 12, 44, 247, 49, 94, 2, 93, 84, 51, 187, 86, + 144, 14, 137, 74, 100, 24, 88, 237, 98, 188, 4, 186, 168, 102, 117, 172, 31, 28, 17, 148, + 200, 48, 176, 217, 196, 119, 8, 115, 79, 204, 234, 87, 62, 56, 34, 39, 143, 96, 95, 177, + 135, 238, 16, 230, 158, 151, 211, 174, 124, 112, 68, 78, 29, 192, 190, 97, 13, 219, 32, 203, + 59, 45, 165, 91, 248, 224, 136, 156, 58, 127, 123, 194, 26, 181, 64, 149, 118, 90, 73, 182, + 239, 191, 15, 55, 116, 254, 246, 131, 52, 105, 128, 41, 236, 180, 146, 107, 221, 125, 30, + 110, 232, 251, 235, 5, 104, 210, 256, 82, 215, 103, 35, 214, 185, 250, 60, 220, 207, 245, + 213, 10, 208, 163, 255, 164, 173, 206, 70, 171, 113, 243, 120, 183, 157, 233, 169, 20, 159, + 69, 253, 71, 89, 155, 140, 85, 226, 229, 240, 109, 57, 209, 81, 40, 61, 138, 249, 142, 178, + 53, 23, 170, 195, 201, 223, 218, 114, 161, 162, 80, 122, 19, 241, 27, 99, 106, 46, 83, 133, + 145, 189, 179, 228, 65, 67, 160, 244, 38, 225, 54, 198, 212, 92, 166, 9, 33, 121, 101, 199, + 130, 134, 63, 231, 76, 193, 108, 139, 167, 184, 75, 18, 66, 242, 202, 141, 3, 11, 126, 205, + 152, 129, 216, 21, 77, 111, 150, 36, 132, 227, 147, 25, 6, 22, 252, 153, 47, 1, + ], + [ + 1, 176, 136, 35, 249, 134, 197, 234, 64, 213, 223, 184, 2, 95, 15, 70, 241, 11, 137, 211, + 128, 169, 189, 111, 4, 190, 30, 140, 225, 22, 17, 165, 256, 81, 121, 222, 8, 123, 60, 23, + 193, 44, 34, 73, 255, 162, 242, 187, 16, 246, 120, 46, 129, 88, 68, 146, 253, 67, 227, 117, + 32, 235, 240, 92, 1, 176, 136, 35, 249, 134, 197, 234, 64, 213, 223, 184, 2, 95, 15, 70, + 241, 11, 137, 211, 128, 169, 189, 111, 4, 190, 30, 140, 225, 22, 17, 165, 256, 81, 121, 222, + 8, 123, 60, 23, 193, 44, 34, 73, 255, 162, 242, 187, 16, 246, 120, 46, 129, 88, 68, 146, + 253, 67, 227, 117, 32, 235, 240, 92, 1, 176, 136, 35, 249, 134, 197, 234, 64, 213, 223, 184, + 2, 95, 15, 70, 241, 11, 137, 211, 128, 169, 189, 111, 4, 190, 30, 140, 225, 22, 17, 165, + 256, 81, 121, 222, 8, 123, 60, 23, 193, 44, 34, 73, 255, 162, 242, 187, 16, 246, 120, 46, + 129, 88, 68, 146, 253, 67, 227, 117, 32, 235, 240, 92, 1, 176, 136, 35, 249, 134, 197, 234, + 64, 213, 223, 184, 2, 95, 15, 70, 241, 11, 137, 211, 128, 169, 189, 111, 4, 190, 30, 140, + 225, 22, 17, 165, 256, 81, 121, 222, 8, 123, 60, 23, 193, 44, 34, 73, 255, 162, 242, 187, + 16, 246, 120, 46, 129, 88, 68, 146, 253, 67, 227, 117, 32, 235, 240, 92, 1, + ], + [ + 1, 177, 232, 201, 111, 115, 52, 209, 242, 172, 118, 69, 134, 74, 248, 206, 225, 247, 29, + 250, 46, 175, 135, 251, 223, 150, 79, 105, 81, 202, 31, 90, 253, 63, 100, 224, 70, 54, 49, + 192, 60, 83, 42, 238, 235, 218, 36, 204, 128, 40, 141, 28, 73, 71, 231, 24, 136, 171, 198, + 94, 190, 220, 133, 154, 16, 5, 114, 132, 234, 41, 61, 3, 17, 182, 89, 76, 88, 156, 113, 212, + 2, 97, 207, 145, 222, 230, 104, 161, 227, 87, 236, 138, 11, 148, 239, 155, 193, 237, 58, + 243, 92, 93, 13, 245, 189, 43, 158, 210, 162, 147, 62, 180, 249, 126, 200, 191, 140, 108, + 98, 127, 120, 166, 84, 219, 213, 179, 72, 151, 256, 80, 25, 56, 146, 142, 205, 48, 15, 85, + 139, 188, 123, 183, 9, 51, 32, 10, 228, 7, 211, 82, 122, 6, 34, 107, 178, 152, 176, 55, 226, + 167, 4, 194, 157, 33, 187, 203, 208, 65, 197, 174, 215, 19, 22, 39, 221, 53, 129, 217, 116, + 229, 184, 186, 26, 233, 121, 86, 59, 163, 67, 37, 124, 103, 241, 252, 143, 125, 23, 216, + 196, 254, 240, 75, 168, 181, 169, 101, 144, 45, 255, 160, 50, 112, 35, 27, 153, 96, 30, 170, + 21, 119, 246, 109, 18, 102, 64, 20, 199, 14, 165, 164, 244, 12, 68, 214, 99, 47, 95, 110, + 195, 77, 8, 131, 57, 66, 117, 149, 159, 130, 137, 91, 173, 38, 44, 78, 185, 106, 1, + ], + [ + 1, 178, 73, 144, 189, 232, 176, 231, 255, 158, 111, 226, 136, 50, 162, 52, 4, 198, 35, 62, + 242, 157, 190, 153, 249, 118, 187, 133, 30, 200, 134, 208, 16, 21, 140, 248, 197, 114, 246, + 98, 225, 215, 234, 18, 120, 29, 22, 61, 64, 84, 46, 221, 17, 199, 213, 135, 129, 89, 165, + 72, 223, 116, 88, 244, 256, 79, 184, 113, 68, 25, 81, 26, 2, 99, 146, 31, 121, 207, 95, 205, + 253, 59, 222, 195, 15, 100, 67, 104, 8, 139, 70, 124, 227, 57, 123, 49, 241, 236, 117, 9, + 60, 143, 11, 159, 32, 42, 23, 239, 137, 228, 235, 196, 193, 173, 211, 36, 240, 58, 44, 122, + 128, 168, 92, 185, 34, 141, 169, 13, 1, 178, 73, 144, 189, 232, 176, 231, 255, 158, 111, + 226, 136, 50, 162, 52, 4, 198, 35, 62, 242, 157, 190, 153, 249, 118, 187, 133, 30, 200, 134, + 208, 16, 21, 140, 248, 197, 114, 246, 98, 225, 215, 234, 18, 120, 29, 22, 61, 64, 84, 46, + 221, 17, 199, 213, 135, 129, 89, 165, 72, 223, 116, 88, 244, 256, 79, 184, 113, 68, 25, 81, + 26, 2, 99, 146, 31, 121, 207, 95, 205, 253, 59, 222, 195, 15, 100, 67, 104, 8, 139, 70, 124, + 227, 57, 123, 49, 241, 236, 117, 9, 60, 143, 11, 159, 32, 42, 23, 239, 137, 228, 235, 196, + 193, 173, 211, 36, 240, 58, 44, 122, 128, 168, 92, 185, 34, 141, 169, 13, 1, + ], + [ + 1, 179, 173, 127, 117, 126, 195, 210, 68, 93, 199, 155, 246, 87, 153, 145, 255, 156, 168, 3, + 23, 5, 124, 94, 121, 71, 116, 204, 22, 83, 208, 224, 4, 202, 178, 251, 211, 247, 9, 69, 15, + 115, 25, 106, 213, 91, 98, 66, 249, 110, 158, 12, 92, 20, 239, 119, 227, 27, 207, 45, 88, + 75, 61, 125, 16, 37, 198, 233, 73, 217, 36, 19, 60, 203, 100, 167, 81, 107, 135, 7, 225, + 183, 118, 48, 111, 80, 185, 219, 137, 108, 57, 180, 95, 43, 244, 243, 64, 148, 21, 161, 35, + 97, 144, 76, 240, 41, 143, 154, 67, 171, 26, 28, 129, 218, 215, 192, 187, 63, 226, 105, 34, + 175, 228, 206, 123, 172, 205, 201, 256, 78, 84, 130, 140, 131, 62, 47, 189, 164, 58, 102, + 11, 170, 104, 112, 2, 101, 89, 254, 234, 252, 133, 163, 136, 186, 141, 53, 235, 174, 49, 33, + 253, 55, 79, 6, 46, 10, 248, 188, 242, 142, 232, 151, 44, 166, 159, 191, 8, 147, 99, 245, + 165, 237, 18, 138, 30, 230, 50, 212, 169, 182, 196, 132, 241, 220, 59, 24, 184, 40, 221, + 238, 197, 54, 157, 90, 176, 150, 122, 250, 32, 74, 139, 209, 146, 177, 72, 38, 120, 149, + 200, 77, 162, 214, 13, 14, 193, 109, 236, 96, 222, 160, 113, 181, 17, 216, 114, 103, 190, + 86, 231, 229, 128, 39, 42, 65, 70, 194, 31, 152, 223, 82, 29, 51, 134, 85, 52, 56, 1, + ], + [ + 1, 180, 18, 156, 67, 238, 178, 172, 120, 12, 104, 216, 73, 33, 29, 80, 8, 155, 144, 220, 22, + 105, 139, 91, 189, 96, 61, 186, 70, 7, 232, 126, 64, 212, 124, 218, 176, 69, 84, 214, 227, + 254, 231, 203, 46, 56, 57, 237, 255, 154, 221, 202, 123, 38, 158, 170, 17, 233, 49, 82, 111, + 191, 199, 97, 241, 204, 226, 74, 213, 47, 236, 75, 136, 65, 135, 142, 117, 243, 50, 5, 129, + 90, 9, 78, 162, 119, 89, 86, 60, 6, 52, 108, 165, 145, 143, 40, 4, 206, 72, 110, 11, 181, + 198, 174, 223, 48, 159, 93, 35, 132, 116, 63, 32, 106, 62, 109, 88, 163, 42, 107, 242, 127, + 244, 230, 23, 28, 157, 247, 256, 77, 239, 101, 190, 19, 79, 85, 137, 245, 153, 41, 184, 224, + 228, 177, 249, 102, 113, 37, 235, 152, 118, 166, 68, 161, 196, 71, 187, 250, 25, 131, 193, + 45, 133, 39, 81, 188, 173, 43, 30, 3, 26, 54, 211, 201, 200, 20, 2, 103, 36, 55, 134, 219, + 99, 87, 240, 24, 208, 175, 146, 66, 58, 160, 16, 53, 31, 183, 44, 210, 21, 182, 121, 192, + 122, 115, 140, 14, 207, 252, 128, 167, 248, 179, 95, 138, 168, 171, 197, 251, 205, 149, 92, + 112, 114, 217, 253, 51, 185, 147, 246, 76, 59, 83, 34, 209, 98, 164, 222, 125, 141, 194, + 225, 151, 195, 148, 169, 94, 215, 150, 15, 130, 13, 27, 234, 229, 100, 10, 1, + ], + [ + 1, 181, 122, 237, 235, 130, 143, 183, 227, 224, 195, 86, 146, 212, 79, 164, 129, 219, 61, + 247, 246, 65, 200, 220, 242, 112, 226, 43, 73, 106, 168, 82, 193, 238, 159, 252, 123, 161, + 100, 110, 121, 56, 113, 150, 165, 53, 84, 41, 225, 119, 208, 126, 190, 209, 50, 55, 189, 28, + 185, 75, 211, 155, 42, 149, 241, 188, 104, 63, 95, 233, 25, 156, 223, 14, 221, 166, 234, + 206, 21, 203, 249, 94, 52, 160, 176, 245, 141, 78, 240, 7, 239, 83, 117, 103, 139, 230, 253, + 47, 26, 80, 88, 251, 199, 39, 120, 132, 248, 170, 187, 180, 198, 115, 255, 152, 13, 40, 44, + 254, 228, 148, 60, 66, 124, 85, 222, 90, 99, 186, 256, 76, 135, 20, 22, 127, 114, 74, 30, + 33, 62, 171, 111, 45, 178, 93, 128, 38, 196, 10, 11, 192, 57, 37, 15, 145, 31, 214, 184, + 151, 89, 175, 64, 19, 98, 5, 134, 96, 157, 147, 136, 201, 144, 107, 92, 204, 173, 216, 32, + 138, 49, 131, 67, 48, 207, 202, 68, 229, 72, 182, 46, 102, 215, 108, 16, 69, 153, 194, 162, + 24, 232, 101, 34, 243, 36, 91, 23, 51, 236, 54, 8, 163, 205, 97, 81, 12, 116, 179, 17, 250, + 18, 174, 140, 154, 118, 27, 4, 210, 231, 177, 169, 6, 58, 218, 137, 125, 9, 87, 70, 77, 59, + 142, 2, 105, 244, 217, 213, 3, 29, 109, 197, 191, 133, 172, 35, 167, 158, 71, 1, + ], + [ + 1, 182, 228, 119, 70, 147, 26, 106, 17, 10, 21, 224, 162, 186, 185, 3, 32, 170, 100, 210, + 184, 78, 61, 51, 30, 63, 158, 229, 44, 41, 9, 96, 253, 43, 116, 38, 234, 183, 153, 90, 189, + 217, 173, 132, 123, 27, 31, 245, 129, 91, 114, 188, 35, 202, 13, 53, 137, 5, 139, 112, 81, + 93, 221, 130, 16, 85, 50, 105, 92, 39, 159, 154, 15, 160, 79, 243, 22, 149, 133, 48, 255, + 150, 58, 19, 117, 220, 205, 45, 223, 237, 215, 66, 190, 142, 144, 251, 193, 174, 57, 94, + 146, 101, 135, 155, 197, 131, 198, 56, 169, 175, 239, 65, 8, 171, 25, 181, 46, 148, 208, 77, + 136, 80, 168, 250, 11, 203, 195, 24, 256, 75, 29, 138, 187, 110, 231, 151, 240, 247, 236, + 33, 95, 71, 72, 254, 225, 87, 157, 47, 73, 179, 196, 206, 227, 194, 99, 28, 213, 216, 248, + 161, 4, 214, 141, 219, 23, 74, 104, 167, 68, 40, 84, 125, 134, 230, 226, 12, 128, 166, 143, + 69, 222, 55, 244, 204, 120, 252, 118, 145, 176, 164, 36, 127, 241, 172, 207, 152, 165, 218, + 98, 103, 242, 97, 178, 14, 235, 108, 124, 209, 2, 107, 199, 238, 140, 37, 52, 212, 34, 20, + 42, 191, 67, 115, 113, 6, 64, 83, 200, 163, 111, 156, 122, 102, 60, 126, 59, 201, 88, 82, + 18, 192, 249, 86, 232, 76, 211, 109, 49, 180, 121, 177, 89, 7, 246, 54, 62, 233, 1, + ], + [ + 1, 183, 79, 65, 73, 252, 113, 119, 189, 149, 25, 206, 176, 83, 26, 132, 255, 148, 99, 127, + 111, 10, 31, 19, 136, 216, 207, 102, 162, 91, 205, 250, 4, 218, 59, 3, 35, 237, 195, 219, + 242, 82, 100, 53, 190, 75, 104, 14, 249, 78, 139, 251, 187, 40, 124, 76, 30, 93, 57, 151, + 134, 107, 49, 229, 16, 101, 236, 12, 140, 177, 9, 105, 197, 71, 143, 212, 246, 43, 159, 56, + 225, 55, 42, 233, 234, 160, 239, 47, 120, 115, 228, 90, 22, 171, 196, 145, 64, 147, 173, 48, + 46, 194, 36, 163, 17, 27, 58, 77, 213, 172, 122, 224, 129, 220, 168, 161, 165, 126, 185, + 188, 223, 203, 141, 103, 88, 170, 13, 66, 256, 74, 178, 192, 184, 5, 144, 138, 68, 108, 232, + 51, 81, 174, 231, 125, 2, 109, 158, 130, 146, 247, 226, 238, 121, 41, 50, 155, 95, 166, 52, + 7, 253, 39, 198, 254, 222, 20, 62, 38, 15, 175, 157, 204, 67, 182, 153, 243, 8, 179, 118, 6, + 70, 217, 133, 181, 227, 164, 200, 106, 123, 150, 208, 28, 241, 156, 21, 245, 117, 80, 248, + 152, 60, 186, 114, 45, 11, 214, 98, 201, 32, 202, 215, 24, 23, 97, 18, 210, 137, 142, 29, + 167, 235, 86, 61, 112, 193, 110, 84, 209, 211, 63, 221, 94, 240, 230, 199, 180, 44, 85, 135, + 33, 128, 37, 89, 96, 92, 131, 72, 69, 34, 54, 116, 154, 169, 87, 244, 191, 1, + ], + [ + 1, 184, 189, 81, 255, 146, 136, 95, 4, 222, 242, 67, 249, 70, 30, 123, 16, 117, 197, 11, + 225, 23, 120, 235, 64, 211, 17, 44, 129, 92, 223, 169, 256, 73, 68, 176, 2, 111, 121, 162, + 253, 35, 15, 190, 8, 187, 227, 134, 241, 140, 60, 246, 32, 234, 137, 22, 193, 46, 240, 213, + 128, 165, 34, 88, 1, 184, 189, 81, 255, 146, 136, 95, 4, 222, 242, 67, 249, 70, 30, 123, 16, + 117, 197, 11, 225, 23, 120, 235, 64, 211, 17, 44, 129, 92, 223, 169, 256, 73, 68, 176, 2, + 111, 121, 162, 253, 35, 15, 190, 8, 187, 227, 134, 241, 140, 60, 246, 32, 234, 137, 22, 193, + 46, 240, 213, 128, 165, 34, 88, 1, 184, 189, 81, 255, 146, 136, 95, 4, 222, 242, 67, 249, + 70, 30, 123, 16, 117, 197, 11, 225, 23, 120, 235, 64, 211, 17, 44, 129, 92, 223, 169, 256, + 73, 68, 176, 2, 111, 121, 162, 253, 35, 15, 190, 8, 187, 227, 134, 241, 140, 60, 246, 32, + 234, 137, 22, 193, 46, 240, 213, 128, 165, 34, 88, 1, 184, 189, 81, 255, 146, 136, 95, 4, + 222, 242, 67, 249, 70, 30, 123, 16, 117, 197, 11, 225, 23, 120, 235, 64, 211, 17, 44, 129, + 92, 223, 169, 256, 73, 68, 176, 2, 111, 121, 162, 253, 35, 15, 190, 8, 187, 227, 134, 241, + 140, 60, 246, 32, 234, 137, 22, 193, 46, 240, 213, 128, 165, 34, 88, 1, + ], + [ + 1, 185, 44, 173, 137, 159, 117, 57, 8, 195, 95, 99, 68, 244, 165, 199, 64, 18, 246, 21, 30, + 153, 35, 50, 255, 144, 169, 168, 240, 196, 23, 143, 241, 124, 67, 59, 121, 26, 184, 116, + 129, 221, 22, 215, 197, 208, 187, 157, 4, 226, 176, 178, 34, 122, 211, 228, 32, 9, 123, 139, + 15, 205, 146, 25, 256, 72, 213, 84, 120, 98, 140, 200, 249, 62, 162, 158, 189, 13, 92, 58, + 193, 239, 11, 236, 227, 104, 222, 207, 2, 113, 88, 89, 17, 61, 234, 114, 16, 133, 190, 198, + 136, 231, 73, 141, 128, 36, 235, 42, 60, 49, 70, 100, 253, 31, 81, 79, 223, 135, 46, 29, + 225, 248, 134, 118, 242, 52, 111, 232, 1, 185, 44, 173, 137, 159, 117, 57, 8, 195, 95, 99, + 68, 244, 165, 199, 64, 18, 246, 21, 30, 153, 35, 50, 255, 144, 169, 168, 240, 196, 23, 143, + 241, 124, 67, 59, 121, 26, 184, 116, 129, 221, 22, 215, 197, 208, 187, 157, 4, 226, 176, + 178, 34, 122, 211, 228, 32, 9, 123, 139, 15, 205, 146, 25, 256, 72, 213, 84, 120, 98, 140, + 200, 249, 62, 162, 158, 189, 13, 92, 58, 193, 239, 11, 236, 227, 104, 222, 207, 2, 113, 88, + 89, 17, 61, 234, 114, 16, 133, 190, 198, 136, 231, 73, 141, 128, 36, 235, 42, 60, 49, 70, + 100, 253, 31, 81, 79, 223, 135, 46, 29, 225, 248, 134, 118, 242, 52, 111, 232, 1, + ], + [ + 1, 186, 158, 90, 35, 85, 133, 66, 197, 148, 29, 254, 213, 40, 244, 152, 2, 115, 59, 180, 70, + 170, 9, 132, 137, 39, 58, 251, 169, 80, 231, 47, 4, 230, 118, 103, 140, 83, 18, 7, 17, 78, + 116, 245, 81, 160, 205, 94, 8, 203, 236, 206, 23, 166, 36, 14, 34, 156, 232, 233, 162, 63, + 153, 188, 16, 149, 215, 155, 46, 75, 72, 28, 68, 55, 207, 209, 67, 126, 49, 119, 32, 41, + 173, 53, 92, 150, 144, 56, 136, 110, 157, 161, 134, 252, 98, 238, 64, 82, 89, 106, 184, 43, + 31, 112, 15, 220, 57, 65, 11, 247, 196, 219, 128, 164, 178, 212, 111, 86, 62, 224, 30, 183, + 114, 130, 22, 237, 135, 181, 256, 71, 99, 167, 222, 172, 124, 191, 60, 109, 228, 3, 44, 217, + 13, 105, 255, 142, 198, 77, 187, 87, 248, 125, 120, 218, 199, 6, 88, 177, 26, 210, 253, 27, + 139, 154, 117, 174, 239, 250, 240, 179, 141, 12, 176, 97, 52, 163, 249, 54, 21, 51, 234, 91, + 221, 243, 223, 101, 25, 24, 95, 194, 104, 69, 241, 108, 42, 102, 211, 182, 185, 229, 189, + 202, 50, 48, 190, 131, 208, 138, 225, 216, 84, 204, 165, 107, 113, 201, 121, 147, 100, 96, + 123, 5, 159, 19, 193, 175, 168, 151, 73, 214, 226, 145, 242, 37, 200, 192, 246, 10, 61, 38, + 129, 93, 79, 45, 146, 171, 195, 33, 227, 74, 143, 127, 235, 20, 122, 76, 1, + ], + [ + 1, 187, 17, 95, 32, 73, 30, 213, 253, 23, 189, 134, 129, 222, 137, 176, 16, 165, 15, 235, + 255, 140, 223, 67, 193, 111, 197, 88, 8, 211, 136, 246, 256, 70, 240, 162, 225, 184, 227, + 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, 92, 242, 22, 2, 117, 34, 190, 64, 146, 60, 169, + 249, 46, 121, 11, 1, 187, 17, 95, 32, 73, 30, 213, 253, 23, 189, 134, 129, 222, 137, 176, + 16, 165, 15, 235, 255, 140, 223, 67, 193, 111, 197, 88, 8, 211, 136, 246, 256, 70, 240, 162, + 225, 184, 227, 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, 92, 242, 22, 2, 117, 34, 190, 64, + 146, 60, 169, 249, 46, 121, 11, 1, 187, 17, 95, 32, 73, 30, 213, 253, 23, 189, 134, 129, + 222, 137, 176, 16, 165, 15, 235, 255, 140, 223, 67, 193, 111, 197, 88, 8, 211, 136, 246, + 256, 70, 240, 162, 225, 184, 227, 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, 92, 242, 22, + 2, 117, 34, 190, 64, 146, 60, 169, 249, 46, 121, 11, 1, 187, 17, 95, 32, 73, 30, 213, 253, + 23, 189, 134, 129, 222, 137, 176, 16, 165, 15, 235, 255, 140, 223, 67, 193, 111, 197, 88, 8, + 211, 136, 246, 256, 70, 240, 162, 225, 184, 227, 44, 4, 234, 68, 123, 128, 35, 120, 81, 241, + 92, 242, 22, 2, 117, 34, 190, 64, 146, 60, 169, 249, 46, 121, 11, 1, + ], + [ + 1, 188, 135, 194, 235, 233, 114, 101, 227, 14, 62, 91, 146, 206, 178, 54, 129, 94, 196, 97, + 246, 245, 57, 179, 242, 7, 31, 174, 73, 103, 89, 27, 193, 47, 98, 177, 123, 251, 157, 218, + 121, 132, 144, 87, 165, 180, 173, 142, 225, 152, 49, 217, 190, 254, 207, 109, 189, 66, 72, + 172, 211, 90, 215, 71, 241, 76, 153, 237, 95, 127, 232, 183, 223, 33, 36, 86, 234, 45, 236, + 164, 249, 38, 205, 247, 176, 192, 116, 220, 240, 145, 18, 43, 117, 151, 118, 82, 253, 19, + 231, 252, 88, 96, 58, 110, 120, 201, 9, 150, 187, 204, 59, 41, 255, 138, 244, 126, 44, 48, + 29, 55, 60, 229, 133, 75, 222, 102, 158, 149, 256, 69, 122, 63, 22, 24, 143, 156, 30, 243, + 195, 166, 111, 51, 79, 203, 128, 163, 61, 160, 11, 12, 200, 78, 15, 250, 226, 83, 184, 154, + 168, 230, 64, 210, 159, 80, 134, 6, 100, 39, 136, 125, 113, 170, 92, 77, 84, 115, 32, 105, + 208, 40, 67, 3, 50, 148, 68, 191, 185, 85, 46, 167, 42, 186, 16, 181, 104, 20, 162, 130, 25, + 74, 34, 224, 221, 171, 23, 212, 21, 93, 8, 219, 52, 10, 81, 65, 141, 37, 17, 112, 239, 214, + 140, 106, 139, 175, 4, 238, 26, 5, 169, 161, 199, 147, 137, 56, 248, 107, 70, 53, 198, 216, + 2, 119, 13, 131, 213, 209, 228, 202, 197, 28, 124, 182, 35, 155, 99, 108, 1, + ], + [ + 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, + 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, + 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, + 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, + 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, + 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, + 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, + 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, + 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, + 241, 60, 32, 137, 193, 240, 128, 34, 1, 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, + 64, 17, 129, 223, 256, 68, 2, 121, 253, 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, + 189, 255, 136, 4, 242, 249, 30, 16, 197, 225, 120, 64, 17, 129, 223, 256, 68, 2, 121, 253, + 15, 8, 227, 241, 60, 32, 137, 193, 240, 128, 34, 1, + ], + [ + 1, 190, 120, 184, 8, 235, 189, 187, 64, 81, 227, 211, 255, 134, 17, 146, 241, 44, 136, 140, + 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, 242, 234, 256, 67, 137, 73, 249, 22, 68, 70, + 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, 121, 117, 128, 162, 197, 165, 253, 11, 34, 35, + 225, 88, 15, 23, 1, 190, 120, 184, 8, 235, 189, 187, 64, 81, 227, 211, 255, 134, 17, 146, + 241, 44, 136, 140, 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, 242, 234, 256, 67, 137, 73, + 249, 22, 68, 70, 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, 121, 117, 128, 162, 197, 165, + 253, 11, 34, 35, 225, 88, 15, 23, 1, 190, 120, 184, 8, 235, 189, 187, 64, 81, 227, 211, 255, + 134, 17, 146, 241, 44, 136, 140, 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, 242, 234, 256, + 67, 137, 73, 249, 22, 68, 70, 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, 121, 117, 128, + 162, 197, 165, 253, 11, 34, 35, 225, 88, 15, 23, 1, 190, 120, 184, 8, 235, 189, 187, 64, 81, + 227, 211, 255, 134, 17, 146, 241, 44, 136, 140, 129, 95, 60, 92, 4, 246, 223, 222, 32, 169, + 242, 234, 256, 67, 137, 73, 249, 22, 68, 70, 193, 176, 30, 46, 2, 123, 240, 111, 16, 213, + 121, 117, 128, 162, 197, 165, 253, 11, 34, 35, 225, 88, 15, 23, 1, + ], + [ + 1, 191, 244, 87, 169, 154, 116, 54, 34, 69, 72, 131, 92, 96, 89, 37, 128, 33, 135, 85, 44, + 180, 199, 230, 240, 94, 221, 63, 211, 209, 84, 110, 193, 112, 61, 86, 235, 167, 29, 142, + 137, 210, 18, 97, 23, 24, 215, 202, 32, 201, 98, 214, 11, 45, 114, 186, 60, 152, 248, 80, + 117, 245, 21, 156, 241, 28, 208, 150, 123, 106, 200, 164, 227, 181, 133, 217, 70, 6, 118, + 179, 8, 243, 153, 182, 67, 204, 157, 175, 15, 38, 62, 20, 222, 254, 198, 39, 253, 7, 52, + 166, 95, 155, 50, 41, 121, 238, 226, 247, 146, 130, 158, 109, 2, 125, 231, 174, 81, 51, 232, + 108, 68, 138, 144, 5, 184, 192, 178, 74, 256, 66, 13, 170, 88, 103, 141, 203, 223, 188, 185, + 126, 165, 161, 168, 220, 129, 224, 122, 172, 213, 77, 58, 27, 17, 163, 36, 194, 46, 48, 173, + 147, 64, 145, 196, 171, 22, 90, 228, 115, 120, 47, 239, 160, 234, 233, 42, 55, 225, 56, 159, + 43, 246, 212, 143, 71, 197, 105, 9, 177, 140, 12, 236, 101, 16, 229, 49, 107, 134, 151, 57, + 93, 30, 76, 124, 40, 187, 251, 139, 78, 249, 14, 104, 75, 190, 53, 100, 82, 242, 219, 195, + 237, 35, 3, 59, 218, 4, 250, 205, 91, 162, 102, 207, 216, 136, 19, 31, 10, 111, 127, 99, + 148, 255, 132, 26, 83, 176, 206, 25, 149, 189, 119, 113, 252, 73, 65, 79, 183, 1, + ], + [ + 1, 192, 113, 108, 176, 125, 99, 247, 136, 155, 205, 39, 35, 38, 100, 182, 249, 6, 124, 164, + 134, 28, 236, 80, 197, 45, 159, 202, 234, 210, 228, 86, 64, 209, 36, 230, 213, 33, 168, 131, + 223, 154, 13, 183, 184, 119, 232, 83, 2, 127, 226, 216, 95, 250, 198, 237, 15, 53, 153, 78, + 70, 76, 200, 107, 241, 12, 248, 71, 11, 56, 215, 160, 137, 90, 61, 147, 211, 163, 199, 172, + 128, 161, 72, 203, 169, 66, 79, 5, 189, 51, 26, 109, 111, 238, 207, 166, 4, 254, 195, 175, + 190, 243, 139, 217, 30, 106, 49, 156, 140, 152, 143, 214, 225, 24, 239, 142, 22, 112, 173, + 63, 17, 180, 122, 37, 165, 69, 141, 87, 256, 65, 144, 149, 81, 132, 158, 10, 121, 102, 52, + 218, 222, 219, 157, 75, 8, 251, 133, 93, 123, 229, 21, 177, 60, 212, 98, 55, 23, 47, 29, + 171, 193, 48, 221, 27, 44, 224, 89, 126, 34, 103, 244, 74, 73, 138, 25, 174, 255, 130, 31, + 41, 162, 7, 59, 20, 242, 204, 104, 179, 187, 181, 57, 150, 16, 245, 9, 186, 246, 201, 42, + 97, 120, 167, 196, 110, 46, 94, 58, 85, 129, 96, 185, 54, 88, 191, 178, 252, 68, 206, 231, + 148, 146, 19, 50, 91, 253, 3, 62, 82, 67, 14, 118, 40, 227, 151, 208, 101, 117, 105, 114, + 43, 32, 233, 18, 115, 235, 145, 84, 194, 240, 77, 135, 220, 92, 188, 116, 170, 1, + ], + [ + 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, + 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, + 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, + 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, + 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, + 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, + 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, + 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, + 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, + 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, + 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, + 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, 193, 241, 253, 256, 64, 16, 4, 1, + ], + [ + 1, 194, 114, 14, 146, 54, 196, 245, 242, 174, 89, 47, 123, 218, 144, 180, 225, 217, 207, 66, + 211, 71, 153, 127, 223, 86, 236, 38, 176, 220, 18, 151, 253, 252, 58, 201, 187, 41, 244, 48, + 60, 75, 158, 69, 22, 156, 195, 51, 128, 160, 200, 250, 184, 230, 159, 6, 136, 170, 84, 105, + 67, 148, 185, 167, 16, 20, 25, 224, 23, 93, 52, 65, 17, 214, 139, 238, 169, 147, 248, 53, 2, + 131, 228, 28, 35, 108, 135, 233, 227, 91, 178, 94, 246, 179, 31, 103, 193, 177, 157, 132, + 165, 142, 49, 254, 189, 172, 215, 76, 95, 183, 36, 45, 249, 247, 116, 145, 117, 82, 231, 96, + 120, 150, 59, 138, 44, 55, 133, 102, 256, 63, 143, 243, 111, 203, 61, 12, 15, 83, 168, 210, + 134, 39, 113, 77, 32, 40, 50, 191, 46, 186, 104, 130, 34, 171, 21, 219, 81, 37, 239, 106, 4, + 5, 199, 56, 70, 216, 13, 209, 197, 182, 99, 188, 235, 101, 62, 206, 129, 97, 57, 7, 73, 27, + 98, 251, 121, 87, 173, 152, 190, 109, 72, 90, 241, 237, 232, 33, 234, 164, 205, 192, 240, + 43, 118, 19, 88, 110, 9, 204, 255, 126, 29, 229, 222, 149, 122, 24, 30, 166, 79, 163, 11, + 78, 226, 154, 64, 80, 100, 125, 92, 115, 208, 3, 68, 85, 42, 181, 162, 74, 221, 212, 8, 10, + 141, 112, 140, 175, 26, 161, 137, 107, 198, 119, 213, 202, 124, 155, 1, + ], + [ + 1, 195, 246, 168, 121, 208, 211, 25, 249, 239, 88, 198, 60, 135, 111, 57, 64, 144, 67, 215, + 34, 205, 140, 58, 2, 133, 235, 79, 242, 159, 165, 50, 241, 221, 176, 139, 120, 13, 222, 114, + 128, 31, 134, 173, 68, 153, 23, 116, 4, 9, 213, 158, 227, 61, 73, 100, 225, 185, 95, 21, + 240, 26, 187, 228, 256, 62, 11, 89, 136, 49, 46, 232, 8, 18, 169, 59, 197, 122, 146, 200, + 193, 113, 190, 42, 223, 52, 117, 199, 255, 124, 22, 178, 15, 98, 92, 207, 16, 36, 81, 118, + 137, 244, 35, 143, 129, 226, 123, 84, 189, 104, 234, 141, 253, 248, 44, 99, 30, 196, 184, + 157, 32, 72, 162, 236, 17, 231, 70, 29, 1, 195, 246, 168, 121, 208, 211, 25, 249, 239, 88, + 198, 60, 135, 111, 57, 64, 144, 67, 215, 34, 205, 140, 58, 2, 133, 235, 79, 242, 159, 165, + 50, 241, 221, 176, 139, 120, 13, 222, 114, 128, 31, 134, 173, 68, 153, 23, 116, 4, 9, 213, + 158, 227, 61, 73, 100, 225, 185, 95, 21, 240, 26, 187, 228, 256, 62, 11, 89, 136, 49, 46, + 232, 8, 18, 169, 59, 197, 122, 146, 200, 193, 113, 190, 42, 223, 52, 117, 199, 255, 124, 22, + 178, 15, 98, 92, 207, 16, 36, 81, 118, 137, 244, 35, 143, 129, 226, 123, 84, 189, 104, 234, + 141, 253, 248, 44, 99, 30, 196, 184, 157, 32, 72, 162, 236, 17, 231, 70, 29, 1, + ], + [ + 1, 196, 123, 207, 223, 18, 187, 158, 128, 159, 67, 25, 17, 248, 35, 178, 193, 49, 95, 116, + 120, 133, 111, 168, 32, 104, 81, 199, 197, 62, 73, 173, 241, 205, 88, 29, 30, 226, 92, 42, + 8, 26, 213, 114, 242, 144, 211, 236, 253, 244, 22, 200, 136, 185, 23, 139, 2, 135, 246, 157, + 189, 36, 117, 59, 256, 61, 134, 50, 34, 239, 70, 99, 129, 98, 190, 232, 240, 9, 222, 79, 64, + 208, 162, 141, 137, 124, 146, 89, 225, 153, 176, 58, 60, 195, 184, 84, 16, 52, 169, 228, + 227, 31, 165, 215, 249, 231, 44, 143, 15, 113, 46, 21, 4, 13, 235, 57, 121, 72, 234, 118, + 255, 122, 11, 100, 68, 221, 140, 198, 1, 196, 123, 207, 223, 18, 187, 158, 128, 159, 67, 25, + 17, 248, 35, 178, 193, 49, 95, 116, 120, 133, 111, 168, 32, 104, 81, 199, 197, 62, 73, 173, + 241, 205, 88, 29, 30, 226, 92, 42, 8, 26, 213, 114, 242, 144, 211, 236, 253, 244, 22, 200, + 136, 185, 23, 139, 2, 135, 246, 157, 189, 36, 117, 59, 256, 61, 134, 50, 34, 239, 70, 99, + 129, 98, 190, 232, 240, 9, 222, 79, 64, 208, 162, 141, 137, 124, 146, 89, 225, 153, 176, 58, + 60, 195, 184, 84, 16, 52, 169, 228, 227, 31, 165, 215, 249, 231, 44, 143, 15, 113, 46, 21, + 4, 13, 235, 57, 121, 72, 234, 118, 255, 122, 11, 100, 68, 221, 140, 198, 1, + ], + [ + 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, + 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, + 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, + 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, + 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, + 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, + 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, + 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, + 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, + 225, 121, 193, 242, 129, 227, 1, 197, 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, + 30, 256, 60, 255, 120, 253, 240, 249, 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, 197, + 2, 137, 4, 17, 8, 34, 16, 68, 32, 136, 64, 15, 128, 30, 256, 60, 255, 120, 253, 240, 249, + 223, 241, 189, 225, 121, 193, 242, 129, 227, 1, + ], + [ + 1, 198, 140, 221, 68, 100, 11, 122, 255, 118, 234, 72, 121, 57, 235, 13, 4, 21, 46, 113, 15, + 143, 44, 231, 249, 215, 165, 31, 227, 228, 169, 52, 16, 84, 184, 195, 60, 58, 176, 153, 225, + 89, 146, 124, 137, 141, 162, 208, 64, 79, 222, 9, 240, 232, 190, 98, 129, 99, 70, 239, 34, + 50, 134, 61, 256, 59, 117, 36, 189, 157, 246, 135, 2, 139, 23, 185, 136, 200, 22, 244, 253, + 236, 211, 144, 242, 114, 213, 26, 8, 42, 92, 226, 30, 29, 88, 205, 241, 173, 73, 62, 197, + 199, 81, 104, 32, 168, 111, 133, 120, 116, 95, 49, 193, 178, 35, 248, 17, 25, 67, 159, 128, + 158, 187, 18, 223, 207, 123, 196, 1, 198, 140, 221, 68, 100, 11, 122, 255, 118, 234, 72, + 121, 57, 235, 13, 4, 21, 46, 113, 15, 143, 44, 231, 249, 215, 165, 31, 227, 228, 169, 52, + 16, 84, 184, 195, 60, 58, 176, 153, 225, 89, 146, 124, 137, 141, 162, 208, 64, 79, 222, 9, + 240, 232, 190, 98, 129, 99, 70, 239, 34, 50, 134, 61, 256, 59, 117, 36, 189, 157, 246, 135, + 2, 139, 23, 185, 136, 200, 22, 244, 253, 236, 211, 144, 242, 114, 213, 26, 8, 42, 92, 226, + 30, 29, 88, 205, 241, 173, 73, 62, 197, 199, 81, 104, 32, 168, 111, 133, 120, 116, 95, 49, + 193, 178, 35, 248, 17, 25, 67, 159, 128, 158, 187, 18, 223, 207, 123, 196, 1, + ], + [ + 1, 199, 23, 208, 15, 158, 88, 36, 225, 57, 35, 26, 34, 84, 11, 133, 253, 232, 165, 196, 197, + 139, 162, 113, 128, 29, 117, 153, 121, 178, 213, 239, 16, 100, 111, 244, 240, 215, 123, 62, + 2, 141, 46, 159, 30, 59, 176, 72, 193, 114, 70, 52, 68, 168, 22, 9, 249, 207, 73, 135, 137, + 21, 67, 226, 256, 58, 234, 49, 242, 99, 169, 221, 32, 200, 222, 231, 223, 173, 246, 124, 4, + 25, 92, 61, 60, 118, 95, 144, 129, 228, 140, 104, 136, 79, 44, 18, 241, 157, 146, 13, 17, + 42, 134, 195, 255, 116, 211, 98, 227, 198, 81, 185, 64, 143, 187, 205, 189, 89, 235, 248, 8, + 50, 184, 122, 120, 236, 190, 31, 1, 199, 23, 208, 15, 158, 88, 36, 225, 57, 35, 26, 34, 84, + 11, 133, 253, 232, 165, 196, 197, 139, 162, 113, 128, 29, 117, 153, 121, 178, 213, 239, 16, + 100, 111, 244, 240, 215, 123, 62, 2, 141, 46, 159, 30, 59, 176, 72, 193, 114, 70, 52, 68, + 168, 22, 9, 249, 207, 73, 135, 137, 21, 67, 226, 256, 58, 234, 49, 242, 99, 169, 221, 32, + 200, 222, 231, 223, 173, 246, 124, 4, 25, 92, 61, 60, 118, 95, 144, 129, 228, 140, 104, 136, + 79, 44, 18, 241, 157, 146, 13, 17, 42, 134, 195, 255, 116, 211, 98, 227, 198, 81, 185, 64, + 143, 187, 205, 189, 89, 235, 248, 8, 50, 184, 122, 120, 236, 190, 31, 1, + ], + [ + 1, 200, 165, 104, 240, 198, 22, 31, 32, 232, 140, 244, 227, 168, 190, 221, 253, 228, 111, + 98, 68, 236, 169, 133, 129, 100, 211, 52, 120, 99, 11, 144, 16, 116, 70, 122, 242, 84, 95, + 239, 255, 114, 184, 49, 34, 118, 213, 195, 193, 50, 234, 26, 60, 178, 134, 72, 8, 58, 35, + 61, 121, 42, 176, 248, 256, 57, 92, 153, 17, 59, 235, 226, 225, 25, 117, 13, 30, 89, 67, 36, + 4, 29, 146, 159, 189, 21, 88, 124, 128, 157, 46, 205, 137, 158, 246, 113, 241, 141, 187, + 135, 15, 173, 162, 18, 2, 143, 73, 208, 223, 139, 44, 62, 64, 207, 23, 231, 197, 79, 123, + 185, 249, 199, 222, 196, 136, 215, 81, 9, 1, 200, 165, 104, 240, 198, 22, 31, 32, 232, 140, + 244, 227, 168, 190, 221, 253, 228, 111, 98, 68, 236, 169, 133, 129, 100, 211, 52, 120, 99, + 11, 144, 16, 116, 70, 122, 242, 84, 95, 239, 255, 114, 184, 49, 34, 118, 213, 195, 193, 50, + 234, 26, 60, 178, 134, 72, 8, 58, 35, 61, 121, 42, 176, 248, 256, 57, 92, 153, 17, 59, 235, + 226, 225, 25, 117, 13, 30, 89, 67, 36, 4, 29, 146, 159, 189, 21, 88, 124, 128, 157, 46, 205, + 137, 158, 246, 113, 241, 141, 187, 135, 15, 173, 162, 18, 2, 143, 73, 208, 223, 139, 44, 62, + 64, 207, 23, 231, 197, 79, 123, 185, 249, 199, 222, 196, 136, 215, 81, 9, 1, + ], + [ + 1, 201, 52, 172, 134, 206, 29, 175, 223, 105, 31, 63, 70, 192, 42, 218, 128, 28, 231, 171, + 190, 154, 114, 41, 17, 76, 113, 97, 222, 161, 236, 148, 193, 243, 13, 43, 162, 180, 200, + 108, 120, 219, 72, 80, 146, 48, 139, 183, 32, 7, 122, 107, 176, 167, 157, 203, 197, 19, 221, + 217, 184, 233, 59, 37, 241, 125, 196, 75, 169, 45, 50, 27, 30, 119, 18, 20, 165, 12, 99, + 110, 8, 66, 159, 91, 44, 106, 232, 115, 242, 69, 248, 247, 46, 251, 79, 202, 253, 224, 49, + 83, 235, 204, 141, 71, 136, 94, 133, 5, 234, 3, 89, 156, 2, 145, 104, 87, 11, 155, 58, 93, + 189, 210, 62, 126, 140, 127, 84, 179, 256, 56, 205, 85, 123, 51, 228, 82, 34, 152, 226, 194, + 187, 65, 215, 39, 129, 229, 26, 86, 67, 103, 143, 216, 240, 181, 144, 160, 35, 96, 21, 109, + 64, 14, 244, 214, 95, 77, 57, 149, 137, 38, 185, 177, 111, 209, 118, 74, 225, 250, 135, 150, + 81, 90, 100, 54, 60, 238, 36, 40, 73, 24, 198, 220, 16, 132, 61, 182, 88, 212, 207, 230, + 227, 138, 239, 237, 92, 245, 158, 147, 249, 191, 98, 166, 213, 151, 25, 142, 15, 188, 9, 10, + 211, 6, 178, 55, 4, 33, 208, 174, 22, 53, 116, 186, 121, 163, 124, 252, 23, 254, 168, 101, + 255, 112, 153, 170, 246, 102, 199, 164, 68, 47, 195, 131, 117, 130, 173, 78, 1, + ], + [ + 1, 202, 198, 161, 140, 10, 221, 181, 68, 115, 100, 154, 11, 166, 122, 229, 255, 110, 118, + 192, 234, 237, 72, 152, 121, 27, 57, 206, 235, 182, 13, 56, 4, 37, 21, 130, 46, 40, 113, + 210, 15, 203, 143, 102, 44, 150, 231, 145, 249, 183, 215, 254, 165, 177, 31, 94, 227, 108, + 228, 53, 169, 214, 52, 224, 16, 148, 84, 6, 184, 160, 195, 69, 60, 41, 58, 151, 176, 86, + 153, 66, 225, 218, 89, 245, 146, 194, 124, 119, 137, 175, 141, 212, 162, 85, 208, 125, 64, + 78, 79, 24, 222, 126, 9, 19, 240, 164, 232, 90, 190, 87, 98, 7, 129, 101, 99, 209, 70, 5, + 239, 219, 34, 186, 50, 77, 134, 83, 61, 243, 256, 55, 59, 96, 117, 247, 36, 76, 189, 142, + 157, 103, 246, 91, 135, 28, 2, 147, 139, 65, 23, 20, 185, 105, 136, 230, 200, 51, 22, 75, + 244, 201, 253, 220, 236, 127, 211, 217, 144, 47, 242, 54, 114, 155, 213, 107, 26, 112, 8, + 74, 42, 3, 92, 80, 226, 163, 30, 149, 29, 204, 88, 43, 205, 33, 241, 109, 173, 251, 73, 97, + 62, 188, 197, 216, 199, 106, 81, 171, 104, 191, 32, 39, 168, 12, 111, 63, 133, 138, 120, 82, + 116, 45, 95, 172, 49, 132, 193, 179, 178, 233, 35, 131, 248, 238, 17, 93, 25, 167, 67, 170, + 159, 250, 128, 156, 158, 48, 187, 252, 18, 38, 223, 71, 207, 180, 123, 174, 196, 14, 1, + ], + [ + 1, 203, 89, 77, 211, 171, 18, 56, 60, 101, 200, 251, 67, 237, 52, 19, 2, 149, 178, 154, 165, + 85, 36, 112, 120, 202, 143, 245, 134, 217, 104, 38, 4, 41, 99, 51, 73, 170, 72, 224, 240, + 147, 29, 233, 11, 177, 208, 76, 8, 82, 198, 102, 146, 83, 144, 191, 223, 37, 58, 209, 22, + 97, 159, 152, 16, 164, 139, 204, 35, 166, 31, 125, 189, 74, 116, 161, 44, 194, 61, 47, 32, + 71, 21, 151, 70, 75, 62, 250, 121, 148, 232, 65, 88, 131, 122, 94, 64, 142, 42, 45, 140, + 150, 124, 243, 242, 39, 207, 130, 176, 5, 244, 188, 128, 27, 84, 90, 23, 43, 248, 229, 227, + 78, 157, 3, 95, 10, 231, 119, 256, 54, 168, 180, 46, 86, 239, 201, 197, 156, 57, 6, 190, 20, + 205, 238, 255, 108, 79, 103, 92, 172, 221, 145, 137, 55, 114, 12, 123, 40, 153, 219, 253, + 216, 158, 206, 184, 87, 185, 33, 17, 110, 228, 24, 246, 80, 49, 181, 249, 175, 59, 155, 111, + 174, 113, 66, 34, 220, 199, 48, 235, 160, 98, 105, 241, 93, 118, 53, 222, 91, 226, 132, 68, + 183, 141, 96, 213, 63, 196, 210, 225, 186, 236, 106, 187, 182, 195, 7, 136, 109, 25, 192, + 169, 126, 135, 163, 193, 115, 215, 212, 117, 107, 133, 14, 15, 218, 50, 127, 81, 252, 13, + 69, 129, 230, 173, 167, 234, 214, 9, 28, 30, 179, 100, 254, 162, 247, 26, 138, 1, + ], + [ + 1, 204, 239, 183, 67, 47, 79, 182, 120, 65, 153, 115, 73, 243, 228, 252, 8, 90, 113, 179, + 22, 119, 118, 171, 189, 6, 196, 149, 70, 145, 25, 217, 64, 206, 133, 147, 176, 181, 173, 83, + 227, 48, 26, 164, 46, 132, 200, 194, 255, 106, 36, 148, 123, 163, 99, 150, 17, 127, 208, 27, + 111, 28, 58, 10, 241, 77, 31, 156, 213, 19, 21, 172, 136, 245, 122, 216, 117, 224, 207, 80, + 129, 102, 248, 220, 162, 152, 168, 91, 60, 161, 205, 186, 165, 250, 114, 126, 4, 45, 185, + 218, 11, 188, 59, 214, 223, 3, 98, 203, 35, 201, 141, 237, 32, 103, 195, 202, 88, 219, 215, + 170, 242, 24, 13, 82, 23, 66, 100, 97, 256, 53, 18, 74, 190, 210, 178, 75, 137, 192, 104, + 142, 184, 14, 29, 5, 249, 167, 144, 78, 235, 138, 139, 86, 68, 251, 61, 108, 187, 112, 232, + 40, 193, 51, 124, 110, 81, 76, 84, 174, 30, 209, 231, 93, 211, 125, 57, 63, 2, 151, 221, + 109, 134, 94, 158, 107, 240, 130, 49, 230, 146, 229, 199, 247, 16, 180, 226, 101, 44, 238, + 236, 85, 121, 12, 135, 41, 140, 33, 50, 177, 128, 155, 9, 37, 95, 105, 89, 166, 197, 96, 52, + 71, 92, 7, 143, 131, 253, 212, 72, 39, 246, 69, 198, 43, 34, 254, 159, 54, 222, 56, 116, 20, + 225, 154, 62, 55, 169, 38, 42, 87, 15, 233, 244, 175, 234, 191, 157, 160, 1, + ], + [ + 1, 205, 134, 228, 223, 226, 70, 215, 128, 26, 190, 143, 17, 144, 222, 21, 193, 244, 162, 57, + 120, 185, 146, 118, 32, 135, 176, 100, 197, 36, 184, 198, 241, 61, 169, 207, 30, 239, 165, + 158, 8, 98, 44, 25, 242, 9, 46, 178, 253, 208, 235, 116, 136, 124, 234, 168, 2, 153, 11, + 199, 189, 195, 140, 173, 256, 52, 123, 29, 34, 31, 187, 42, 129, 231, 67, 114, 240, 113, 35, + 236, 64, 13, 95, 200, 137, 72, 111, 139, 225, 122, 81, 157, 60, 221, 73, 59, 16, 196, 88, + 50, 227, 18, 92, 99, 249, 159, 213, 232, 15, 248, 211, 79, 4, 49, 22, 141, 121, 133, 23, 89, + 255, 104, 246, 58, 68, 62, 117, 84, 1, 205, 134, 228, 223, 226, 70, 215, 128, 26, 190, 143, + 17, 144, 222, 21, 193, 244, 162, 57, 120, 185, 146, 118, 32, 135, 176, 100, 197, 36, 184, + 198, 241, 61, 169, 207, 30, 239, 165, 158, 8, 98, 44, 25, 242, 9, 46, 178, 253, 208, 235, + 116, 136, 124, 234, 168, 2, 153, 11, 199, 189, 195, 140, 173, 256, 52, 123, 29, 34, 31, 187, + 42, 129, 231, 67, 114, 240, 113, 35, 236, 64, 13, 95, 200, 137, 72, 111, 139, 225, 122, 81, + 157, 60, 221, 73, 59, 16, 196, 88, 50, 227, 18, 92, 99, 249, 159, 213, 232, 15, 248, 211, + 79, 4, 49, 22, 141, 121, 133, 23, 89, 255, 104, 246, 58, 68, 62, 117, 84, 1, + ], + [ + 1, 206, 31, 218, 190, 76, 236, 43, 120, 48, 122, 203, 184, 125, 50, 20, 8, 106, 248, 202, + 235, 94, 89, 87, 189, 127, 205, 82, 187, 229, 143, 160, 64, 77, 185, 74, 81, 238, 198, 182, + 227, 245, 98, 142, 211, 33, 116, 252, 255, 102, 195, 78, 134, 105, 42, 171, 17, 161, 13, + 108, 146, 7, 157, 217, 241, 45, 18, 110, 44, 69, 79, 83, 136, 3, 104, 93, 140, 56, 228, 194, + 129, 103, 144, 109, 95, 38, 118, 150, 60, 24, 61, 230, 92, 191, 25, 10, 4, 53, 124, 101, + 246, 47, 173, 172, 223, 192, 231, 41, 222, 243, 200, 80, 32, 167, 221, 37, 169, 119, 99, 91, + 242, 251, 49, 71, 234, 145, 58, 126, 256, 51, 226, 39, 67, 181, 21, 214, 137, 209, 135, 54, + 73, 132, 207, 237, 249, 151, 9, 55, 22, 163, 168, 170, 68, 130, 52, 175, 70, 28, 114, 97, + 193, 180, 72, 183, 176, 19, 59, 75, 30, 12, 159, 115, 46, 224, 141, 5, 2, 155, 62, 179, 123, + 152, 215, 86, 240, 96, 244, 149, 111, 250, 100, 40, 16, 212, 239, 147, 213, 188, 178, 174, + 121, 254, 153, 164, 117, 201, 29, 63, 128, 154, 113, 148, 162, 219, 139, 107, 197, 233, 196, + 27, 165, 66, 232, 247, 253, 204, 133, 156, 11, 210, 84, 85, 34, 65, 26, 216, 35, 14, 57, + 177, 225, 90, 36, 220, 88, 138, 158, 166, 15, 6, 208, 186, 23, 112, 199, 131, 1, + ], + [ + 1, 207, 187, 159, 17, 178, 95, 133, 32, 199, 73, 205, 30, 42, 213, 144, 253, 200, 23, 135, + 189, 59, 134, 239, 129, 232, 222, 208, 137, 89, 176, 195, 16, 228, 165, 231, 15, 21, 235, + 72, 255, 100, 140, 196, 223, 158, 67, 248, 193, 116, 111, 104, 197, 173, 88, 226, 8, 114, + 211, 244, 136, 139, 246, 36, 256, 50, 70, 98, 240, 79, 162, 124, 225, 58, 184, 52, 227, 215, + 44, 113, 4, 57, 234, 122, 68, 198, 123, 18, 128, 25, 35, 49, 120, 168, 81, 62, 241, 29, 92, + 26, 242, 236, 22, 185, 2, 157, 117, 61, 34, 99, 190, 9, 64, 141, 146, 153, 60, 84, 169, 31, + 249, 143, 46, 13, 121, 118, 11, 221, 1, 207, 187, 159, 17, 178, 95, 133, 32, 199, 73, 205, + 30, 42, 213, 144, 253, 200, 23, 135, 189, 59, 134, 239, 129, 232, 222, 208, 137, 89, 176, + 195, 16, 228, 165, 231, 15, 21, 235, 72, 255, 100, 140, 196, 223, 158, 67, 248, 193, 116, + 111, 104, 197, 173, 88, 226, 8, 114, 211, 244, 136, 139, 246, 36, 256, 50, 70, 98, 240, 79, + 162, 124, 225, 58, 184, 52, 227, 215, 44, 113, 4, 57, 234, 122, 68, 198, 123, 18, 128, 25, + 35, 49, 120, 168, 81, 62, 241, 29, 92, 26, 242, 236, 22, 185, 2, 157, 117, 61, 34, 99, 190, + 9, 64, 141, 146, 153, 60, 84, 169, 31, 249, 143, 46, 13, 121, 118, 11, 221, 1, + ], + [ + 1, 208, 88, 57, 34, 133, 165, 139, 128, 153, 213, 100, 240, 62, 46, 59, 193, 52, 22, 207, + 137, 226, 234, 99, 32, 231, 246, 25, 60, 144, 140, 79, 241, 13, 134, 116, 227, 185, 187, 89, + 8, 122, 190, 199, 15, 36, 35, 84, 253, 196, 162, 29, 121, 239, 111, 215, 2, 159, 176, 114, + 68, 9, 73, 21, 256, 49, 169, 200, 223, 124, 92, 118, 129, 104, 44, 157, 17, 195, 211, 198, + 64, 205, 235, 50, 120, 31, 23, 158, 225, 26, 11, 232, 197, 113, 117, 178, 16, 244, 123, 141, + 30, 72, 70, 168, 249, 135, 67, 58, 242, 221, 222, 173, 4, 61, 95, 228, 136, 18, 146, 42, + 255, 98, 81, 143, 189, 248, 184, 236, 1, 208, 88, 57, 34, 133, 165, 139, 128, 153, 213, 100, + 240, 62, 46, 59, 193, 52, 22, 207, 137, 226, 234, 99, 32, 231, 246, 25, 60, 144, 140, 79, + 241, 13, 134, 116, 227, 185, 187, 89, 8, 122, 190, 199, 15, 36, 35, 84, 253, 196, 162, 29, + 121, 239, 111, 215, 2, 159, 176, 114, 68, 9, 73, 21, 256, 49, 169, 200, 223, 124, 92, 118, + 129, 104, 44, 157, 17, 195, 211, 198, 64, 205, 235, 50, 120, 31, 23, 158, 225, 26, 11, 232, + 197, 113, 117, 178, 16, 244, 123, 141, 30, 72, 70, 168, 249, 135, 67, 58, 242, 221, 222, + 173, 4, 61, 95, 228, 136, 18, 146, 42, 255, 98, 81, 143, 189, 248, 184, 236, 1, + ], + [ + 1, 209, 248, 175, 81, 224, 42, 40, 136, 154, 61, 156, 222, 138, 58, 43, 249, 127, 72, 142, + 123, 7, 178, 194, 197, 53, 26, 37, 23, 181, 50, 170, 64, 12, 195, 149, 44, 201, 118, 247, + 223, 90, 49, 218, 73, 94, 114, 182, 2, 161, 239, 93, 162, 191, 84, 80, 15, 51, 122, 55, 187, + 19, 116, 86, 241, 254, 144, 27, 246, 14, 99, 131, 137, 106, 52, 74, 46, 105, 100, 83, 128, + 24, 133, 41, 88, 145, 236, 237, 189, 180, 98, 179, 146, 188, 228, 107, 4, 65, 221, 186, 67, + 125, 168, 160, 30, 102, 244, 110, 117, 38, 232, 172, 225, 251, 31, 54, 235, 28, 198, 5, 17, + 212, 104, 148, 92, 210, 200, 166, 256, 48, 9, 82, 176, 33, 215, 217, 121, 103, 196, 101, 35, + 119, 199, 214, 8, 130, 185, 115, 134, 250, 79, 63, 60, 204, 231, 220, 234, 76, 207, 87, 193, + 245, 62, 108, 213, 56, 139, 10, 34, 167, 208, 39, 184, 163, 143, 75, 255, 96, 18, 164, 95, + 66, 173, 177, 242, 206, 135, 202, 70, 238, 141, 171, 16, 3, 113, 230, 11, 243, 158, 126, + 120, 151, 205, 183, 211, 152, 157, 174, 129, 233, 124, 216, 169, 112, 21, 20, 68, 77, 159, + 78, 111, 69, 29, 150, 253, 192, 36, 71, 190, 132, 89, 97, 227, 155, 13, 147, 140, 219, 25, + 85, 32, 6, 226, 203, 22, 229, 59, 252, 240, 45, 153, 109, 165, 47, 57, 91, 1, + ], + [ + 1, 210, 153, 5, 22, 251, 25, 110, 227, 125, 36, 107, 111, 180, 21, 41, 129, 105, 205, 131, + 11, 254, 141, 55, 242, 191, 18, 182, 184, 90, 139, 149, 193, 181, 231, 194, 134, 127, 199, + 156, 121, 224, 9, 91, 92, 45, 198, 203, 225, 219, 244, 97, 67, 192, 228, 78, 189, 112, 133, + 174, 46, 151, 99, 230, 241, 238, 122, 177, 162, 96, 114, 39, 223, 56, 195, 87, 23, 204, 178, + 115, 249, 119, 61, 217, 81, 48, 57, 148, 240, 28, 226, 172, 140, 102, 89, 186, 253, 188, + 159, 237, 169, 24, 157, 74, 120, 14, 113, 86, 70, 51, 173, 93, 255, 94, 208, 247, 213, 12, + 207, 37, 60, 7, 185, 43, 35, 154, 215, 175, 256, 47, 104, 252, 235, 6, 232, 147, 30, 132, + 221, 150, 146, 77, 236, 216, 128, 152, 52, 126, 246, 3, 116, 202, 15, 66, 239, 75, 73, 167, + 118, 108, 64, 76, 26, 63, 123, 130, 58, 101, 136, 33, 248, 166, 165, 212, 59, 54, 32, 38, + 13, 160, 190, 65, 29, 179, 68, 145, 124, 83, 211, 106, 158, 27, 16, 19, 135, 80, 95, 161, + 143, 218, 34, 201, 62, 170, 234, 53, 79, 142, 8, 138, 196, 40, 176, 209, 200, 109, 17, 229, + 31, 85, 117, 155, 168, 71, 4, 69, 98, 20, 88, 233, 100, 183, 137, 243, 144, 171, 187, 206, + 84, 164, 2, 163, 49, 10, 44, 245, 50, 220, 197, 250, 72, 214, 222, 103, 42, 82, 1, + ], + [ + 1, 211, 60, 67, 2, 165, 120, 134, 4, 73, 240, 11, 8, 146, 223, 22, 16, 35, 189, 44, 32, 70, + 121, 88, 64, 140, 242, 176, 128, 23, 227, 95, 256, 46, 197, 190, 255, 92, 137, 123, 253, + 184, 17, 246, 249, 111, 34, 235, 241, 222, 68, 213, 225, 187, 136, 169, 193, 117, 15, 81, + 129, 234, 30, 162, 1, 211, 60, 67, 2, 165, 120, 134, 4, 73, 240, 11, 8, 146, 223, 22, 16, + 35, 189, 44, 32, 70, 121, 88, 64, 140, 242, 176, 128, 23, 227, 95, 256, 46, 197, 190, 255, + 92, 137, 123, 253, 184, 17, 246, 249, 111, 34, 235, 241, 222, 68, 213, 225, 187, 136, 169, + 193, 117, 15, 81, 129, 234, 30, 162, 1, 211, 60, 67, 2, 165, 120, 134, 4, 73, 240, 11, 8, + 146, 223, 22, 16, 35, 189, 44, 32, 70, 121, 88, 64, 140, 242, 176, 128, 23, 227, 95, 256, + 46, 197, 190, 255, 92, 137, 123, 253, 184, 17, 246, 249, 111, 34, 235, 241, 222, 68, 213, + 225, 187, 136, 169, 193, 117, 15, 81, 129, 234, 30, 162, 1, 211, 60, 67, 2, 165, 120, 134, + 4, 73, 240, 11, 8, 146, 223, 22, 16, 35, 189, 44, 32, 70, 121, 88, 64, 140, 242, 176, 128, + 23, 227, 95, 256, 46, 197, 190, 255, 92, 137, 123, 253, 184, 17, 246, 249, 111, 34, 235, + 241, 222, 68, 213, 225, 187, 136, 169, 193, 117, 15, 81, 129, 234, 30, 162, 1, + ], + [ + 1, 212, 226, 110, 190, 188, 21, 83, 120, 254, 135, 93, 184, 201, 207, 194, 8, 154, 9, 109, + 235, 219, 168, 150, 189, 233, 52, 230, 187, 66, 114, 10, 64, 204, 72, 101, 81, 210, 59, 172, + 227, 65, 159, 41, 211, 14, 141, 80, 255, 90, 62, 37, 134, 138, 215, 91, 17, 6, 244, 71, 146, + 112, 100, 126, 241, 206, 239, 39, 44, 76, 178, 214, 136, 48, 153, 54, 140, 125, 29, 237, + 129, 106, 113, 55, 95, 94, 139, 170, 60, 127, 196, 175, 92, 229, 232, 97, 4, 77, 133, 183, + 246, 238, 84, 75, 223, 245, 26, 115, 222, 33, 57, 5, 32, 102, 36, 179, 169, 105, 158, 86, + 242, 161, 208, 149, 234, 7, 199, 40, 256, 45, 31, 147, 67, 69, 236, 174, 137, 3, 122, 164, + 73, 56, 50, 63, 249, 103, 248, 148, 22, 38, 89, 107, 68, 24, 205, 27, 70, 191, 143, 247, + 193, 53, 185, 156, 176, 47, 198, 85, 30, 192, 98, 216, 46, 243, 116, 177, 2, 167, 195, 220, + 123, 119, 42, 166, 240, 251, 13, 186, 111, 145, 157, 131, 16, 51, 18, 218, 213, 181, 79, 43, + 121, 209, 104, 203, 117, 132, 228, 20, 128, 151, 144, 202, 162, 163, 118, 87, 197, 130, 61, + 82, 165, 28, 25, 160, 253, 180, 124, 74, 11, 19, 173, 182, 34, 12, 231, 142, 35, 224, 200, + 252, 225, 155, 221, 78, 88, 152, 99, 171, 15, 96, 49, 108, 23, 250, 58, 217, 1, + ], + [ + 1, 213, 137, 140, 8, 162, 68, 92, 64, 11, 30, 222, 255, 88, 240, 234, 241, 190, 121, 73, + 129, 235, 197, 70, 4, 81, 34, 46, 32, 134, 15, 111, 256, 44, 120, 117, 249, 95, 189, 165, + 193, 246, 227, 35, 2, 169, 17, 23, 16, 67, 136, 184, 128, 22, 60, 187, 253, 176, 223, 211, + 225, 123, 242, 146, 1, 213, 137, 140, 8, 162, 68, 92, 64, 11, 30, 222, 255, 88, 240, 234, + 241, 190, 121, 73, 129, 235, 197, 70, 4, 81, 34, 46, 32, 134, 15, 111, 256, 44, 120, 117, + 249, 95, 189, 165, 193, 246, 227, 35, 2, 169, 17, 23, 16, 67, 136, 184, 128, 22, 60, 187, + 253, 176, 223, 211, 225, 123, 242, 146, 1, 213, 137, 140, 8, 162, 68, 92, 64, 11, 30, 222, + 255, 88, 240, 234, 241, 190, 121, 73, 129, 235, 197, 70, 4, 81, 34, 46, 32, 134, 15, 111, + 256, 44, 120, 117, 249, 95, 189, 165, 193, 246, 227, 35, 2, 169, 17, 23, 16, 67, 136, 184, + 128, 22, 60, 187, 253, 176, 223, 211, 225, 123, 242, 146, 1, 213, 137, 140, 8, 162, 68, 92, + 64, 11, 30, 222, 255, 88, 240, 234, 241, 190, 121, 73, 129, 235, 197, 70, 4, 81, 34, 46, 32, + 134, 15, 111, 256, 44, 120, 117, 249, 95, 189, 165, 193, 246, 227, 35, 2, 169, 17, 23, 16, + 67, 136, 184, 128, 22, 60, 187, 253, 176, 223, 211, 225, 123, 242, 146, 1, + ], + [ + 1, 214, 50, 163, 187, 183, 98, 155, 17, 40, 79, 201, 95, 27, 124, 65, 32, 166, 58, 76, 73, + 202, 52, 77, 30, 252, 215, 7, 213, 93, 113, 24, 253, 172, 57, 119, 23, 39, 122, 151, 189, + 97, 198, 224, 134, 149, 18, 254, 129, 107, 25, 210, 222, 220, 49, 206, 137, 20, 168, 229, + 176, 142, 62, 161, 16, 83, 29, 38, 165, 101, 26, 167, 15, 126, 236, 132, 235, 175, 185, 12, + 255, 86, 157, 188, 140, 148, 61, 204, 223, 177, 99, 112, 67, 203, 9, 127, 193, 182, 141, + 105, 111, 110, 153, 103, 197, 10, 84, 243, 88, 71, 31, 209, 8, 170, 143, 19, 211, 179, 13, + 212, 136, 63, 118, 66, 246, 216, 221, 6, 256, 43, 207, 94, 70, 74, 159, 102, 240, 217, 178, + 56, 162, 230, 133, 192, 225, 91, 199, 181, 184, 55, 205, 180, 227, 5, 42, 250, 44, 164, 144, + 233, 4, 85, 200, 138, 234, 218, 135, 106, 68, 160, 59, 33, 123, 108, 239, 3, 128, 150, 232, + 47, 35, 37, 208, 51, 120, 237, 89, 28, 81, 115, 195, 96, 241, 174, 228, 219, 92, 156, 231, + 90, 242, 131, 21, 125, 22, 82, 72, 245, 2, 171, 100, 69, 117, 109, 196, 53, 34, 80, 158, + 145, 190, 54, 248, 130, 64, 75, 116, 152, 146, 147, 104, 154, 60, 247, 173, 14, 169, 186, + 226, 48, 249, 87, 114, 238, 46, 78, 244, 45, 121, 194, 139, 191, 11, 41, 36, 251, 1, + ], + [ + 1, 215, 222, 185, 197, 207, 44, 208, 2, 173, 187, 113, 137, 157, 88, 159, 4, 89, 117, 226, + 17, 57, 176, 61, 8, 178, 234, 195, 34, 114, 95, 122, 16, 99, 211, 133, 68, 228, 190, 244, + 32, 198, 165, 9, 136, 199, 123, 231, 64, 139, 73, 18, 15, 141, 246, 205, 128, 21, 146, 36, + 30, 25, 235, 153, 256, 42, 35, 72, 60, 50, 213, 49, 255, 84, 70, 144, 120, 100, 169, 98, + 253, 168, 140, 31, 240, 200, 81, 196, 249, 79, 23, 62, 223, 143, 162, 135, 241, 158, 46, + 124, 189, 29, 67, 13, 225, 59, 92, 248, 121, 58, 134, 26, 193, 118, 184, 239, 242, 116, 11, + 52, 129, 236, 111, 221, 227, 232, 22, 104, 1, 215, 222, 185, 197, 207, 44, 208, 2, 173, 187, + 113, 137, 157, 88, 159, 4, 89, 117, 226, 17, 57, 176, 61, 8, 178, 234, 195, 34, 114, 95, + 122, 16, 99, 211, 133, 68, 228, 190, 244, 32, 198, 165, 9, 136, 199, 123, 231, 64, 139, 73, + 18, 15, 141, 246, 205, 128, 21, 146, 36, 30, 25, 235, 153, 256, 42, 35, 72, 60, 50, 213, 49, + 255, 84, 70, 144, 120, 100, 169, 98, 253, 168, 140, 31, 240, 200, 81, 196, 249, 79, 23, 62, + 223, 143, 162, 135, 241, 158, 46, 124, 189, 29, 67, 13, 225, 59, 92, 248, 121, 58, 134, 26, + 193, 118, 184, 239, 242, 116, 11, 52, 129, 236, 111, 221, 227, 232, 22, 104, 1, + ], + [ + 1, 216, 139, 212, 46, 170, 226, 243, 60, 110, 116, 127, 190, 177, 196, 188, 2, 175, 21, 167, + 92, 83, 195, 229, 120, 220, 232, 254, 123, 97, 135, 119, 4, 93, 42, 77, 184, 166, 133, 201, + 240, 183, 207, 251, 246, 194, 13, 238, 8, 186, 84, 154, 111, 75, 9, 145, 223, 109, 157, 245, + 235, 131, 26, 219, 16, 115, 168, 51, 222, 150, 18, 33, 189, 218, 57, 233, 213, 5, 52, 181, + 32, 230, 79, 102, 187, 43, 36, 66, 121, 179, 114, 209, 169, 10, 104, 105, 64, 203, 158, 204, + 117, 86, 72, 132, 242, 101, 228, 161, 81, 20, 208, 210, 128, 149, 59, 151, 234, 172, 144, 7, + 227, 202, 199, 65, 162, 40, 159, 163, 256, 41, 118, 45, 211, 87, 31, 14, 197, 147, 141, 130, + 67, 80, 61, 69, 255, 82, 236, 90, 165, 174, 62, 28, 137, 37, 25, 3, 134, 160, 122, 138, 253, + 164, 215, 180, 73, 91, 124, 56, 17, 74, 50, 6, 11, 63, 244, 19, 249, 71, 173, 103, 146, 182, + 248, 112, 34, 148, 100, 12, 22, 126, 231, 38, 241, 142, 89, 206, 35, 107, 239, 224, 68, 39, + 200, 24, 44, 252, 205, 76, 225, 27, 178, 155, 70, 214, 221, 191, 136, 78, 143, 48, 88, 247, + 153, 152, 193, 54, 99, 53, 140, 171, 185, 125, 15, 156, 29, 96, 176, 237, 49, 47, 129, 108, + 198, 106, 23, 85, 113, 250, 30, 55, 58, 192, 95, 217, 98, 94, 1, + ], + [ + 1, 217, 58, 250, 23, 108, 49, 96, 15, 171, 99, 152, 88, 78, 221, 155, 225, 252, 200, 224, + 35, 142, 231, 12, 34, 182, 173, 19, 11, 74, 124, 180, 253, 160, 25, 28, 165, 82, 61, 130, + 197, 87, 118, 163, 162, 202, 144, 151, 128, 20, 228, 132, 117, 203, 104, 209, 121, 43, 79, + 181, 213, 218, 18, 51, 16, 131, 157, 145, 111, 186, 13, 251, 240, 166, 42, 119, 123, 220, + 195, 167, 2, 177, 116, 243, 46, 216, 98, 192, 30, 85, 198, 47, 176, 156, 185, 53, 193, 247, + 143, 191, 70, 27, 205, 24, 68, 107, 89, 38, 22, 148, 248, 103, 249, 63, 50, 56, 73, 164, + 122, 3, 137, 174, 236, 69, 67, 147, 31, 45, 256, 40, 199, 7, 234, 149, 208, 161, 242, 86, + 158, 105, 169, 179, 36, 102, 32, 5, 57, 33, 222, 115, 26, 245, 223, 75, 84, 238, 246, 183, + 133, 77, 4, 97, 232, 229, 92, 175, 196, 127, 60, 170, 139, 94, 95, 55, 113, 106, 129, 237, + 29, 125, 140, 54, 153, 48, 136, 214, 178, 76, 44, 39, 239, 206, 241, 126, 100, 112, 146, 71, + 244, 6, 17, 91, 215, 138, 134, 37, 62, 90, 255, 80, 141, 14, 211, 41, 159, 65, 227, 172, 59, + 210, 81, 101, 72, 204, 64, 10, 114, 66, 187, 230, 52, 233, 189, 150, 168, 219, 235, 109, 9, + 154, 8, 194, 207, 201, 184, 93, 135, 254, 120, 83, 21, 188, 190, 110, 226, 212, 1, + ], + [ + 1, 218, 236, 48, 184, 20, 248, 94, 189, 82, 143, 77, 81, 182, 98, 33, 255, 78, 42, 161, 146, + 217, 18, 69, 136, 93, 228, 103, 95, 150, 61, 191, 4, 101, 173, 192, 222, 80, 221, 119, 242, + 71, 58, 51, 67, 214, 135, 132, 249, 55, 168, 130, 70, 97, 72, 19, 30, 115, 141, 155, 123, + 86, 244, 250, 16, 147, 178, 254, 117, 63, 113, 219, 197, 27, 232, 204, 11, 85, 26, 14, 225, + 220, 158, 6, 23, 131, 31, 76, 120, 203, 50, 106, 235, 87, 205, 229, 64, 74, 198, 245, 211, + 252, 195, 105, 17, 108, 157, 45, 44, 83, 104, 56, 129, 109, 118, 24, 92, 10, 124, 47, 223, + 41, 200, 167, 169, 91, 49, 145, 256, 39, 21, 209, 73, 237, 9, 163, 68, 175, 114, 180, 176, + 75, 159, 224, 2, 179, 215, 96, 111, 40, 239, 188, 121, 164, 29, 154, 162, 107, 196, 66, 253, + 156, 84, 65, 35, 177, 36, 138, 15, 186, 199, 206, 190, 43, 122, 125, 8, 202, 89, 127, 187, + 160, 185, 238, 227, 142, 116, 102, 134, 171, 13, 7, 241, 110, 79, 3, 140, 194, 144, 38, 60, + 230, 25, 53, 246, 172, 231, 243, 32, 37, 99, 251, 234, 126, 226, 181, 137, 54, 207, 151, 22, + 170, 52, 28, 193, 183, 59, 12, 46, 5, 62, 152, 240, 149, 100, 212, 213, 174, 153, 201, 128, + 148, 139, 233, 165, 247, 133, 210, 34, 216, 57, 90, 88, 166, 208, 112, 1, + ], + [ + 1, 219, 159, 126, 95, 245, 199, 148, 30, 145, 144, 182, 23, 154, 59, 71, 129, 238, 208, 63, + 176, 251, 228, 74, 15, 201, 72, 91, 140, 77, 158, 164, 193, 119, 104, 160, 88, 254, 114, 37, + 136, 229, 36, 174, 70, 167, 79, 82, 225, 188, 52, 80, 44, 127, 57, 147, 68, 243, 18, 87, 35, + 212, 168, 41, 241, 94, 26, 40, 22, 192, 157, 202, 34, 250, 9, 172, 146, 106, 84, 149, 249, + 47, 13, 20, 11, 96, 207, 101, 17, 125, 133, 86, 73, 53, 42, 203, 253, 152, 135, 10, 134, 48, + 232, 179, 137, 191, 195, 43, 165, 155, 21, 230, 255, 76, 196, 5, 67, 24, 116, 218, 197, 224, + 226, 150, 211, 206, 139, 115, 256, 38, 98, 131, 162, 12, 58, 109, 227, 112, 113, 75, 234, + 103, 198, 186, 128, 19, 49, 194, 81, 6, 29, 183, 242, 56, 185, 166, 117, 180, 99, 93, 64, + 138, 153, 97, 169, 3, 143, 220, 121, 28, 221, 83, 187, 90, 178, 175, 32, 69, 205, 177, 213, + 130, 200, 110, 189, 14, 239, 170, 222, 45, 89, 216, 16, 163, 231, 217, 235, 65, 100, 55, + 223, 7, 248, 85, 111, 151, 173, 108, 8, 210, 244, 237, 246, 161, 50, 156, 240, 132, 124, + 171, 184, 204, 215, 54, 4, 105, 122, 247, 123, 209, 25, 78, 120, 66, 62, 214, 92, 102, 236, + 27, 2, 181, 61, 252, 190, 233, 141, 39, 60, 33, 31, 107, 46, 51, 118, 142, 1, + ], + [ + 1, 220, 84, 233, 117, 40, 62, 19, 68, 54, 58, 167, 246, 150, 104, 7, 255, 74, 89, 48, 23, + 177, 133, 219, 121, 149, 141, 180, 22, 214, 49, 243, 4, 109, 79, 161, 211, 160, 248, 76, 15, + 216, 232, 154, 213, 86, 159, 28, 249, 39, 99, 192, 92, 194, 18, 105, 227, 82, 50, 206, 88, + 85, 196, 201, 16, 179, 59, 130, 73, 126, 221, 47, 60, 93, 157, 102, 81, 87, 122, 112, 225, + 156, 139, 254, 111, 5, 72, 163, 137, 71, 200, 53, 95, 83, 13, 33, 64, 202, 236, 6, 35, 247, + 113, 188, 240, 115, 114, 151, 67, 91, 231, 191, 129, 110, 42, 245, 187, 20, 31, 138, 34, 27, + 29, 212, 123, 75, 52, 132, 256, 37, 173, 24, 140, 217, 195, 238, 189, 203, 199, 90, 11, 107, + 153, 250, 2, 183, 168, 209, 234, 80, 124, 38, 136, 108, 116, 77, 235, 43, 208, 14, 253, 148, + 178, 96, 46, 97, 9, 181, 242, 41, 25, 103, 44, 171, 98, 229, 8, 218, 158, 65, 165, 63, 239, + 152, 30, 175, 207, 51, 169, 172, 61, 56, 241, 78, 198, 127, 184, 131, 36, 210, 197, 164, + 100, 155, 176, 170, 135, 145, 32, 101, 118, 3, 146, 252, 185, 94, 120, 186, 57, 204, 162, + 174, 244, 224, 193, 55, 21, 251, 222, 10, 144, 69, 17, 142, 143, 106, 190, 166, 26, 66, 128, + 147, 215, 12, 70, 237, 226, 119, 223, 230, 228, 45, 134, 182, 205, 125, 1, + ], + [ + 1, 221, 11, 118, 121, 13, 46, 143, 249, 31, 169, 84, 60, 153, 146, 141, 64, 9, 190, 99, 34, + 61, 117, 157, 2, 185, 22, 236, 242, 26, 92, 29, 241, 62, 81, 168, 120, 49, 35, 25, 128, 18, + 123, 198, 68, 122, 234, 57, 4, 113, 44, 215, 227, 52, 184, 58, 225, 124, 162, 79, 240, 98, + 70, 50, 256, 36, 246, 139, 136, 244, 211, 114, 8, 226, 88, 173, 197, 104, 111, 116, 193, + 248, 67, 158, 223, 196, 140, 100, 255, 72, 235, 21, 15, 231, 165, 228, 16, 195, 176, 89, + 137, 208, 222, 232, 129, 239, 134, 59, 189, 135, 23, 200, 253, 144, 213, 42, 30, 205, 73, + 199, 32, 133, 95, 178, 17, 159, 187, 207, 1, 221, 11, 118, 121, 13, 46, 143, 249, 31, 169, + 84, 60, 153, 146, 141, 64, 9, 190, 99, 34, 61, 117, 157, 2, 185, 22, 236, 242, 26, 92, 29, + 241, 62, 81, 168, 120, 49, 35, 25, 128, 18, 123, 198, 68, 122, 234, 57, 4, 113, 44, 215, + 227, 52, 184, 58, 225, 124, 162, 79, 240, 98, 70, 50, 256, 36, 246, 139, 136, 244, 211, 114, + 8, 226, 88, 173, 197, 104, 111, 116, 193, 248, 67, 158, 223, 196, 140, 100, 255, 72, 235, + 21, 15, 231, 165, 228, 16, 195, 176, 89, 137, 208, 222, 232, 129, 239, 134, 59, 189, 135, + 23, 200, 253, 144, 213, 42, 30, 205, 73, 199, 32, 133, 95, 178, 17, 159, 187, 207, 1, + ], + [ + 1, 222, 197, 44, 2, 187, 137, 88, 4, 117, 17, 176, 8, 234, 34, 95, 16, 211, 68, 190, 32, + 165, 136, 123, 64, 73, 15, 246, 128, 146, 30, 235, 256, 35, 60, 213, 255, 70, 120, 169, 253, + 140, 240, 81, 249, 23, 223, 162, 241, 46, 189, 67, 225, 92, 121, 134, 193, 184, 242, 11, + 129, 111, 227, 22, 1, 222, 197, 44, 2, 187, 137, 88, 4, 117, 17, 176, 8, 234, 34, 95, 16, + 211, 68, 190, 32, 165, 136, 123, 64, 73, 15, 246, 128, 146, 30, 235, 256, 35, 60, 213, 255, + 70, 120, 169, 253, 140, 240, 81, 249, 23, 223, 162, 241, 46, 189, 67, 225, 92, 121, 134, + 193, 184, 242, 11, 129, 111, 227, 22, 1, 222, 197, 44, 2, 187, 137, 88, 4, 117, 17, 176, 8, + 234, 34, 95, 16, 211, 68, 190, 32, 165, 136, 123, 64, 73, 15, 246, 128, 146, 30, 235, 256, + 35, 60, 213, 255, 70, 120, 169, 253, 140, 240, 81, 249, 23, 223, 162, 241, 46, 189, 67, 225, + 92, 121, 134, 193, 184, 242, 11, 129, 111, 227, 22, 1, 222, 197, 44, 2, 187, 137, 88, 4, + 117, 17, 176, 8, 234, 34, 95, 16, 211, 68, 190, 32, 165, 136, 123, 64, 73, 15, 246, 128, + 146, 30, 235, 256, 35, 60, 213, 255, 70, 120, 169, 253, 140, 240, 81, 249, 23, 223, 162, + 241, 46, 189, 67, 225, 92, 121, 134, 193, 184, 242, 11, 129, 111, 227, 22, 1, + ], + [ + 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, + 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, + 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, + 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, + 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, + 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, + 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, + 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, + 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, + 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, + 242, 253, 136, 2, 189, 256, 34, 129, 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, + 68, 1, 223, 128, 17, 193, 120, 32, 197, 241, 30, 8, 242, 253, 136, 2, 189, 256, 34, 129, + 240, 64, 137, 225, 60, 16, 227, 249, 15, 4, 121, 255, 68, 1, + ], + [ + 1, 224, 61, 43, 123, 53, 50, 149, 223, 94, 239, 80, 187, 254, 99, 74, 128, 145, 98, 107, 67, + 102, 232, 54, 17, 210, 9, 217, 35, 130, 79, 220, 193, 56, 208, 75, 95, 206, 141, 230, 120, + 152, 124, 20, 111, 192, 89, 147, 32, 229, 153, 91, 81, 154, 58, 142, 197, 181, 195, 247, 73, + 161, 84, 55, 241, 14, 52, 83, 88, 180, 228, 186, 30, 38, 31, 5, 92, 48, 215, 101, 8, 250, + 231, 87, 213, 167, 143, 164, 242, 238, 113, 126, 211, 233, 21, 78, 253, 132, 13, 85, 22, 45, + 57, 175, 136, 138, 72, 194, 23, 12, 118, 218, 2, 191, 122, 86, 246, 106, 100, 41, 189, 188, + 221, 160, 117, 251, 198, 148, 256, 33, 196, 214, 134, 204, 207, 108, 34, 163, 18, 177, 70, + 3, 158, 183, 129, 112, 159, 150, 190, 155, 25, 203, 240, 47, 248, 40, 222, 127, 178, 37, 64, + 201, 49, 182, 162, 51, 116, 27, 137, 105, 133, 237, 146, 65, 168, 110, 225, 28, 104, 166, + 176, 103, 199, 115, 60, 76, 62, 10, 184, 96, 173, 202, 16, 243, 205, 174, 169, 77, 29, 71, + 227, 219, 226, 252, 165, 209, 42, 156, 249, 7, 26, 170, 44, 90, 114, 93, 15, 19, 144, 131, + 46, 24, 236, 179, 4, 125, 244, 172, 235, 212, 200, 82, 121, 119, 185, 63, 234, 245, 139, 39, + 255, 66, 135, 171, 11, 151, 157, 216, 68, 69, 36, 97, 140, 6, 59, 109, 1, + ], + [ + 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, + 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, + 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, + 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, + 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, + 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, + 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, + 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, + 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, + 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, + 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, + 249, 256, 32, 4, 129, 241, 255, 64, 8, 1, 225, 253, 128, 16, 2, 193, 249, 256, 32, 4, 129, + 241, 255, 64, 8, 1, + ], + [ + 1, 226, 190, 21, 120, 135, 184, 207, 8, 9, 235, 168, 189, 52, 187, 114, 64, 72, 81, 59, 227, + 159, 211, 141, 255, 62, 134, 215, 17, 244, 146, 100, 241, 239, 44, 178, 136, 153, 140, 29, + 129, 113, 95, 139, 60, 196, 92, 232, 4, 133, 246, 84, 223, 26, 222, 57, 32, 36, 169, 158, + 242, 208, 234, 199, 256, 31, 67, 236, 137, 122, 73, 50, 249, 248, 22, 89, 68, 205, 70, 143, + 193, 185, 176, 198, 30, 98, 46, 116, 2, 195, 123, 42, 240, 13, 111, 157, 16, 18, 213, 79, + 121, 104, 117, 228, 128, 144, 162, 118, 197, 61, 165, 25, 253, 124, 11, 173, 34, 231, 35, + 200, 225, 221, 88, 99, 15, 49, 23, 58, 1, 226, 190, 21, 120, 135, 184, 207, 8, 9, 235, 168, + 189, 52, 187, 114, 64, 72, 81, 59, 227, 159, 211, 141, 255, 62, 134, 215, 17, 244, 146, 100, + 241, 239, 44, 178, 136, 153, 140, 29, 129, 113, 95, 139, 60, 196, 92, 232, 4, 133, 246, 84, + 223, 26, 222, 57, 32, 36, 169, 158, 242, 208, 234, 199, 256, 31, 67, 236, 137, 122, 73, 50, + 249, 248, 22, 89, 68, 205, 70, 143, 193, 185, 176, 198, 30, 98, 46, 116, 2, 195, 123, 42, + 240, 13, 111, 157, 16, 18, 213, 79, 121, 104, 117, 228, 128, 144, 162, 118, 197, 61, 165, + 25, 253, 124, 11, 173, 34, 231, 35, 200, 225, 221, 88, 99, 15, 49, 23, 58, 1, + ], + [ + 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, + 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, + 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, + 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, + 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, + 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, + 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, + 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, + 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, + 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, + 240, 253, 120, 255, 60, 256, 30, 128, 15, 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, + 227, 129, 242, 193, 121, 225, 189, 241, 223, 249, 240, 253, 120, 255, 60, 256, 30, 128, 15, + 64, 136, 32, 68, 16, 34, 8, 17, 4, 137, 2, 197, 1, + ], + [ + 1, 228, 70, 26, 17, 21, 162, 185, 32, 100, 184, 61, 30, 158, 44, 9, 253, 116, 234, 153, 189, + 173, 123, 31, 129, 114, 35, 13, 137, 139, 81, 221, 16, 50, 92, 159, 15, 79, 22, 133, 255, + 58, 117, 205, 223, 215, 190, 144, 193, 57, 146, 135, 197, 198, 169, 239, 8, 25, 46, 208, + 136, 168, 11, 195, 256, 29, 187, 231, 240, 236, 95, 72, 225, 157, 73, 196, 227, 99, 213, + 248, 4, 141, 23, 104, 68, 84, 134, 226, 128, 143, 222, 244, 120, 118, 176, 36, 241, 207, + 165, 98, 242, 178, 235, 124, 2, 199, 140, 52, 34, 42, 67, 113, 64, 200, 111, 122, 60, 59, + 88, 18, 249, 232, 211, 49, 121, 89, 246, 62, 1, 228, 70, 26, 17, 21, 162, 185, 32, 100, 184, + 61, 30, 158, 44, 9, 253, 116, 234, 153, 189, 173, 123, 31, 129, 114, 35, 13, 137, 139, 81, + 221, 16, 50, 92, 159, 15, 79, 22, 133, 255, 58, 117, 205, 223, 215, 190, 144, 193, 57, 146, + 135, 197, 198, 169, 239, 8, 25, 46, 208, 136, 168, 11, 195, 256, 29, 187, 231, 240, 236, 95, + 72, 225, 157, 73, 196, 227, 99, 213, 248, 4, 141, 23, 104, 68, 84, 134, 226, 128, 143, 222, + 244, 120, 118, 176, 36, 241, 207, 165, 98, 242, 178, 235, 124, 2, 199, 140, 52, 34, 42, 67, + 113, 64, 200, 111, 122, 60, 59, 88, 18, 249, 232, 211, 49, 121, 89, 246, 62, 1, + ], + [ + 1, 229, 13, 150, 169, 151, 141, 164, 34, 76, 185, 217, 92, 251, 168, 179, 128, 14, 122, 182, + 44, 53, 58, 175, 240, 219, 36, 20, 211, 3, 173, 39, 193, 250, 196, 166, 235, 102, 228, 41, + 137, 19, 239, 247, 23, 127, 42, 109, 32, 132, 159, 174, 11, 206, 143, 108, 60, 119, 9, 5, + 117, 65, 236, 74, 241, 191, 49, 170, 123, 154, 57, 203, 227, 69, 124, 126, 70, 96, 139, 220, + 8, 33, 104, 172, 67, 180, 100, 27, 15, 94, 195, 194, 222, 209, 59, 147, 253, 112, 205, 171, + 95, 167, 207, 115, 121, 210, 31, 160, 146, 24, 99, 55, 2, 201, 26, 43, 81, 45, 25, 71, 68, + 152, 113, 177, 184, 245, 79, 101, 256, 28, 244, 107, 88, 106, 116, 93, 223, 181, 72, 40, + 165, 6, 89, 78, 129, 243, 135, 75, 213, 204, 199, 82, 17, 38, 221, 237, 46, 254, 84, 218, + 64, 7, 61, 91, 22, 155, 29, 216, 120, 238, 18, 10, 234, 130, 215, 148, 225, 125, 98, 83, + 246, 51, 114, 149, 197, 138, 248, 252, 140, 192, 21, 183, 16, 66, 208, 87, 134, 103, 200, + 54, 30, 188, 133, 131, 187, 161, 118, 37, 249, 224, 153, 85, 190, 77, 157, 230, 242, 163, + 62, 63, 35, 48, 198, 110, 4, 145, 52, 86, 162, 90, 50, 142, 136, 47, 226, 97, 111, 233, 158, + 202, 255, 56, 231, 214, 176, 212, 232, 186, 189, 105, 144, 80, 73, 12, 178, 156, 1, + ], + [ + 1, 230, 215, 106, 222, 174, 185, 145, 197, 78, 207, 65, 44, 97, 208, 38, 2, 203, 173, 212, + 187, 91, 113, 33, 137, 156, 157, 130, 88, 194, 159, 76, 4, 149, 89, 167, 117, 182, 226, 66, + 17, 55, 57, 3, 176, 131, 61, 152, 8, 41, 178, 77, 234, 107, 195, 132, 34, 110, 114, 6, 95, + 5, 122, 47, 16, 82, 99, 154, 211, 214, 133, 7, 68, 220, 228, 12, 190, 10, 244, 94, 32, 164, + 198, 51, 165, 171, 9, 14, 136, 183, 199, 24, 123, 20, 231, 188, 64, 71, 139, 102, 73, 85, + 18, 28, 15, 109, 141, 48, 246, 40, 205, 119, 128, 142, 21, 204, 146, 170, 36, 56, 30, 218, + 25, 96, 235, 80, 153, 238, 256, 27, 42, 151, 35, 83, 72, 112, 60, 179, 50, 192, 213, 160, + 49, 219, 255, 54, 84, 45, 70, 166, 144, 224, 120, 101, 100, 127, 169, 63, 98, 181, 253, 108, + 168, 90, 140, 75, 31, 191, 240, 202, 200, 254, 81, 126, 196, 105, 249, 216, 79, 180, 23, + 150, 62, 125, 223, 147, 143, 251, 162, 252, 135, 210, 241, 175, 158, 103, 46, 43, 124, 250, + 189, 37, 29, 245, 67, 247, 13, 163, 225, 93, 59, 206, 92, 86, 248, 243, 121, 74, 58, 233, + 134, 237, 26, 69, 193, 186, 118, 155, 184, 172, 239, 229, 242, 148, 116, 209, 11, 217, 52, + 138, 129, 115, 236, 53, 111, 87, 221, 201, 227, 39, 232, 161, 22, 177, 104, 19, 1, + ], + [ + 1, 231, 162, 157, 30, 248, 234, 84, 129, 244, 81, 207, 15, 124, 117, 42, 193, 122, 169, 232, + 136, 62, 187, 21, 225, 61, 213, 116, 68, 31, 222, 139, 241, 159, 235, 58, 34, 144, 111, 198, + 249, 208, 246, 29, 17, 72, 184, 99, 253, 104, 123, 143, 137, 36, 92, 178, 255, 52, 190, 200, + 197, 18, 46, 89, 256, 26, 95, 100, 227, 9, 23, 173, 128, 13, 176, 50, 242, 133, 140, 215, + 64, 135, 88, 25, 121, 195, 70, 236, 32, 196, 44, 141, 189, 226, 35, 118, 16, 98, 22, 199, + 223, 113, 146, 59, 8, 49, 11, 228, 240, 185, 73, 158, 4, 153, 134, 114, 120, 221, 165, 79, + 2, 205, 67, 57, 60, 239, 211, 168, 1, 231, 162, 157, 30, 248, 234, 84, 129, 244, 81, 207, + 15, 124, 117, 42, 193, 122, 169, 232, 136, 62, 187, 21, 225, 61, 213, 116, 68, 31, 222, 139, + 241, 159, 235, 58, 34, 144, 111, 198, 249, 208, 246, 29, 17, 72, 184, 99, 253, 104, 123, + 143, 137, 36, 92, 178, 255, 52, 190, 200, 197, 18, 46, 89, 256, 26, 95, 100, 227, 9, 23, + 173, 128, 13, 176, 50, 242, 133, 140, 215, 64, 135, 88, 25, 121, 195, 70, 236, 32, 196, 44, + 141, 189, 226, 35, 118, 16, 98, 22, 199, 223, 113, 146, 59, 8, 49, 11, 228, 240, 185, 73, + 158, 4, 153, 134, 114, 120, 221, 165, 79, 2, 205, 67, 57, 60, 239, 211, 168, 1, + ], + [ + 1, 232, 111, 52, 242, 118, 134, 248, 225, 29, 46, 135, 223, 79, 81, 31, 253, 100, 70, 49, + 60, 42, 235, 36, 128, 141, 73, 231, 136, 198, 190, 133, 16, 114, 234, 61, 17, 89, 88, 113, + 2, 207, 222, 104, 227, 236, 11, 239, 193, 58, 92, 13, 189, 158, 162, 62, 249, 200, 140, 98, + 120, 84, 213, 72, 256, 25, 146, 205, 15, 139, 123, 9, 32, 228, 211, 122, 34, 178, 176, 226, + 4, 157, 187, 208, 197, 215, 22, 221, 129, 116, 184, 26, 121, 59, 67, 124, 241, 143, 23, 196, + 240, 168, 169, 144, 255, 50, 35, 153, 30, 21, 246, 18, 64, 199, 165, 244, 68, 99, 95, 195, + 8, 57, 117, 159, 137, 173, 44, 185, 1, 232, 111, 52, 242, 118, 134, 248, 225, 29, 46, 135, + 223, 79, 81, 31, 253, 100, 70, 49, 60, 42, 235, 36, 128, 141, 73, 231, 136, 198, 190, 133, + 16, 114, 234, 61, 17, 89, 88, 113, 2, 207, 222, 104, 227, 236, 11, 239, 193, 58, 92, 13, + 189, 158, 162, 62, 249, 200, 140, 98, 120, 84, 213, 72, 256, 25, 146, 205, 15, 139, 123, 9, + 32, 228, 211, 122, 34, 178, 176, 226, 4, 157, 187, 208, 197, 215, 22, 221, 129, 116, 184, + 26, 121, 59, 67, 124, 241, 143, 23, 196, 240, 168, 169, 144, 255, 50, 35, 153, 30, 21, 246, + 18, 64, 199, 165, 244, 68, 99, 95, 195, 8, 57, 117, 159, 137, 173, 44, 185, 1, + ], + [ + 1, 233, 62, 54, 246, 7, 89, 177, 121, 180, 49, 109, 211, 76, 232, 86, 249, 192, 18, 82, 88, + 201, 59, 126, 60, 102, 122, 156, 111, 163, 200, 83, 64, 6, 113, 115, 67, 191, 42, 20, 34, + 212, 52, 37, 140, 238, 199, 107, 2, 209, 124, 108, 235, 14, 178, 97, 242, 103, 98, 218, 165, + 152, 207, 172, 241, 127, 36, 164, 176, 145, 118, 252, 120, 204, 244, 55, 222, 69, 143, 166, + 128, 12, 226, 230, 134, 125, 84, 40, 68, 167, 104, 74, 23, 219, 141, 214, 4, 161, 248, 216, + 213, 28, 99, 194, 227, 206, 196, 179, 73, 47, 157, 87, 225, 254, 72, 71, 95, 33, 236, 247, + 240, 151, 231, 110, 187, 138, 29, 75, 256, 24, 195, 203, 11, 250, 168, 80, 136, 77, 208, + 148, 46, 181, 25, 171, 8, 65, 239, 175, 169, 56, 198, 131, 197, 155, 135, 101, 146, 94, 57, + 174, 193, 251, 144, 142, 190, 66, 215, 237, 223, 45, 205, 220, 117, 19, 58, 150, 255, 48, + 133, 149, 22, 243, 79, 160, 15, 154, 159, 39, 92, 105, 50, 85, 16, 130, 221, 93, 81, 112, + 139, 5, 137, 53, 13, 202, 35, 188, 114, 91, 129, 245, 31, 27, 123, 132, 173, 217, 189, 90, + 153, 183, 234, 38, 116, 43, 253, 96, 9, 41, 44, 229, 158, 63, 30, 51, 61, 78, 184, 210, 100, + 170, 32, 3, 185, 186, 162, 224, 21, 10, 17, 106, 26, 147, 70, 119, 228, 182, 1, + ], + [ + 1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, 95, 128, 140, 121, 44, 16, 146, 240, 134, + 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, 190, 256, 23, 242, 88, 32, 35, 223, 11, 4, + 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, 123, 255, 46, 227, 176, 64, 70, 189, 22, 8, + 73, 120, 67, 1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, 95, 128, 140, 121, 44, 16, + 146, 240, 134, 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, 190, 256, 23, 242, 88, 32, + 35, 223, 11, 4, 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, 123, 255, 46, 227, 176, 64, + 70, 189, 22, 8, 73, 120, 67, 1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, 95, 128, 140, + 121, 44, 16, 146, 240, 134, 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, 190, 256, 23, + 242, 88, 32, 35, 223, 11, 4, 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, 123, 255, 46, + 227, 176, 64, 70, 189, 22, 8, 73, 120, 67, 1, 234, 15, 169, 225, 222, 34, 246, 253, 92, 197, + 95, 128, 140, 121, 44, 16, 146, 240, 134, 2, 211, 30, 81, 193, 187, 68, 235, 249, 184, 137, + 190, 256, 23, 242, 88, 32, 35, 223, 11, 4, 165, 60, 162, 129, 117, 136, 213, 241, 111, 17, + 123, 255, 46, 227, 176, 64, 70, 189, 22, 8, 73, 120, 67, 1, + ], + [ + 1, 235, 227, 146, 129, 246, 242, 73, 193, 123, 121, 165, 225, 190, 189, 211, 241, 95, 223, + 234, 249, 176, 240, 117, 253, 88, 120, 187, 255, 44, 60, 222, 256, 22, 30, 111, 128, 11, 15, + 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, 162, 34, 23, 8, 81, 17, 140, 4, 169, 137, 70, 2, + 213, 197, 35, 1, 235, 227, 146, 129, 246, 242, 73, 193, 123, 121, 165, 225, 190, 189, 211, + 241, 95, 223, 234, 249, 176, 240, 117, 253, 88, 120, 187, 255, 44, 60, 222, 256, 22, 30, + 111, 128, 11, 15, 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, 162, 34, 23, 8, 81, 17, 140, 4, + 169, 137, 70, 2, 213, 197, 35, 1, 235, 227, 146, 129, 246, 242, 73, 193, 123, 121, 165, 225, + 190, 189, 211, 241, 95, 223, 234, 249, 176, 240, 117, 253, 88, 120, 187, 255, 44, 60, 222, + 256, 22, 30, 111, 128, 11, 15, 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, 162, 34, 23, 8, + 81, 17, 140, 4, 169, 137, 70, 2, 213, 197, 35, 1, 235, 227, 146, 129, 246, 242, 73, 193, + 123, 121, 165, 225, 190, 189, 211, 241, 95, 223, 234, 249, 176, 240, 117, 253, 88, 120, 187, + 255, 44, 60, 222, 256, 22, 30, 111, 128, 11, 15, 184, 64, 134, 136, 92, 32, 67, 68, 46, 16, + 162, 34, 23, 8, 81, 17, 140, 4, 169, 137, 70, 2, 213, 197, 35, 1, + ], + [ + 1, 236, 184, 248, 189, 143, 81, 98, 255, 42, 146, 18, 136, 228, 95, 61, 4, 173, 222, 221, + 242, 58, 67, 135, 249, 168, 70, 72, 30, 141, 123, 244, 16, 178, 117, 113, 197, 232, 11, 26, + 225, 158, 23, 31, 120, 50, 235, 205, 64, 198, 211, 195, 17, 157, 44, 104, 129, 118, 92, 124, + 223, 200, 169, 49, 256, 21, 73, 9, 68, 114, 176, 159, 2, 215, 111, 239, 121, 29, 162, 196, + 253, 84, 35, 36, 15, 199, 190, 122, 8, 89, 187, 185, 227, 116, 134, 13, 241, 79, 140, 144, + 60, 25, 246, 231, 32, 99, 234, 226, 137, 207, 22, 52, 193, 59, 46, 62, 240, 100, 213, 153, + 128, 139, 165, 133, 34, 57, 88, 208, 1, 236, 184, 248, 189, 143, 81, 98, 255, 42, 146, 18, + 136, 228, 95, 61, 4, 173, 222, 221, 242, 58, 67, 135, 249, 168, 70, 72, 30, 141, 123, 244, + 16, 178, 117, 113, 197, 232, 11, 26, 225, 158, 23, 31, 120, 50, 235, 205, 64, 198, 211, 195, + 17, 157, 44, 104, 129, 118, 92, 124, 223, 200, 169, 49, 256, 21, 73, 9, 68, 114, 176, 159, + 2, 215, 111, 239, 121, 29, 162, 196, 253, 84, 35, 36, 15, 199, 190, 122, 8, 89, 187, 185, + 227, 116, 134, 13, 241, 79, 140, 144, 60, 25, 246, 231, 32, 99, 234, 226, 137, 207, 22, 52, + 193, 59, 46, 62, 240, 100, 213, 153, 128, 139, 165, 133, 34, 57, 88, 208, 1, + ], + [ + 1, 237, 143, 224, 146, 164, 61, 65, 242, 43, 168, 238, 123, 110, 113, 53, 225, 126, 50, 28, + 211, 149, 104, 233, 223, 166, 21, 94, 176, 78, 239, 103, 253, 80, 199, 132, 187, 115, 13, + 254, 60, 85, 99, 76, 22, 74, 62, 45, 128, 10, 57, 145, 184, 175, 98, 96, 136, 107, 173, 138, + 67, 202, 72, 102, 16, 194, 232, 243, 23, 54, 205, 12, 17, 174, 118, 210, 169, 218, 9, 77, 2, + 217, 29, 191, 35, 71, 122, 130, 227, 86, 79, 219, 246, 220, 226, 106, 193, 252, 100, 56, + 165, 41, 208, 209, 189, 75, 42, 188, 95, 156, 221, 206, 249, 160, 141, 7, 117, 230, 26, 251, + 120, 170, 198, 152, 44, 148, 124, 90, 256, 20, 114, 33, 111, 93, 196, 192, 15, 214, 89, 19, + 134, 147, 144, 204, 32, 131, 207, 229, 46, 108, 153, 24, 34, 91, 236, 163, 81, 179, 18, 154, + 4, 177, 58, 125, 70, 142, 244, 3, 197, 172, 158, 181, 235, 183, 195, 212, 129, 247, 200, + 112, 73, 82, 159, 161, 121, 150, 84, 119, 190, 55, 185, 155, 241, 63, 25, 14, 234, 203, 52, + 245, 240, 83, 139, 47, 88, 39, 248, 180, 255, 40, 228, 66, 222, 186, 135, 127, 30, 171, 178, + 38, 11, 37, 31, 151, 64, 5, 157, 201, 92, 216, 49, 48, 68, 182, 215, 69, 162, 101, 36, 51, + 8, 97, 116, 250, 140, 27, 231, 6, 137, 87, 59, 105, 213, 109, 133, 167, 1, + ], + [ + 1, 238, 104, 80, 22, 96, 232, 218, 227, 56, 221, 170, 111, 204, 236, 142, 129, 119, 52, 40, + 11, 48, 116, 109, 242, 28, 239, 85, 184, 102, 118, 71, 193, 188, 26, 20, 134, 24, 58, 183, + 121, 14, 248, 171, 92, 51, 59, 164, 225, 94, 13, 10, 67, 12, 29, 220, 189, 7, 124, 214, 46, + 154, 158, 82, 241, 47, 135, 5, 162, 6, 143, 110, 223, 132, 62, 107, 23, 77, 79, 41, 249, + 152, 196, 131, 81, 3, 200, 55, 240, 66, 31, 182, 140, 167, 168, 149, 253, 76, 98, 194, 169, + 130, 100, 156, 120, 33, 144, 91, 70, 212, 84, 203, 255, 38, 49, 97, 213, 65, 50, 78, 60, + 145, 72, 174, 35, 106, 42, 230, 256, 19, 153, 177, 235, 161, 25, 39, 30, 201, 36, 87, 146, + 53, 21, 115, 128, 138, 205, 217, 246, 209, 141, 148, 15, 229, 18, 172, 73, 155, 139, 186, + 64, 69, 231, 237, 123, 233, 199, 74, 136, 243, 9, 86, 165, 206, 198, 93, 32, 163, 244, 247, + 190, 245, 228, 37, 68, 250, 133, 43, 211, 103, 99, 175, 16, 210, 122, 252, 95, 251, 114, + 147, 34, 125, 195, 150, 234, 180, 178, 216, 8, 105, 61, 126, 176, 254, 57, 202, 17, 191, + 226, 75, 117, 90, 89, 108, 4, 181, 159, 63, 88, 127, 157, 101, 137, 224, 113, 166, 187, 45, + 173, 54, 2, 219, 208, 160, 44, 192, 207, 179, 197, 112, 185, 83, 222, 151, 215, 27, 1, + ], + [ + 1, 239, 67, 79, 120, 153, 73, 228, 8, 113, 22, 118, 189, 196, 70, 25, 64, 133, 176, 173, + 227, 26, 46, 200, 255, 36, 123, 99, 17, 208, 111, 58, 241, 31, 213, 21, 136, 122, 117, 207, + 129, 248, 162, 168, 60, 205, 165, 114, 4, 185, 11, 59, 223, 98, 35, 141, 32, 195, 88, 215, + 242, 13, 23, 100, 256, 18, 190, 178, 137, 104, 184, 29, 249, 144, 235, 139, 68, 61, 187, + 232, 193, 124, 81, 84, 30, 231, 211, 57, 2, 221, 134, 158, 240, 49, 146, 199, 16, 226, 44, + 236, 121, 135, 140, 50, 128, 9, 95, 89, 197, 52, 92, 143, 253, 72, 246, 198, 34, 159, 222, + 116, 225, 62, 169, 42, 15, 244, 234, 157, 1, 239, 67, 79, 120, 153, 73, 228, 8, 113, 22, + 118, 189, 196, 70, 25, 64, 133, 176, 173, 227, 26, 46, 200, 255, 36, 123, 99, 17, 208, 111, + 58, 241, 31, 213, 21, 136, 122, 117, 207, 129, 248, 162, 168, 60, 205, 165, 114, 4, 185, 11, + 59, 223, 98, 35, 141, 32, 195, 88, 215, 242, 13, 23, 100, 256, 18, 190, 178, 137, 104, 184, + 29, 249, 144, 235, 139, 68, 61, 187, 232, 193, 124, 81, 84, 30, 231, 211, 57, 2, 221, 134, + 158, 240, 49, 146, 199, 16, 226, 44, 236, 121, 135, 140, 50, 128, 9, 95, 89, 197, 52, 92, + 143, 253, 72, 246, 198, 34, 159, 222, 116, 225, 62, 169, 42, 15, 244, 234, 157, 1, + ], + [ + 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, + 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, + 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, + 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, + 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, + 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, + 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, + 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, + 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, + 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, + 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, + 1, 240, 32, 227, 253, 68, 129, 120, 16, 242, 255, 34, 193, 60, 8, 121, 256, 17, 225, 30, 4, + 189, 128, 137, 241, 15, 2, 223, 64, 197, 249, 136, 1, + ], + [ + 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, + 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, + 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, + 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, + 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, + 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, + 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, + 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, + 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, + 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, + 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, + 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, 241, 256, 16, 1, + ], + [ + 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, + 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, + 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, + 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, + 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, + 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, + 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, + 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, + 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, + 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, + 189, 249, 120, 256, 15, 32, 34, 4, 197, 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, 242, + 225, 223, 253, 60, 128, 136, 16, 17, 2, 227, 193, 189, 249, 120, 256, 15, 32, 34, 4, 197, + 129, 121, 241, 240, 255, 30, 64, 68, 8, 137, 1, + ], + [ + 1, 243, 196, 83, 123, 77, 207, 186, 223, 219, 18, 5, 187, 209, 158, 101, 128, 7, 159, 87, + 67, 90, 25, 164, 17, 19, 248, 126, 35, 24, 178, 78, 193, 125, 49, 85, 95, 212, 116, 175, + 120, 119, 133, 194, 111, 245, 168, 218, 32, 66, 104, 86, 81, 151, 199, 41, 197, 69, 62, 160, + 73, 6, 173, 148, 241, 224, 205, 214, 88, 53, 29, 108, 30, 94, 226, 177, 92, 254, 42, 183, 8, + 145, 26, 150, 213, 102, 114, 203, 242, 210, 144, 40, 211, 130, 236, 37, 253, 56, 244, 182, + 22, 206, 200, 27, 136, 152, 185, 237, 23, 192, 139, 110, 2, 229, 135, 166, 246, 154, 157, + 115, 189, 181, 36, 10, 117, 161, 59, 202, 256, 14, 61, 174, 134, 180, 50, 71, 34, 38, 239, + 252, 70, 48, 99, 156, 129, 250, 98, 170, 190, 167, 232, 93, 240, 238, 9, 131, 222, 233, 79, + 179, 64, 132, 208, 172, 162, 45, 141, 82, 137, 138, 124, 63, 146, 12, 89, 39, 225, 191, 153, + 171, 176, 106, 58, 216, 60, 188, 195, 97, 184, 251, 84, 109, 16, 33, 52, 43, 169, 204, 228, + 149, 227, 163, 31, 80, 165, 3, 215, 74, 249, 112, 231, 107, 44, 155, 143, 54, 15, 47, 113, + 217, 46, 127, 21, 220, 4, 201, 13, 75, 235, 51, 57, 230, 121, 105, 72, 20, 234, 65, 118, + 147, 255, 28, 122, 91, 11, 103, 100, 142, 68, 76, 221, 247, 140, 96, 198, 55, 1, + ], + [ + 1, 244, 169, 116, 34, 72, 92, 89, 128, 135, 44, 199, 240, 221, 211, 84, 193, 61, 235, 29, + 137, 18, 23, 215, 32, 98, 11, 114, 60, 248, 117, 21, 241, 208, 123, 200, 227, 133, 70, 118, + 8, 153, 67, 157, 15, 62, 222, 198, 253, 52, 95, 50, 121, 226, 146, 158, 2, 231, 81, 232, 68, + 144, 184, 178, 256, 13, 88, 141, 223, 185, 165, 168, 129, 122, 213, 58, 17, 36, 46, 173, 64, + 196, 22, 228, 120, 239, 234, 42, 225, 159, 246, 143, 197, 9, 140, 236, 16, 49, 134, 57, 30, + 124, 187, 139, 249, 104, 190, 100, 242, 195, 35, 59, 4, 205, 162, 207, 136, 31, 111, 99, + 255, 26, 176, 25, 189, 113, 73, 79, 1, 244, 169, 116, 34, 72, 92, 89, 128, 135, 44, 199, + 240, 221, 211, 84, 193, 61, 235, 29, 137, 18, 23, 215, 32, 98, 11, 114, 60, 248, 117, 21, + 241, 208, 123, 200, 227, 133, 70, 118, 8, 153, 67, 157, 15, 62, 222, 198, 253, 52, 95, 50, + 121, 226, 146, 158, 2, 231, 81, 232, 68, 144, 184, 178, 256, 13, 88, 141, 223, 185, 165, + 168, 129, 122, 213, 58, 17, 36, 46, 173, 64, 196, 22, 228, 120, 239, 234, 42, 225, 159, 246, + 143, 197, 9, 140, 236, 16, 49, 134, 57, 30, 124, 187, 139, 249, 104, 190, 100, 242, 195, 35, + 59, 4, 205, 162, 207, 136, 31, 111, 99, 255, 26, 176, 25, 189, 113, 73, 79, 1, + ], + [ + 1, 245, 144, 71, 176, 201, 158, 160, 136, 167, 52, 147, 35, 94, 157, 172, 249, 96, 133, 203, + 134, 191, 21, 5, 197, 206, 98, 109, 234, 19, 29, 166, 64, 3, 221, 175, 213, 14, 89, 217, + 223, 151, 244, 156, 184, 105, 25, 214, 2, 233, 31, 142, 95, 145, 59, 63, 15, 77, 104, 37, + 70, 188, 57, 87, 241, 192, 9, 149, 11, 125, 42, 10, 137, 155, 196, 218, 211, 38, 58, 75, + 128, 6, 185, 93, 169, 28, 178, 177, 189, 45, 231, 55, 111, 210, 50, 171, 4, 209, 62, 27, + 190, 33, 118, 126, 30, 154, 208, 74, 140, 119, 114, 174, 225, 127, 18, 41, 22, 250, 84, 20, + 17, 53, 135, 179, 165, 76, 116, 150, 256, 12, 113, 186, 81, 56, 99, 97, 121, 90, 205, 110, + 222, 163, 100, 85, 8, 161, 124, 54, 123, 66, 236, 252, 60, 51, 159, 148, 23, 238, 228, 91, + 193, 254, 36, 82, 44, 243, 168, 40, 34, 106, 13, 101, 73, 152, 232, 43, 255, 24, 226, 115, + 162, 112, 198, 194, 242, 180, 153, 220, 187, 69, 200, 170, 16, 65, 248, 108, 246, 132, 215, + 247, 120, 102, 61, 39, 46, 219, 199, 182, 129, 251, 72, 164, 88, 229, 79, 80, 68, 212, 26, + 202, 146, 47, 207, 86, 253, 48, 195, 230, 67, 224, 139, 131, 227, 103, 49, 183, 117, 138, + 143, 83, 32, 130, 239, 216, 235, 7, 173, 237, 240, 204, 122, 78, 92, 181, 141, 107, 1, + ], + [ + 1, 246, 121, 211, 249, 88, 60, 111, 64, 67, 34, 140, 2, 235, 242, 165, 241, 176, 120, 222, + 128, 134, 68, 23, 4, 213, 227, 73, 225, 95, 240, 187, 256, 11, 136, 46, 8, 169, 197, 146, + 193, 190, 223, 117, 255, 22, 15, 92, 16, 81, 137, 35, 129, 123, 189, 234, 253, 44, 30, 184, + 32, 162, 17, 70, 1, 246, 121, 211, 249, 88, 60, 111, 64, 67, 34, 140, 2, 235, 242, 165, 241, + 176, 120, 222, 128, 134, 68, 23, 4, 213, 227, 73, 225, 95, 240, 187, 256, 11, 136, 46, 8, + 169, 197, 146, 193, 190, 223, 117, 255, 22, 15, 92, 16, 81, 137, 35, 129, 123, 189, 234, + 253, 44, 30, 184, 32, 162, 17, 70, 1, 246, 121, 211, 249, 88, 60, 111, 64, 67, 34, 140, 2, + 235, 242, 165, 241, 176, 120, 222, 128, 134, 68, 23, 4, 213, 227, 73, 225, 95, 240, 187, + 256, 11, 136, 46, 8, 169, 197, 146, 193, 190, 223, 117, 255, 22, 15, 92, 16, 81, 137, 35, + 129, 123, 189, 234, 253, 44, 30, 184, 32, 162, 17, 70, 1, 246, 121, 211, 249, 88, 60, 111, + 64, 67, 34, 140, 2, 235, 242, 165, 241, 176, 120, 222, 128, 134, 68, 23, 4, 213, 227, 73, + 225, 95, 240, 187, 256, 11, 136, 46, 8, 169, 197, 146, 193, 190, 223, 117, 255, 22, 15, 92, + 16, 81, 137, 35, 129, 123, 189, 234, 253, 44, 30, 184, 32, 162, 17, 70, 1, + ], + [ + 1, 247, 100, 28, 234, 230, 13, 127, 15, 107, 215, 163, 169, 109, 195, 106, 225, 63, 141, + 132, 222, 93, 98, 48, 34, 174, 59, 181, 246, 110, 185, 206, 253, 40, 114, 145, 92, 108, 205, + 6, 197, 86, 168, 119, 95, 78, 248, 90, 128, 5, 207, 243, 140, 142, 122, 65, 121, 75, 21, 47, + 44, 74, 31, 204, 16, 97, 58, 191, 146, 82, 208, 233, 240, 170, 99, 38, 134, 202, 36, 154, 2, + 237, 200, 56, 211, 203, 26, 254, 30, 214, 173, 69, 81, 218, 133, 212, 193, 126, 25, 7, 187, + 186, 196, 96, 68, 91, 118, 105, 235, 220, 113, 155, 249, 80, 228, 33, 184, 216, 153, 12, + 137, 172, 79, 238, 190, 156, 239, 180, 256, 10, 157, 229, 23, 27, 244, 130, 242, 150, 42, + 94, 88, 148, 62, 151, 32, 194, 116, 125, 35, 164, 159, 209, 223, 83, 198, 76, 11, 147, 72, + 51, 4, 217, 143, 112, 165, 149, 52, 251, 60, 171, 89, 138, 162, 179, 9, 167, 129, 252, 50, + 14, 117, 115, 135, 192, 136, 182, 236, 210, 213, 183, 226, 53, 241, 160, 199, 66, 111, 175, + 49, 24, 17, 87, 158, 219, 123, 55, 221, 103, 255, 20, 57, 201, 46, 54, 231, 3, 227, 43, 84, + 188, 176, 39, 124, 45, 64, 131, 232, 250, 70, 71, 61, 161, 189, 166, 139, 152, 22, 37, 144, + 102, 8, 177, 29, 224, 73, 41, 104, 245, 120, 85, 178, 19, 67, 101, 18, 77, 1, + ], + [ + 1, 248, 81, 42, 136, 61, 222, 58, 249, 72, 123, 178, 197, 26, 23, 50, 64, 195, 44, 118, 223, + 49, 73, 114, 2, 239, 162, 84, 15, 122, 187, 116, 241, 144, 246, 99, 137, 52, 46, 100, 128, + 133, 88, 236, 189, 98, 146, 228, 4, 221, 67, 168, 30, 244, 117, 232, 225, 31, 235, 198, 17, + 104, 92, 200, 256, 9, 176, 215, 121, 196, 35, 199, 8, 185, 134, 79, 60, 231, 234, 207, 193, + 62, 213, 139, 34, 208, 184, 143, 255, 18, 95, 173, 242, 135, 70, 141, 16, 113, 11, 158, 120, + 205, 211, 157, 129, 124, 169, 21, 68, 159, 111, 29, 253, 36, 190, 89, 227, 13, 140, 25, 32, + 226, 22, 59, 240, 153, 165, 57, 1, 248, 81, 42, 136, 61, 222, 58, 249, 72, 123, 178, 197, + 26, 23, 50, 64, 195, 44, 118, 223, 49, 73, 114, 2, 239, 162, 84, 15, 122, 187, 116, 241, + 144, 246, 99, 137, 52, 46, 100, 128, 133, 88, 236, 189, 98, 146, 228, 4, 221, 67, 168, 30, + 244, 117, 232, 225, 31, 235, 198, 17, 104, 92, 200, 256, 9, 176, 215, 121, 196, 35, 199, 8, + 185, 134, 79, 60, 231, 234, 207, 193, 62, 213, 139, 34, 208, 184, 143, 255, 18, 95, 173, + 242, 135, 70, 141, 16, 113, 11, 158, 120, 205, 211, 157, 129, 124, 169, 21, 68, 159, 111, + 29, 253, 36, 190, 89, 227, 13, 140, 25, 32, 226, 22, 59, 240, 153, 165, 57, 1, + ], + [ + 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, + 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, + 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, + 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, + 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, + 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, + 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, + 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, + 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, + 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, + 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, + 193, 255, 16, 129, 253, 32, 1, 249, 64, 2, 241, 128, 4, 225, 256, 8, 193, 255, 16, 129, 253, + 32, 1, + ], + [ + 1, 250, 49, 171, 88, 155, 200, 142, 34, 19, 124, 160, 165, 130, 118, 202, 128, 132, 104, 43, + 213, 51, 157, 186, 240, 119, 195, 177, 46, 192, 198, 156, 193, 191, 205, 107, 22, 103, 50, + 164, 137, 69, 31, 40, 234, 161, 158, 179, 32, 33, 26, 75, 246, 77, 232, 175, 60, 94, 113, + 237, 140, 48, 178, 39, 241, 112, 244, 91, 134, 90, 141, 41, 227, 210, 72, 10, 187, 233, 168, + 109, 8, 201, 135, 83, 190, 212, 58, 108, 15, 152, 221, 252, 35, 12, 173, 74, 253, 28, 61, + 87, 162, 151, 228, 203, 121, 181, 18, 131, 111, 251, 42, 220, 2, 243, 98, 85, 176, 53, 143, + 27, 68, 38, 248, 63, 73, 3, 236, 147, 256, 7, 208, 86, 169, 102, 57, 115, 223, 238, 133, 97, + 92, 127, 139, 55, 129, 125, 153, 214, 44, 206, 100, 71, 17, 138, 62, 80, 211, 65, 59, 101, + 64, 66, 52, 150, 235, 154, 207, 93, 120, 188, 226, 217, 23, 96, 99, 78, 225, 224, 231, 182, + 11, 180, 25, 82, 197, 163, 144, 20, 117, 209, 79, 218, 16, 145, 13, 166, 123, 167, 116, 216, + 30, 47, 185, 247, 70, 24, 89, 148, 249, 56, 122, 174, 67, 45, 199, 149, 242, 105, 36, 5, + 222, 245, 84, 183, 4, 229, 196, 170, 95, 106, 29, 54, 136, 76, 239, 126, 146, 6, 215, 37, + 255, 14, 159, 172, 81, 204, 114, 230, 189, 219, 9, 194, 184, 254, 21, 110, 1, + ], + [ + 1, 251, 36, 41, 11, 191, 139, 194, 121, 45, 244, 78, 46, 238, 114, 87, 249, 48, 226, 186, + 169, 14, 173, 247, 60, 154, 104, 147, 146, 152, 116, 75, 64, 130, 248, 54, 190, 145, 158, + 80, 34, 53, 196, 109, 117, 69, 100, 171, 2, 245, 72, 82, 22, 125, 21, 131, 242, 90, 231, + 156, 92, 219, 228, 174, 241, 96, 195, 115, 81, 28, 89, 237, 120, 51, 208, 37, 35, 47, 232, + 150, 128, 3, 239, 108, 123, 33, 59, 160, 68, 106, 135, 218, 234, 138, 200, 85, 4, 233, 144, + 164, 44, 250, 42, 5, 227, 180, 205, 55, 184, 181, 199, 91, 225, 192, 133, 230, 162, 56, 178, + 217, 240, 102, 159, 74, 70, 94, 207, 43, 256, 6, 221, 216, 246, 66, 118, 63, 136, 212, 13, + 179, 211, 19, 143, 170, 8, 209, 31, 71, 88, 243, 84, 10, 197, 103, 153, 110, 111, 105, 141, + 182, 193, 127, 9, 203, 67, 112, 99, 177, 223, 204, 61, 148, 140, 188, 157, 86, 255, 12, 185, + 175, 235, 132, 236, 126, 15, 167, 26, 101, 165, 38, 29, 83, 16, 161, 62, 142, 176, 229, 168, + 20, 137, 206, 49, 220, 222, 210, 25, 107, 129, 254, 18, 149, 134, 224, 198, 97, 189, 151, + 122, 39, 23, 119, 57, 172, 253, 24, 113, 93, 213, 7, 215, 252, 30, 77, 52, 202, 73, 76, 58, + 166, 32, 65, 124, 27, 95, 201, 79, 40, 17, 155, 98, 183, 187, 163, 50, 214, 1, + ], + [ + 1, 252, 25, 132, 111, 216, 205, 3, 242, 75, 139, 76, 134, 101, 9, 212, 225, 160, 228, 145, + 46, 27, 122, 161, 223, 170, 178, 138, 81, 109, 226, 155, 253, 20, 157, 243, 70, 164, 208, + 245, 60, 214, 215, 210, 235, 110, 221, 180, 128, 131, 116, 191, 73, 149, 26, 127, 136, 91, + 59, 219, 190, 78, 124, 151, 16, 177, 143, 56, 234, 115, 196, 48, 17, 172, 168, 188, 88, 74, + 144, 51, 2, 247, 50, 7, 222, 175, 153, 6, 227, 150, 21, 152, 11, 202, 18, 167, 193, 63, 199, + 33, 92, 54, 244, 65, 189, 83, 99, 19, 162, 218, 195, 53, 249, 40, 57, 229, 140, 71, 159, + 233, 120, 171, 173, 163, 213, 220, 185, 103, 256, 5, 232, 125, 146, 41, 52, 254, 15, 182, + 118, 181, 123, 156, 248, 45, 32, 97, 29, 112, 211, 230, 135, 96, 34, 87, 79, 119, 176, 148, + 31, 102, 4, 237, 100, 14, 187, 93, 49, 12, 197, 43, 42, 47, 22, 147, 36, 77, 129, 126, 141, + 66, 184, 108, 231, 130, 121, 166, 198, 38, 67, 179, 133, 106, 241, 80, 114, 201, 23, 142, + 61, 209, 240, 85, 89, 69, 169, 183, 113, 206, 255, 10, 207, 250, 35, 82, 104, 251, 30, 107, + 236, 105, 246, 55, 239, 90, 64, 194, 58, 224, 165, 203, 13, 192, 68, 174, 158, 238, 95, 39, + 62, 204, 8, 217, 200, 28, 117, 186, 98, 24, 137, 86, 84, 94, 44, 37, 72, 154, 1, + ], + [ + 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, + 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, + 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, + 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, + 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, + 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, + 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, + 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, + 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, + 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, + 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, + 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, 253, 16, 193, 256, 4, 241, 64, 1, + ], + [ + 1, 254, 9, 230, 81, 14, 215, 126, 136, 106, 196, 183, 222, 105, 199, 174, 249, 24, 185, 216, + 123, 145, 79, 20, 197, 180, 231, 78, 23, 188, 207, 150, 64, 65, 62, 71, 44, 125, 139, 97, + 223, 102, 208, 147, 73, 38, 143, 85, 2, 251, 18, 203, 162, 28, 173, 252, 15, 212, 135, 109, + 187, 210, 141, 91, 241, 48, 113, 175, 246, 33, 158, 40, 137, 103, 205, 156, 46, 119, 157, + 43, 128, 130, 124, 142, 88, 250, 21, 194, 189, 204, 159, 37, 146, 76, 29, 170, 4, 245, 36, + 149, 67, 56, 89, 247, 30, 167, 13, 218, 117, 163, 25, 182, 225, 96, 226, 93, 235, 66, 59, + 80, 17, 206, 153, 55, 92, 238, 57, 86, 256, 3, 248, 27, 176, 243, 42, 131, 121, 151, 61, 74, + 35, 152, 58, 83, 8, 233, 72, 41, 134, 112, 178, 237, 60, 77, 26, 179, 234, 69, 50, 107, 193, + 192, 195, 186, 213, 132, 118, 160, 34, 155, 49, 110, 184, 219, 114, 172, 255, 6, 239, 54, + 95, 229, 84, 5, 242, 45, 122, 148, 70, 47, 116, 166, 16, 209, 144, 82, 11, 224, 99, 217, + 120, 154, 52, 101, 211, 138, 100, 214, 129, 127, 133, 115, 169, 7, 236, 63, 68, 53, 98, 220, + 111, 181, 228, 87, 253, 12, 221, 108, 190, 201, 168, 10, 227, 90, 244, 39, 140, 94, 232, 75, + 32, 161, 31, 164, 22, 191, 198, 177, 240, 51, 104, 202, 165, 19, 200, 171, 1, + ], + [ + 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, + 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, + 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, + 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, + 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, + 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, + 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, + 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, + 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, + 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, + 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, + 129, 256, 2, 253, 8, 241, 32, 193, 128, 1, 255, 4, 249, 16, 225, 64, 129, 256, 2, 253, 8, + 241, 32, 193, 128, 1, + ], + [ + 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, + 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, + 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, + 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, + 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, + 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, + 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, + 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, + 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, + 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, + 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, 256, 1, + 256, 1, 256, 1, + ], ]; fn main(x: Field, y: pub Field) { diff --git a/noir/noir-repo/test_programs/execution_success/regression_5045/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_5045/src/main.nr index d1bc4f663fd..545694368fd 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_5045/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_5045/src/main.nr @@ -5,7 +5,7 @@ fn main(is_active: bool) { let a = EmbeddedCurvePoint { x: 0x1d8eb4378a3bde41e0b6a9a8dcbd21b7ff9c51bdd6ca13ce989abbbf90df3666, y: 0x06075b63354f2504f9cddba0b94ed0cef35fc88615e69ec1f853b51eb79a24a0, - is_infinite: false + is_infinite: false, }; if is_active { @@ -13,7 +13,7 @@ fn main(is_active: bool) { let d = bad.double(); let e = std::embedded_curve_ops::multi_scalar_mul( [a, bad], - [EmbeddedCurveScalar { lo: 1, hi: 0 }, EmbeddedCurveScalar { lo: 1, hi: 0 }] + [EmbeddedCurveScalar { lo: 1, hi: 0 }, EmbeddedCurveScalar { lo: 1, hi: 0 }], ); assert(e.x != d.x); } diff --git a/noir/noir-repo/test_programs/execution_success/regression_5252/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_5252/src/main.nr index 4b4d1937c0e..b3d2e5b4116 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_5252/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_5252/src/main.nr @@ -9,14 +9,16 @@ pub fn poseidon_hash(inputs: [Field; N]) -> Field { fn main( to_hash: [[Field; HASH_LENGTH]; NUM_HASHES], - enable: [bool; NUM_HASHES] + enable: [bool; NUM_HASHES], ) -> pub [Field; NUM_HASHES] { let mut result = [0; NUM_HASHES]; for i in 0..NUM_HASHES { let enable = enable[i]; let to_hash = to_hash[i]; if enable { - result[i] = poseidon_hash(to_hash) + poseidon::bn254::sponge(to_hash) + mimc::mimc_bn254(to_hash); + result[i] = poseidon_hash(to_hash) + + poseidon::bn254::sponge(to_hash) + + mimc::mimc_bn254(to_hash); } } result diff --git a/noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr index d8aeb76356b..895a6983ad9 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr @@ -3,16 +3,18 @@ fn main(input: Field, enable: bool) { let hash = no_predicate_function(input); // `EnableSideEffects` instruction from above instruction leaks out and removes the predicate from this call, // resulting in execution failure. - unsafe { - fail(hash) - }; + unsafe { fail(hash) }; } } #[no_predicates] fn no_predicate_function(enable: Field) -> Field { // if-statement ensures that an `EnableSideEffects` instruction is emitted. - if enable == 0 { 1 } else { 0 } + if enable == 0 { + 1 + } else { + 0 + } } unconstrained fn fail(_: Field) { diff --git a/noir/noir-repo/test_programs/execution_success/regression_5615/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_5615/src/main.nr index afb641e510d..1d8e0a045cd 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_5615/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_5615/src/main.nr @@ -3,9 +3,9 @@ use std::hash::BuildHasherDefault; use std::hash::poseidon2::Poseidon2Hasher; unconstrained fn main() { - comptime - { - let mut map: UHashMap> = UHashMap::default(); + comptime { + let mut map: UHashMap> = + UHashMap::default(); map.insert(1, 2); } diff --git a/noir/noir-repo/test_programs/execution_success/regression_capacity_tracker/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_capacity_tracker/src/main.nr index be645c811d2..11690b5c186 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_capacity_tracker/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_capacity_tracker/src/main.nr @@ -1,14 +1,14 @@ // Reference https://github.com/noir-lang/noir/issues/4395#issuecomment-2018948631 -// for context. +// for context. // We were not accurately accounting for situations where the slice capacity tracker // was expecting a capacity from slice intrinsic results. fn main(expected: pub Field, first: Field, input: [Field; 20]) { let mut hasher_slice = input.as_slice(); hasher_slice = hasher_slice.push_front(first); assert(hasher_slice[0] == expected); - // We need a conditional based upon witnesses - // to force a store of the slice. - // If this successfully compiles it means we have stored + // We need a conditional based upon witnesses + // to force a store of the slice. + // If this successfully compiles it means we have stored // the results of the slice intrinsics used above. if expected as u32 > 10 { hasher_slice[expected - 10] = 100; diff --git a/noir/noir-repo/test_programs/execution_success/regression_struct_array_conditional/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_struct_array_conditional/src/main.nr index 17502a9fe50..fe5f1ef1918 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_struct_array_conditional/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_struct_array_conditional/src/main.nr @@ -1,15 +1,15 @@ -struct foo { +struct foo { value: Field, counter: u8, dummy: u8, } struct bar { - dummy: [u8;3], + dummy: [u8; 3], value: Field, counter: u8, } struct bar_field { - dummy: [Field;3], + dummy: [Field; 3], value: Field, counter: u8, } diff --git a/noir/noir-repo/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr index 63c2493fc89..fc1e55ee641 100644 --- a/noir/noir-repo/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr @@ -7,9 +7,7 @@ fn main(x: u8, nest: bool) { #[no_predicates] pub fn unsafe_assert(msg: [u8; N]) -> u8 { - let block = unsafe { - get_block(msg) - }; + let block = unsafe { get_block(msg) }; verify_block(msg, block); block[0] } diff --git a/noir/noir-repo/test_programs/execution_success/schnorr/src/main.nr b/noir/noir-repo/test_programs/execution_success/schnorr/src/main.nr index 835ea2ffb1f..21845cd54fa 100644 --- a/noir/noir-repo/test_programs/execution_success/schnorr/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/schnorr/src/main.nr @@ -7,21 +7,23 @@ fn main( message_field: Field, pub_key_x: Field, pub_key_y: Field, - signature: [u8; 64] + signature: [u8; 64], ) { // Regression for issue #2421 // We want to make sure that we can accurately verify a signature whose message is a slice vs. an array let message_field_bytes: [u8; 10] = message_field.to_be_bytes(); - // Is there ever a situation where someone would want + // Is there ever a situation where someone would want // to ensure that a signature was invalid? // Check that passing a slice as the message is valid - let valid_signature = std::schnorr::verify_signature_slice(pub_key_x, pub_key_y, signature, message_field_bytes); + let valid_signature = + std::schnorr::verify_signature_slice(pub_key_x, pub_key_y, signature, message_field_bytes); assert(valid_signature); // Check that passing an array as the message is valid let valid_signature = std::schnorr::verify_signature(pub_key_x, pub_key_y, signature, message); assert(valid_signature); - let pub_key = embedded_curve_ops::EmbeddedCurvePoint { x: pub_key_x, y: pub_key_y, is_infinite: false }; + let pub_key = + embedded_curve_ops::EmbeddedCurvePoint { x: pub_key_x, y: pub_key_y, is_infinite: false }; let valid_signature = std::schnorr::verify_signature_noir(pub_key, signature, message); assert(valid_signature); std::schnorr::assert_valid_signature(pub_key, signature, message); diff --git a/noir/noir-repo/test_programs/execution_success/sha256/src/main.nr b/noir/noir-repo/test_programs/execution_success/sha256/src/main.nr index 29bc9ac371a..d26d916ccff 100644 --- a/noir/noir-repo/test_programs/execution_success/sha256/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/sha256/src/main.nr @@ -1,5 +1,5 @@ // Sha256 example -// +// // Calls Sha256 from the standard library. // // The Compiler sees this special function and creates an ACIR gate @@ -9,7 +9,6 @@ // // Not yet here: For R1CS, it is more about manipulating arithmetic gates to get performance // This can be done in ACIR! - fn main(x: Field, result: [u8; 32], input: [u8; 2], toggle: bool) { // We use the `as` keyword here to denote the fact that we want to take just the first byte from the x Field // The padding is taken care of by the program diff --git a/noir/noir-repo/test_programs/execution_success/sha256_regression/src/main.nr b/noir/noir-repo/test_programs/execution_success/sha256_regression/src/main.nr index 83049640ac4..dbbcc07e501 100644 --- a/noir/noir-repo/test_programs/execution_success/sha256_regression/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/sha256_regression/src/main.nr @@ -14,7 +14,7 @@ fn main( // This is the same as `msg_big_with_padding` but with no padding msg_big_no_padding: [u8; 297], message_size: u64, - result_big_with_padding: pub [u8; 32] + result_big_with_padding: pub [u8; 32], ) { let hash = std::hash::sha256_var(msg_just_over_block, msg_just_over_block.len() as u64); assert_eq(hash, result_just_over_block); @@ -27,7 +27,7 @@ fn main( let hash = std::hash::sha256_var( msg_big_not_block_multiple, - msg_big_not_block_multiple.len() as u64 + msg_big_not_block_multiple.len() as u64, ); assert_eq(hash, result_big); diff --git a/noir/noir-repo/test_programs/execution_success/sha2_byte/src/main.nr b/noir/noir-repo/test_programs/execution_success/sha2_byte/src/main.nr index aecd9fba2f3..1b4bed1a643 100644 --- a/noir/noir-repo/test_programs/execution_success/sha2_byte/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/sha2_byte/src/main.nr @@ -1,5 +1,4 @@ // Test Noir implementations of SHA256 and SHA512 on a one-byte message. - fn main(x: Field, result256: [u8; 32], result512: [u8; 64]) { let digest256 = std::sha256::digest([x as u8]); assert(digest256 == result256); diff --git a/noir/noir-repo/test_programs/execution_success/signed_arithmetic/src/main.nr b/noir/noir-repo/test_programs/execution_success/signed_arithmetic/src/main.nr index 7a997d177ba..9b72b688bc5 100644 --- a/noir/noir-repo/test_programs/execution_success/signed_arithmetic/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/signed_arithmetic/src/main.nr @@ -4,7 +4,7 @@ fn main(mut x: i32, mut y: i32, z: i32) { assert(s1 + s2 == 13); assert(x + y == 13); - s2= -8; + s2 = -8; y = -y; assert(s1 + s2 == -3); assert(x + y == -3); diff --git a/noir/noir-repo/test_programs/execution_success/signed_division/src/main.nr b/noir/noir-repo/test_programs/execution_success/signed_division/src/main.nr index 207ef59986b..64ba4a5354c 100644 --- a/noir/noir-repo/test_programs/execution_success/signed_division/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/signed_division/src/main.nr @@ -1,4 +1,4 @@ -// Testing signed integer division: +// Testing signed integer division: // 7/3 = 2 // -7/3 = -2 // -7/-3 = 2 diff --git a/noir/noir-repo/test_programs/execution_success/simple_add_and_ret_arr/src/main.nr b/noir/noir-repo/test_programs/execution_success/simple_add_and_ret_arr/src/main.nr index 016c4fedf40..891ea9c4982 100644 --- a/noir/noir-repo/test_programs/execution_success/simple_add_and_ret_arr/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/simple_add_and_ret_arr/src/main.nr @@ -1,4 +1,4 @@ -// A simple program to test that SSA array values elements +// A simple program to test that SSA array values elements // aren't disconnected from their instruction results, and // that dead instruction elemination looks inside of arrays // when deciding whether of not an instruction should be diff --git a/noir/noir-repo/test_programs/execution_success/simple_comparison/src/main.nr b/noir/noir-repo/test_programs/execution_success/simple_comparison/src/main.nr index 05800440459..45c4e4a0321 100644 --- a/noir/noir-repo/test_programs/execution_success/simple_comparison/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/simple_comparison/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is comparison fn main(x: Field, y: Field) { assert(x as u32 < y as u32); diff --git a/noir/noir-repo/test_programs/execution_success/simple_print/src/main.nr b/noir/noir-repo/test_programs/execution_success/simple_print/src/main.nr index 3a68f8cc4c3..938f770c5a5 100644 --- a/noir/noir-repo/test_programs/execution_success/simple_print/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/simple_print/src/main.nr @@ -1,6 +1,5 @@ // Simple program for testing the logging // of single witnesses and witness arrays. - fn main(x: Field, y: pub Field) { std::println(x); std::println([x, y]); diff --git a/noir/noir-repo/test_programs/execution_success/simple_shield/src/main.nr b/noir/noir-repo/test_programs/execution_success/simple_shield/src/main.nr index fd2fc20d08f..35b50150986 100644 --- a/noir/noir-repo/test_programs/execution_success/simple_shield/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/simple_shield/src/main.nr @@ -1,6 +1,6 @@ fn main( // Public key of note - // all notes have the same denomination + // all notes have the same denomination priv_key: Field, // Merkle membership proof note_root: pub Field, @@ -8,7 +8,7 @@ fn main( note_hash_path: [Field; 3], // Receiver public key to_pubkey_x: Field, - to_pubkey_y: Field + to_pubkey_y: Field, ) -> pub [Field; 2] { let priv_key_as_scalar = std::embedded_curve_ops::EmbeddedCurveScalar { lo: priv_key, hi: 0 }; // Compute public key from private key to show ownership diff --git a/noir/noir-repo/test_programs/execution_success/simple_shift_left_right/src/main.nr b/noir/noir-repo/test_programs/execution_success/simple_shift_left_right/src/main.nr index 40698af6ce7..f5d06eff25a 100644 --- a/noir/noir-repo/test_programs/execution_success/simple_shift_left_right/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/simple_shift_left_right/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested are left and right shifts. fn main(x: u32) { let z = x >> 4; diff --git a/noir/noir-repo/test_programs/execution_success/single_verify_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/single_verify_proof/src/main.nr index 4eb0cfdf6d0..6f880f085e8 100644 --- a/noir/noir-repo/test_programs/execution_success/single_verify_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/single_verify_proof/src/main.nr @@ -1,4 +1,3 @@ - // This circuit aggregates one proof from `assert_statement_recursive`. fn main( verification_key: [Field; 114], @@ -9,7 +8,7 @@ fn main( public_inputs: pub [Field; 1], // This is currently not public. It is fine given that the vk is a part of the circuit definition. // I believe we want to eventually make it public too though. - key_hash: Field + key_hash: Field, ) { std::verify_proof(verification_key, proof, public_inputs, key_hash); } diff --git a/noir/noir-repo/test_programs/execution_success/slice_regex/src/main.nr b/noir/noir-repo/test_programs/execution_success/slice_regex/src/main.nr index 3b860839a6e..4ba33e83903 100644 --- a/noir/noir-repo/test_programs/execution_success/slice_regex/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/slice_regex/src/main.nr @@ -55,7 +55,11 @@ impl Regex for str { } // And -impl Regex for (T, U) where T: Regex, U: Regex { +impl Regex for (T, U) +where + T: Regex, + U: Regex, +{ fn match(self, input: [u8]) -> Match { let lhs_result = self.0.match(input); if lhs_result.succeeded { @@ -64,7 +68,7 @@ impl Regex for (T, U) where T: Regex, U: Regex { Match { succeeded: true, match_ends: lhs_result.match_ends + rhs_result.match_ends, - leftover: rhs_result.leftover + leftover: rhs_result.leftover, } } else { Match { succeeded: false, match_ends: 0, leftover: input } @@ -80,7 +84,10 @@ struct Repeated { inner: T, } -impl Regex for Repeated where T: Regex { +impl Regex for Repeated +where + T: Regex, +{ fn match(self, input: [u8]) -> Match { let mut result = Match::empty(input); for _ in 0..N { @@ -102,7 +109,11 @@ struct Or { rhs: U, } -impl Regex for Or where T: Regex, U: Regex { +impl Regex for Or +where + T: Regex, + U: Regex, +{ fn match(self, input: [u8]) -> Match { let lhs_result = self.lhs.match(input); if lhs_result.succeeded { @@ -117,7 +128,10 @@ struct Question { inner: T, } -impl Regex for Question where T: Regex { +impl Regex for Question +where + T: Regex, +{ fn match(self, input: [u8]) -> Match { Or { lhs: self.inner, rhs: () }.match(input) } @@ -128,7 +142,10 @@ struct Star { inner: T, } -impl Regex for Star where T: Regex { +impl Regex for Star +where + T: Regex, +{ fn match(self, input: [u8]) -> Match { let regex: Repeated<_, N> = Repeated { inner: Question { inner: self.inner } }; regex.match(input) @@ -140,7 +157,10 @@ struct Plus { inner: T, } -impl Regex for Plus where T: Regex { +impl Regex for Plus +where + T: Regex, +{ fn match(self, input: [u8]) -> Match { std::static_assert(N_PRED + 1 == N, "N - 1 != N_PRED"); let star: Star = Star { inner: self.inner }; @@ -209,33 +229,33 @@ fn main() { println(result); assert_eq(result, Match { succeeded: true, match_ends: 3, leftover: &[] }); // TODO(https://github.com/noir-lang/noir/issues/6285): re-enable these cases and complete the test using array_regex below - // + // // // 1* // let ones_regex: Star, 5> = Star { inner: "1" }; - // + // // let result = ones_regex.match("11000".as_bytes().as_slice()); // println(result); // assert_eq(result, Match { succeeded: true, match_ends: 2, leftover: &[] }); - // + // // let result = ones_regex.match("11".as_bytes().as_slice()); // println(result); // assert_eq(result, Match { succeeded: true, match_ends: 2, leftover: &[] }); - // + // // let result = ones_regex.match("111111".as_bytes().as_slice()); // println(result); // assert_eq(result, Match { succeeded: true, match_ends: 5, leftover: &[] }); - // - // + // + // // // 1+ // let nonempty_ones_regex: Plus, 5, 4> = Plus { inner: "1" }; - // + // // let result = nonempty_ones_regex.match("111111".as_bytes().as_slice()); // println(result); // assert_eq(result, Match { succeeded: true, match_ends: 5, leftover: &[] }); - // + // // // 2^n-1 in binary: 1+0 // let pred_pow_two_regex = (nonempty_ones_regex, "0"); - // + // // let result = pred_pow_two_regex.match("1110".as_bytes().as_slice()); // println(result); // assert_eq(result, Match { succeeded: true, match_ends: 3, leftover: &[] }); @@ -288,7 +308,7 @@ fn main() { // inner: [T; N], // // // elements at indices < offset are zero -// offset: u32, +// offset: u32, // // // elements at indices >= len are zero // len: u32, diff --git a/noir/noir-repo/test_programs/execution_success/slices/src/main.nr b/noir/noir-repo/test_programs/execution_success/slices/src/main.nr index 47272869b04..f1f2580d6c8 100644 --- a/noir/noir-repo/test_programs/execution_success/slices/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/slices/src/main.nr @@ -160,7 +160,11 @@ fn merge_slices_else(x: Field) { fn merge_slices_return(x: Field, y: Field) -> [Field] { let slice = &[0; 2]; if x != y { - if x != 20 { slice.push_back(y) } else { slice } + if x != 20 { + slice.push_back(y) + } else { + slice + } } else { slice } diff --git a/noir/noir-repo/test_programs/execution_success/struct/src/main.nr b/noir/noir-repo/test_programs/execution_success/struct/src/main.nr index de08f42f79d..e4611b90b7d 100644 --- a/noir/noir-repo/test_programs/execution_success/struct/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/struct/src/main.nr @@ -26,7 +26,7 @@ impl Pair { struct Nested { a: Field, - b: Field + b: Field, } struct MyStruct { my_bool: bool, diff --git a/noir/noir-repo/test_programs/execution_success/to_bytes_consistent/src/main.nr b/noir/noir-repo/test_programs/execution_success/to_bytes_consistent/src/main.nr index a51d52da855..171ac9dfbc0 100644 --- a/noir/noir-repo/test_programs/execution_success/to_bytes_consistent/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/to_bytes_consistent/src/main.nr @@ -1,5 +1,5 @@ -// This test aims to check that we have consistent behavior -// between a `to_be_bytes` call (which is radix decomposition under the hood) +// This test aims to check that we have consistent behavior +// between a `to_be_bytes` call (which is radix decomposition under the hood) // with constant inputs or with witness inputs. // x = 2040124 fn main(x: Field) { diff --git a/noir/noir-repo/test_programs/execution_success/trait_as_return_type/src/main.nr b/noir/noir-repo/test_programs/execution_success/trait_as_return_type/src/main.nr index f6828a356c1..905f7f5d8b3 100644 --- a/noir/noir-repo/test_programs/execution_success/trait_as_return_type/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/trait_as_return_type/src/main.nr @@ -5,7 +5,7 @@ trait SomeTrait { struct A {} struct B {} struct C { - x: Field + x: Field, } impl SomeTrait for A { diff --git a/noir/noir-repo/test_programs/execution_success/trait_impl_base_type/src/main.nr b/noir/noir-repo/test_programs/execution_success/trait_impl_base_type/src/main.nr index e12cf019e0b..d12da11bc54 100644 --- a/noir/noir-repo/test_programs/execution_success/trait_impl_base_type/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/trait_impl_base_type/src/main.nr @@ -18,13 +18,21 @@ impl Fieldable for [u32; 3] { impl Fieldable for bool { fn to_field(self) -> Field { - if self { 14 } else { 3 } + if self { + 14 + } else { + 3 + } } } impl Fieldable for (u32, bool) { fn to_field(self) -> Field { - if self.1 { self.0 as Field } else { 32 } + if self.1 { + self.0 as Field + } else { + 32 + } } } diff --git a/noir/noir-repo/test_programs/execution_success/u128/src/main.nr b/noir/noir-repo/test_programs/execution_success/u128/src/main.nr index d0835ccf30f..4ea93437814 100644 --- a/noir/noir-repo/test_programs/execution_success/u128/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/u128/src/main.nr @@ -22,7 +22,7 @@ fn main(mut x: u32, y: u32, z: u32, big_int: U128, hexa: str<7>) { assert( (U128::from_hex("0x71f03a23783f9d9c7a8777") * U128::from_hex("0x8BFCF39041")).hi - == U128::from_hex("0x3e4e0471b873470e247c824e61445537").hi + == U128::from_hex("0x3e4e0471b873470e247c824e61445537").hi, ); let q = U128::from_hex("0x3e4e0471b873470e247c824e61445537") / U128::from_hex("0x8BFCF39041"); assert(q == U128::from_hex("0x71f03a23783f9d9c7a8777")); diff --git a/noir/noir-repo/test_programs/execution_success/uhashmap/src/main.nr b/noir/noir-repo/test_programs/execution_success/uhashmap/src/main.nr index f2ca6813713..e917a83c5fd 100644 --- a/noir/noir-repo/test_programs/execution_success/uhashmap/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/uhashmap/src/main.nr @@ -6,9 +6,9 @@ type K = Field; type V = Field; // It is more convenient and readable to use structs as input. -struct Entry{ +struct Entry { key: Field, - value: Field + value: Field, } global HASHMAP_LEN = 6; @@ -19,8 +19,8 @@ global K_CMP = FIELD_CMP; global V_CMP = FIELD_CMP; global KV_CMP = |a: (K, V), b: (K, V)| a.0.lt(b.0); -global ALLOCATE_HASHMAP = || -> UHashMap> - UHashMap::default(); +global ALLOCATE_HASHMAP = + || -> UHashMap> UHashMap::default(); unconstrained fn main(input: [Entry; HASHMAP_LEN]) { test_sequential(input[0].key, input[0].value); @@ -49,7 +49,10 @@ unconstrained fn test_sequential(key: K, value: V) { assert(value == got, f"Inserted {value} but got {got} for the same key."); hashmap.remove(key); - assert(hashmap.is_empty(), "UHashMap after one insert and corresponding removal should be empty."); + assert( + hashmap.is_empty(), + "UHashMap after one insert and corresponding removal should be empty.", + ); let got = hashmap.get(key); assert(got.is_none(), "Value has been removed, but is still available (not none)."); } @@ -120,11 +123,14 @@ unconstrained fn test_retain() { let (key, value) = (11, 5); hashmap.insert(key, value); - let predicate = |key: K, value: V| -> bool {key * value == 55}; + let predicate = |key: K, value: V| -> bool { key * value == 55 }; hashmap.retain(predicate); assert(hashmap.len() == 2, "UHashMap should have retained 2 elements."); - assert(hashmap.get(2).is_none(), "Pair should have been removed, since it does not match predicate."); + assert( + hashmap.get(2).is_none(), + "Pair should have been removed, since it does not match predicate.", + ); } // Equality trait check. @@ -169,10 +175,10 @@ unconstrained fn test_mut_iterators() { hashmap.insert(5, 7); hashmap.insert(11, 13); - let f = |k: K| -> K{ k * 3}; + let f = |k: K| -> K { k * 3 }; hashmap.iter_keys_mut(f); - let f = |v: V| -> V{ v * 5}; + let f = |v: V| -> V { v * 5 }; hashmap.iter_values_mut(f); let keys: [K; 3] = hashmap.keys().as_array().sort_via(K_CMP); @@ -181,7 +187,7 @@ unconstrained fn test_mut_iterators() { assert(keys == [6, 15, 33], f"Got incorrect iteration of keys: {keys}"); assert(values == [15, 35, 65], "Got incorrect iteration of values."); - let f = |k: K, v: V| -> (K, V){(k * 2, v * 2)}; + let f = |k: K, v: V| -> (K, V) { (k * 2, v * 2) }; hashmap.iter_mut(f); let entries: [(K, V); 3] = hashmap.entries().as_array().sort_via(KV_CMP); @@ -199,19 +205,17 @@ unconstrained fn doc_tests() { let hashmap: UHashMap> = UHashMap::default(); assert(hashmap.is_empty()); // docs:end:default_example - // docs:start:with_hasher_example let my_hasher: BuildHasherDefault = Default::default(); - let hashmap: UHashMap> = UHashMap::with_hasher(my_hasher); + let hashmap: UHashMap> = + UHashMap::with_hasher(my_hasher); assert(hashmap.is_empty()); // docs:end:with_hasher_example - // docs:start:insert_example let mut map: UHashMap> = UHashMap::default(); map.insert(12, 42); assert(map.len() == 1); // docs:end:insert_example - get_example(map); // docs:start:remove_example @@ -222,7 +226,6 @@ unconstrained fn doc_tests() { map.remove(12); assert(map.is_empty()); // docs:end:remove_example - // docs:start:is_empty_example assert(map.is_empty()); @@ -232,7 +235,6 @@ unconstrained fn doc_tests() { map.remove(1); assert(map.is_empty()); // docs:end:is_empty_example - // docs:start:len_example // This is equivalent to checking map.is_empty() assert(map.len() == 0); @@ -249,19 +251,17 @@ unconstrained fn doc_tests() { map.remove(1); assert(map.len() == 2); // docs:end:len_example - // docs:start:capacity_example - let empty_map: UHashMap> = UHashMap::default(); + let empty_map: UHashMap> = + UHashMap::default(); assert(empty_map.len() == 0); println(empty_map.capacity()); // docs:end:capacity_example - // docs:start:clear_example assert(!map.is_empty()); map.clear(); assert(map.is_empty()); // docs:end:clear_example - // docs:start:contains_key_example if map.contains_key(7) { let value = map.get(7); @@ -270,14 +270,12 @@ unconstrained fn doc_tests() { println("No value for key 7!"); } // docs:end:contains_key_example - entries_examples(map); iter_examples(map); // docs:start:retain_example map.retain(|k, v| (k != 0) & (v != 0)); // docs:end:retain_example - // docs:start:eq_example let mut map1: UHashMap> = UHashMap::default(); let mut map2: UHashMap> = UHashMap::default(); @@ -294,9 +292,7 @@ unconstrained fn doc_tests() { // docs:start:get_example fn get_example(map: UHashMap>) { - let x = unsafe { - map.get(12) - }; + let x = unsafe { map.get(12) }; if x.is_some() { assert(x.unwrap() == 42); @@ -317,18 +313,14 @@ fn entries_examples(map: UHashMap {value}"); } // docs:end:keys_example - // docs:start:values_example let values = map.values(); @@ -338,17 +330,17 @@ fn entries_examples(map: UHashMap>) { +unconstrained fn iter_examples( + mut map: UHashMap>, +) { // docs:start:iter_mut_example // Add 1 to each key in the map, and double the value associated with that key. map.iter_mut(|k, v| (k + 1, v * 2)); // docs:end:iter_mut_example - // docs:start:iter_keys_mut_example // Double each key, leaving the value associated with that key untouched map.iter_keys_mut(|k| k * 2); // docs:end:iter_keys_mut_example - // docs:start:iter_values_mut_example // Halve each value map.iter_values_mut(|v| v / 2); diff --git a/noir/noir-repo/test_programs/execution_success/unary_operator_overloading/src/main.nr b/noir/noir-repo/test_programs/execution_success/unary_operator_overloading/src/main.nr index 20cdac51434..bf931d8dafb 100644 --- a/noir/noir-repo/test_programs/execution_success/unary_operator_overloading/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/unary_operator_overloading/src/main.nr @@ -14,7 +14,7 @@ fn main(x: u32) { } struct Wrapper { - inner: i32 + inner: i32, } impl Wrapper { diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr index 152b2dafef8..6e96b459b0b 100644 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr @@ -1,7 +1,6 @@ - // This circuit aggregates a single Honk proof from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 463; -global HONK_IDENTIFIER : u32 = 1; +global SIZE_OF_PROOF_IF_LOGN_IS_28: u32 = 463; +global HONK_IDENTIFIER: u32 = 1; fn main( verification_key: [Field; 128], // This is the proof without public inputs attached. @@ -10,13 +9,13 @@ fn main( public_inputs: pub [Field; 1], // This is currently not public. It is fine given that the vk is a part of the circuit definition. // I believe we want to eventually make it public too though. - key_hash: Field + key_hash: Field, ) { std::verify_proof_with_type( verification_key, proof, public_inputs, key_hash, - HONK_IDENTIFIER + HONK_IDENTIFIER, ); } diff --git a/noir/noir-repo/test_programs/execution_success/wildcard_type/src/main.nr b/noir/noir-repo/test_programs/execution_success/wildcard_type/src/main.nr index c27f9987c48..2227dfbf3c7 100644 --- a/noir/noir-repo/test_programs/execution_success/wildcard_type/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/wildcard_type/src/main.nr @@ -18,6 +18,6 @@ fn foo(x: Field) -> [bar; 4] { bar { enable: [true, true, false, false], data: [x, x + 1], pad: 0 }, bar { enable: [true, false, false, false], data: [x + 2, x + 7], pad: 0 }, bar { enable: [true, true, false, true], data: [x + 3, x + 5], pad: 0 }, - bar { enable: [false, false, false, false], data: [x + 4, x - 1], pad: 0 } + bar { enable: [false, false, false, false], data: [x + 4, x - 1], pad: 0 }, ] } diff --git a/noir/noir-repo/tooling/nargo_cli/benches/criterion.rs b/noir/noir-repo/tooling/nargo_cli/benches/criterion.rs index 949f7add393..488cbfcd243 100644 --- a/noir/noir-repo/tooling/nargo_cli/benches/criterion.rs +++ b/noir/noir-repo/tooling/nargo_cli/benches/criterion.rs @@ -18,11 +18,15 @@ use std::{process::Command, time::Duration}; include!("./utils.rs"); /// Compile the test program in a sub-process -fn compile_program(test_program_dir: &Path) { +/// The `force_brillig` option is used to benchmark the program as if it was executed by the AVM. +fn compile_program(test_program_dir: &Path, force_brillig: bool) { let mut cmd = Command::cargo_bin("nargo").unwrap(); cmd.arg("--program-dir").arg(test_program_dir); cmd.arg("compile"); cmd.arg("--force"); + if force_brillig { + cmd.arg("--force-brillig"); + } cmd.assert().success(); } @@ -100,53 +104,63 @@ fn read_inputs_from_file( /// Use the nargo CLI to compile a test program, then benchmark its execution /// by executing the command directly from the benchmark, so that we can have /// meaningful flamegraphs about the ACVM. +fn criterion_test_execution(c: &mut Criterion, test_program_dir: &Path, force_brillig: bool) { + let benchmark_name = format!( + "{}_execute{}", + test_program_dir.file_name().unwrap().to_str().unwrap(), + if force_brillig { "_brillig" } else { "" } + ); + + // The program and its inputs will be populated in the first setup. + let artifacts = RefCell::new(None); + + let mut foreign_call_executor = + nargo::ops::DefaultForeignCallExecutor::new(false, None, None, None); + + c.bench_function(&benchmark_name, |b| { + b.iter_batched( + || { + // Setup will be called many times to set a batch (which we don't use), + // but we can compile it only once, and then the executions will not have to do so. + // It is done as a setup so that we only compile the test programs that we filter for. + if artifacts.borrow().is_some() { + return; + } + compile_program(test_program_dir, force_brillig); + // Parse the artifacts for use in the benchmark routine + let programs = read_compiled_programs_and_inputs(test_program_dir); + // Warn, but don't stop, if we haven't found any binary packages. + if programs.is_empty() { + eprintln!("\nWARNING: There is nothing to benchmark in {benchmark_name}"); + } + // Store them for execution + artifacts.replace(Some(programs)); + }, + |_| { + let artifacts = artifacts.borrow(); + let artifacts = artifacts.as_ref().expect("setup compiled them"); + + for (program, initial_witness) in artifacts { + let _witness_stack = black_box(nargo::ops::execute_program( + black_box(&program.program), + black_box(initial_witness.clone()), + &bn254_blackbox_solver::Bn254BlackBoxSolver, + &mut foreign_call_executor, + )) + .expect("failed to execute program"); + } + }, + criterion::BatchSize::SmallInput, + ); + }); +} + +/// Go through all the selected tests and executem with and without Brillig. fn criterion_selected_tests_execution(c: &mut Criterion) { for test_program_dir in get_selected_tests() { - let benchmark_name = - format!("{}_execute", test_program_dir.file_name().unwrap().to_str().unwrap()); - - // The program and its inputs will be populated in the first setup. - let artifacts = RefCell::new(None); - - let mut foreign_call_executor = - nargo::ops::DefaultForeignCallExecutor::new(false, None, None, None); - - c.bench_function(&benchmark_name, |b| { - b.iter_batched( - || { - // Setup will be called many times to set a batch (which we don't use), - // but we can compile it only once, and then the executions will not have to do so. - // It is done as a setup so that we only compile the test programs that we filter for. - if artifacts.borrow().is_some() { - return; - } - compile_program(&test_program_dir); - // Parse the artifacts for use in the benchmark routine - let programs = read_compiled_programs_and_inputs(&test_program_dir); - // Warn, but don't stop, if we haven't found any binary packages. - if programs.is_empty() { - eprintln!("\nWARNING: There is nothing to benchmark in {benchmark_name}"); - } - // Store them for execution - artifacts.replace(Some(programs)); - }, - |_| { - let artifacts = artifacts.borrow(); - let artifacts = artifacts.as_ref().expect("setup compiled them"); - - for (program, initial_witness) in artifacts { - let _witness_stack = black_box(nargo::ops::execute_program( - black_box(&program.program), - black_box(initial_witness.clone()), - &bn254_blackbox_solver::Bn254BlackBoxSolver, - &mut foreign_call_executor, - )) - .expect("failed to execute program"); - } - }, - criterion::BatchSize::SmallInput, - ); - }); + for force_brillig in [false, true] { + criterion_test_execution(c, &test_program_dir, force_brillig); + } } } diff --git a/noir/noir-repo/tooling/nargo_cli/tests/stdlib-props.rs b/noir/noir-repo/tooling/nargo_cli/tests/stdlib-props.rs index 9e1a2823e70..0013a90b4ff 100644 --- a/noir/noir-repo/tooling/nargo_cli/tests/stdlib-props.rs +++ b/noir/noir-repo/tooling/nargo_cli/tests/stdlib-props.rs @@ -77,7 +77,7 @@ fn run_snippet_proptest( ) { let program = match prepare_and_compile_snippet(source.clone(), force_brillig) { Ok((program, _)) => program, - Err(e) => panic!("failed to compile program:\n{source}\n{e:?}"), + Err(e) => panic!("failed to compile program; brillig = {force_brillig}:\n{source}\n{e:?}"), }; let blackbox_solver = bn254_blackbox_solver::Bn254BlackBoxSolver; diff --git a/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs b/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs index 847250c1dc0..d27a2961a62 100644 --- a/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs +++ b/noir/noir-repo/tooling/nargo_cli/tests/stdlib-tests.rs @@ -1,9 +1,10 @@ -use std::io::Write; -use std::{collections::BTreeMap, path::PathBuf}; - +//! Execute unit tests in the Noir standard library. +use clap::Parser; use fm::FileManager; use noirc_driver::{check_crate, file_manager_with_stdlib, CompileOptions}; use noirc_frontend::hir::FunctionNameMatch; +use std::io::Write; +use std::{collections::BTreeMap, path::PathBuf}; use nargo::{ ops::{report_errors, run_test, TestStatus}, @@ -12,8 +13,32 @@ use nargo::{ }; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; +#[derive(Parser, Debug)] +#[command(ignore_errors = true)] +pub struct Options { + /// Test name to filter for. + /// + /// First is assumed to be `run_stdlib_tests` and the second the of the stdlib tests, e.g.: + /// + /// ```text + /// cargo test -p nargo_cli --test stdlib-tests -- run_stdlib_tests sha256 + /// ``` + args: Vec, +} + +impl Options { + pub fn function_name_match(&self) -> FunctionNameMatch { + match self.args.as_slice() { + [_, lib] => FunctionNameMatch::Contains(lib.as_str()), + _ => FunctionNameMatch::Anything, + } + } +} + #[test] fn run_stdlib_tests() { + let opts = Options::parse(); + let mut file_manager = file_manager_with_stdlib(&PathBuf::from(".")); file_manager.add_file_with_source_canonical_path(&PathBuf::from("main.nr"), "".to_owned()); let parsed_files = parse_all(&file_manager); @@ -41,7 +66,7 @@ fn run_stdlib_tests() { let test_functions = context.get_all_test_functions_in_crate_matching( context.stdlib_crate_id(), - FunctionNameMatch::Anything, + opts.function_name_match(), ); let test_report: Vec<(String, TestStatus)> = test_functions diff --git a/noir/noir-repo/tooling/nargo_fmt/Cargo.toml b/noir/noir-repo/tooling/nargo_fmt/Cargo.toml index 1e4d93b3125..710519712a2 100644 --- a/noir/noir-repo/tooling/nargo_fmt/Cargo.toml +++ b/noir/noir-repo/tooling/nargo_fmt/Cargo.toml @@ -10,8 +10,6 @@ license.workspace = true workspace = true [dependencies] -bytecount = "0.6.3" -noirc_errors.workspace = true noirc_frontend.workspace = true serde.workspace = true toml.workspace = true diff --git a/noir/noir-repo/tooling/nargo_fmt/build.rs b/noir/noir-repo/tooling/nargo_fmt/build.rs index 4051597c088..47bb375f7d1 100644 --- a/noir/noir-repo/tooling/nargo_fmt/build.rs +++ b/noir/noir-repo/tooling/nargo_fmt/build.rs @@ -49,13 +49,6 @@ fn generate_formatter_tests(test_file: &mut File, test_data_dir: &Path) { let output_source_path = outputs_dir.join(file_name).display().to_string(); let output_source = std::fs::read_to_string(output_source_path.clone()).unwrap(); - let skip_idempotent_test = - // TODO(https://github.com/noir-lang/noir/issues/4766): spurious trailing space - test_name == "array" || - // TODO(https://github.com/noir-lang/noir/issues/4767): pre-comment space - // TODO(https://github.com/noir-lang/noir/issues/4768): spurious newline - test_name == "tuple"; - write!( test_file, r##" @@ -80,10 +73,9 @@ fn generate_formatter_tests(test_file: &mut File, test_data_dir: &Path) { ) .expect("Could not write templated test file."); - if !skip_idempotent_test { - write!( - test_file, - r##" + write!( + test_file, + r##" #[test] fn format_idempotent_{test_name}() {{ let expected_output = r#"{output_source}"#; @@ -96,8 +88,7 @@ fn generate_formatter_tests(test_file: &mut File, test_data_dir: &Path) { similar_asserts::assert_eq!(fmt_text, expected_output); }} "## - ) - .expect("Could not write templated test file."); - } + ) + .expect("Could not write templated test file."); } } diff --git a/noir/noir-repo/tooling/nargo_fmt/src/chunks.rs b/noir/noir-repo/tooling/nargo_fmt/src/chunks.rs new file mode 100644 index 00000000000..073e03ea74a --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/chunks.rs @@ -0,0 +1,973 @@ +//! This module has all the logic to format a series of chunks (a piece of text) in a way +//! that we (almost always) never exceed the configurable maximum line width. +//! +//! It's heavily inspired by this excellent blog post: +//! +//! https://yorickpeterse.com/articles/how-to-write-a-code-formatter/ +//! +//! However, some changes were introduces to handle comments and other particularities of Noir. +use std::ops::Deref; + +use noirc_frontend::token::Token; + +use super::Formatter; + +/// A text chunk. It precomputes the text width and whether it has newlines. +#[derive(Debug)] +pub(crate) struct TextChunk { + pub(crate) string: String, + pub(crate) width: usize, + pub(crate) has_newlines: bool, +} + +impl TextChunk { + pub(crate) fn new(string: String) -> Self { + TextChunk { + width: string.chars().count(), + has_newlines: string.chars().any(|char| char == '\n'), + string, + } + } +} + +/// A chunk can either be text or a directive that instructs the formatter to do something +/// (for example: increase or decrease the current indentation). +#[derive(Debug)] +pub(crate) enum Chunk { + /// A text chunk. It might contain leading comments. + Text(TextChunk), + /// A text chunk that should be printed unmodified (used for `quote { ... }` contents). + Verbatim(TextChunk), + /// A trailing comma that's only written if we decide to format chunks in multiple lines + /// (for example for a call we'll add a trailing comma to the last argument). + TrailingComma, + /// A trailing comment (happens at the end of a line, and always after something else have been written). + TrailingComment(TextChunk), + /// A leading comment. Happens at the beginning of a line. + LeadingComment(TextChunk), + /// A group of chunks. + Group(ChunkGroup), + /// Write a line (or two) if we decide to format chunks in multiple lines, otherwise do nothing. + Line { two: bool }, + /// Writes a space if we can write a group in one line, otherwise writes a line. + /// However, a space might be written if `one_chunk_per_line` of a Chunks object is set to false. + SpaceOrLine, + /// Command to increase the current indentation. + IncreaseIndentation, + /// Command to decrease the current indentation. + DecreaseIndentation, + /// Push the current indentation to the indentation stack. + PushIndentation, + /// Set the current indentation by popping it from the indentation stack. + PopIndentation, +} + +impl Chunk { + pub(crate) fn width(&self) -> usize { + match self { + Chunk::Text(chunk) + | Chunk::Verbatim(chunk) + | Chunk::TrailingComment(chunk) + | Chunk::LeadingComment(chunk) => chunk.width, + Chunk::Group(group) => group.width(), + Chunk::SpaceOrLine => 1, + Chunk::Line { .. } + | Chunk::IncreaseIndentation + | Chunk::DecreaseIndentation + | Chunk::TrailingComma + | Chunk::PushIndentation + | Chunk::PopIndentation => 0, + } + } + + /// Computes the width of this chunk considering it's inside an ExpressionList. + /// The only thing that changes here compared to `width` is that a LambdaAsLastExpressionInList's + /// width is considered to be only the first line, so we can avoid splitting the entire call + /// arguments into separate lines. + pub(crate) fn width_inside_an_expression_list(&self) -> usize { + if let Chunk::Group(group) = &self { + if let GroupKind::LambdaAsLastExpressionInList { first_line_width, .. } = &group.kind { + return *first_line_width; + } + } + + self.width() + } + + pub(crate) fn has_newlines(&self) -> bool { + match self { + Chunk::Text(chunk) + | Chunk::Verbatim(chunk) + | Chunk::TrailingComment(chunk) + | Chunk::LeadingComment(chunk) => chunk.has_newlines, + Chunk::Group(group) => group.has_newlines(), + Chunk::TrailingComma + | Chunk::Line { .. } + | Chunk::SpaceOrLine + | Chunk::IncreaseIndentation + | Chunk::DecreaseIndentation + | Chunk::PushIndentation + | Chunk::PopIndentation => false, + } + } + + /// Returns the current chunk as a Group, if it is one. Otherwise returns None. + pub(crate) fn group(self) -> Option { + if let Chunk::Group(group) = self { + Some(group) + } else { + None + } + } +} + +#[derive(Debug)] +pub(crate) struct ChunkGroup { + pub(crate) chunks: Vec, + + /// If `true`, when formatting in multiple lines, and after a SpaceOrLine, + /// a line will be written. + /// If `false`, when formatting in multiple lines, and after a SpaceOrLine, + /// a space will be inserted and the next chunk will go in the same line if + /// it fits that line. + /// + /// This is used to, for example, control how arrays are formatted. If each + /// element is short, we'll format the array like this: + /// + /// [ + /// 1, 2, 3, + /// 4, 5 + /// ] + /// + /// but if one of the elements is long, each one will go in a separate line: + /// + /// ```text + /// [ + /// 1, + /// 1234567890123, + /// 3 + /// ] + /// ``` + pub(crate) one_chunk_per_line: bool, + + /// If true, regardless of this group's chunks, this group will be formatted in + /// multiple lines. + /// This is set to true when, for example, we format a block that has at least + /// two statements: we always want to show that in multiple lines. + pub(crate) force_multiple_lines: bool, + + /// Groups can be tagged. For example we tag all consequences and alternative blocks + /// of an `if` expression. If we determine one of them needs to be formatted in multiple + /// lines, we find all other chunks with the same tag and mark them too to be formatted + /// in multiple lines. + pub(crate) tag: Option, + + /// The kind of this group. Some group kinds are formatted in a special way + /// (mainly lambda arguments that are the last expression in a list). + pub(crate) kind: GroupKind, + + /// This name is a bit long and explicit, but it's to make things clearer: + /// if we determine that this group needs to be formatted in multiple lines, + /// children groups with the same tag will also be formatted in multiple lines. + /// + /// This is used for example in infix expressions like `a + b + c + d`, where if we + /// determine that `a + b` needs to be formatted in multiple lines, we want the entire + /// tree (of those infix expressions) to be formatted in multiple lines. + pub(crate) force_multiline_on_children_with_same_tag_if_multiline: bool, +} + +impl ChunkGroup { + pub(crate) fn new() -> Self { + Self { + chunks: Vec::new(), + one_chunk_per_line: true, + force_multiple_lines: false, + tag: None, + kind: GroupKind::Regular, + force_multiline_on_children_with_same_tag_if_multiline: false, + } + } + + /// Appends a text to this group. + /// If the last chunk in this group is a text, no new chunk is inserted and + /// instead the last text chunk is extended. + pub(crate) fn text(&mut self, chunk: TextChunk) { + if chunk.width == 0 { + return; + } + + if let Some(Chunk::Text(text_chunk)) = self.chunks.last_mut() { + text_chunk.string.push_str(&chunk.string); + text_chunk.width += chunk.width; + text_chunk.has_newlines |= chunk.has_newlines; + } else { + self.push(Chunk::Text(chunk)); + } + } + + /// Appends a verbatim text chunk to this group. + pub(crate) fn verbatim(&mut self, chunk: TextChunk) { + if chunk.width == 0 { + return; + } + + self.push(Chunk::Verbatim(chunk)); + } + + /// Appends a single space to this group by reading it from the given formatter. + pub(crate) fn space(&mut self, formatter: &mut ChunkFormatter<'_, '_>) { + self.text(formatter.chunk(|formatter| { + formatter.write_space(); + })); + } + + /// Appends a semicolon to this group by reading it from the given formatter. + /// This will actually end up attaching the semicolon to the last text in this + /// group so that we don't end up with stray semicolons. + pub(crate) fn semicolon(&mut self, formatter: &mut ChunkFormatter<'_, '_>) { + self.text_attached_to_last_group(formatter.chunk(|formatter| { + formatter.write_semicolon(); + })); + } + + /// Appends a TextChunk to this chunks chunks. However, if the last chunk is a group, + /// it's appended to that group's last text. + pub(crate) fn text_attached_to_last_group(&mut self, chunk: TextChunk) { + if chunk.width == 0 { + return; + } + + if let Some(Chunk::Group(group)) = self.chunks.last_mut() { + group.text(chunk); + } else { + self.text(chunk); + } + } + + /// Appends a trailing comment (it's formatted slightly differently than a regular text chunk). + pub(crate) fn trailing_comment(&mut self, chunk: TextChunk) { + if chunk.width > 0 { + self.push(Chunk::TrailingComment(chunk)); + } + } + + /// Appends a leading comment (it's formatted slightly differently than a regular text chunk). + pub(crate) fn leading_comment(&mut self, chunk: TextChunk) { + if chunk.width > 0 { + self.push(Chunk::LeadingComment(chunk)); + } + } + + /// Appends a trailing comma (will only show up if the group is formatted in multiple lines). + pub(crate) fn trailing_comma(&mut self) { + self.push(Chunk::TrailingComma); + } + + /// Appends another group as a nested group. + pub(crate) fn group(&mut self, group: ChunkGroup) { + self.push(Chunk::Group(group)); + } + + /// Append one line to this chunk. + pub(crate) fn line(&mut self) { + self.lines(false); + } + + /// Append one or two lines to this chunk. + pub(crate) fn lines(&mut self, two: bool) { + self.push(Chunk::Line { two }); + } + + /// Appends a SpaceOrLine chunk, which means that it's a space when this group is + /// formatted in a single line, or a line when it's formatted in multiple lines. + pub(crate) fn space_or_line(&mut self) { + self.push(Chunk::SpaceOrLine); + } + + pub(crate) fn increase_indentation(&mut self) { + self.push(Chunk::IncreaseIndentation); + } + + pub(crate) fn decrease_indentation(&mut self) { + self.push(Chunk::DecreaseIndentation); + } + + pub(crate) fn push_indentation(&mut self) { + self.push(Chunk::PushIndentation); + } + + pub(crate) fn pop_indentation(&mut self) { + self.push(Chunk::PopIndentation); + } + + pub(crate) fn push(&mut self, chunk: Chunk) { + self.chunks.push(chunk); + } + + pub(crate) fn width(&self) -> usize { + self.chunks.iter().map(|chunk| chunk.width()).sum() + } + + pub(crate) fn expression_list_width(&self) -> usize { + self.chunks.iter().map(|chunk| chunk.width_inside_an_expression_list()).sum() + } + + pub(crate) fn has_newlines(&self) -> bool { + self.force_multiple_lines || self.chunks.iter().any(|chunk| chunk.has_newlines()) + } + + /// Determines if this group has a LambdaAsLastExpressionInList chunk. + /// Note that if this group is a MethodCall, this is checked for the ExpressionList group + /// inside it. + pub(crate) fn has_lambda_as_last_expression_in_list(&self) -> bool { + self.chunks.iter().any(|chunk| { + if let Chunk::Group(group) = chunk { + if self.kind.is_method_call() && group.kind.is_expression_list() { + group.has_lambda_as_last_expression_in_list() + } else { + matches!(group.kind, GroupKind::LambdaAsLastExpressionInList { .. }) + } + } else { + false + } + }) + } + + /// Finds the `LambdaAsLastExpressionInList` associated to this group and sets its indentation + /// to the given value. + pub(crate) fn set_lambda_as_last_expression_in_list_indentation( + &mut self, + indentation_to_set: i32, + ) { + for chunk in self.chunks.iter_mut() { + if let Chunk::Group(group) = chunk { + if self.kind.is_method_call() && group.kind.is_expression_list() { + group.set_lambda_as_last_expression_in_list_indentation(indentation_to_set); + } else if let GroupKind::LambdaAsLastExpressionInList { indentation, .. } = + &mut group.kind + { + if indentation.is_none() { + *indentation = Some(indentation_to_set); + } + } + } + } + } + + /// Before writing a Chunks object in multiple lines, create a new one where `TrailingComma` + /// is turned into `Text`. Because Chunks will glue two consecutive `Text`s together, if we + /// have two chunks `Text("123"), TrailingComma`, we'll consider the entire string "123," + /// when deciding whether we can still write in the current line or not. + pub(crate) fn prepare_for_multiple_lines(self) -> ChunkGroup { + let mut group = ChunkGroup { chunks: Vec::new(), ..self }; + + for chunk in self.chunks { + match chunk { + Chunk::Text(chunk) => group.text(chunk), + Chunk::Verbatim(chunk) => group.verbatim(chunk), + Chunk::TrailingComma => { + // If there's a trailing comma after a group, append the text to that group + // so that it glues with the last text present there (if any) + group.add_trailing_comma_to_last_text(); + } + Chunk::TrailingComment(chunk) => group.trailing_comment(chunk), + Chunk::LeadingComment(chunk) => group.leading_comment(chunk), + Chunk::Group(inner_group) => group.group(inner_group), + Chunk::Line { two } => group.lines(two), + Chunk::SpaceOrLine => group.space_or_line(), + Chunk::IncreaseIndentation => group.increase_indentation(), + Chunk::DecreaseIndentation => group.decrease_indentation(), + Chunk::PushIndentation => group.push_indentation(), + Chunk::PopIndentation => group.pop_indentation(), + } + } + group + } + + fn add_trailing_comma_to_last_text(&mut self) { + if let Some(Chunk::Group(group)) = self.chunks.last_mut() { + group.add_trailing_comma_to_last_text(); + } else { + self.text(TextChunk::new(",".to_string())); + } + } + + /// Returns the width of text until we hit a Line or LineOrSpace, together + /// with whether we hit a Line or LineOrSpace. + fn width_until_line(&self) -> (usize, bool) { + let mut width = 0; + for chunk in &self.chunks { + match chunk { + Chunk::Text(text_chunk) + | Chunk::Verbatim(text_chunk) + | Chunk::TrailingComment(text_chunk) + | Chunk::LeadingComment(text_chunk) => { + width += text_chunk.width; + } + Chunk::Group(chunk_group) => { + let (group_width, hit_line) = chunk_group.width_until_line(); + width += group_width; + if hit_line { + return (width, true); + } + } + Chunk::Line { .. } | Chunk::SpaceOrLine => { + return (width, true); + } + Chunk::IncreaseIndentation + | Chunk::DecreaseIndentation + | Chunk::PushIndentation + | Chunk::PopIndentation + | Chunk::TrailingComma => (), + } + } + + (width, false) + } + + fn first_group(&self) -> Option<&ChunkGroup> { + self.chunks + .iter() + .filter_map(|chunk| if let Chunk::Group(group) = chunk { Some(group) } else { None }) + .next() + } + + fn has_expression_list_or_method_call_group(&self) -> bool { + for chunk in &self.chunks { + if let Chunk::Group(group) = chunk { + if group.kind.is_expression_list() || group.kind.is_method_call() { + return true; + } + } + } + + false + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) struct GroupTag(usize); + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum GroupKind { + /// Most chunks are regular chunks and are not of interest. + Regular, + /// This is a chunk that has a list of expression in it, for example: + /// a call, a method call, an array literal, a tuple literal, etc. + /// `prefix_width` is the width of whatever is before the actual expression list. + /// For example, for an array this is 1 (for "["), for a slice it's 2 ("&["), etc. + ExpressionList { prefix_width: usize, expressions_count: usize }, + /// This is a chunk for a lambda argument that is the last expression of an ExpressionList. + /// `first_line_width` is the width of the first line of the lambda argument: the parameters + /// list and the left bracket. + LambdaAsLastExpressionInList { first_line_width: usize, indentation: Option }, + /// The body of a lambda. + /// We track this as a group kind so that when we have to write it, if it doesn't + /// fit in the current line and it's not a block, instead of splitting that expression + /// somewhere that's probably undesired, we'll "turn it" into a block + /// (write the "{" and "}" delimiters) and write the lambda body in the next line. + LambdaBody { is_block: bool }, + /// A method call. + /// We track all this information to see, if we end up needing to format this call + /// in multiple lines, if we can write everything up to the left parentheses (inclusive) + /// in one line, and just the call arguments in multiple lines. + MethodCall { + /// This is the width of the group until the left parenthesis (inclusive). + width_until_left_paren_inclusive: usize, + /// Are there newlines before the left parentheses in this group? + has_newlines_before_left_paren: bool, + /// Is this method call the left-hand side of a call chain? If so, this is true, + /// otherwise this is false an it means it's the outermost call. + lhs: bool, + }, + /// The value of an assignment or let statement. We know this is the last group in a chunk so + /// if it doesn't fit in the current line but it fits in the next line, we can + /// write a newline, indent, and put it there (instead of writing the value in + /// multiple lines). + AssignValue, +} + +impl GroupKind { + fn is_method_call(&self) -> bool { + matches!(self, GroupKind::MethodCall { .. }) + } + + fn is_expression_list(&self) -> bool { + matches!(self, GroupKind::ExpressionList { .. }) + } +} + +/// Interface for creating TextChunks. +pub(crate) struct ChunkFormatter<'a, 'b>(&'b mut Formatter<'a>); + +impl<'a, 'b> ChunkFormatter<'a, 'b> { + pub(crate) fn new(formatter: &'b mut Formatter<'a>) -> Self { + Self(formatter) + } + + /// Stops writing to the current buffer for the duration of the `f` call, which takes + /// a formatter to write to. Then, returns a `TextChunk` with the written text. + /// + /// This allows a caller to format pieces of code and then pre-process them before + /// writing to the main buffer. + pub(crate) fn chunk(&mut self, f: impl FnOnce(&mut Formatter)) -> TextChunk { + let previous_buffer = std::mem::take(&mut self.0.buffer); + let previous_indentation = self.0.indentation; + self.0.indentation = 0; + + f(self.0); + + self.0.indentation = previous_indentation; + + let buffer = std::mem::replace(&mut self.0.buffer, previous_buffer); + TextChunk::new(buffer.contents()) + } + + /// Stops writing to the current buffer, skips comments and whitespaces (formatting them) + /// and returns the formatted result as a `TextChunk`. + pub(crate) fn skip_comments_and_whitespace_chunk(&mut self) -> TextChunk { + self.chunk(|formatter| { + formatter.skip_comments_and_whitespace(); + }) + } + + pub(super) fn new_group_tag(&mut self) -> GroupTag { + self.0.new_group_tag() + } + + pub(super) fn bump(&mut self) -> Token { + self.0.bump() + } +} + +/// Treating a `ChunkFormatter` as a `Formatter` in read-only mode is always fine, +/// and reduces some boilerplate. +impl<'a, 'b> Deref for ChunkFormatter<'a, 'b> { + type Target = Formatter<'b>; + + fn deref(&self) -> &Self::Target { + self.0 + } +} + +impl<'a> Formatter<'a> { + /// Returns an object that has a `chunk` method to get a TextChunk. + /// This method exists so that we can't mix the two operation modes: + /// using the formatter directly while writing to the buffer, or creating text chunks. + pub(super) fn chunk_formatter(&mut self) -> ChunkFormatter<'a, '_> { + ChunkFormatter::new(self) + } + + /// Main interface to format a chunk group. + /// Here it's determined if the chunk will group in a single line or multiple lines. + pub(super) fn format_chunk_group(&mut self, group: ChunkGroup) { + let previous_indentation = self.indentation; + self.format_chunk_group_impl(group); + self.indentation = previous_indentation; + } + + pub(super) fn format_chunk_group_impl(&mut self, group: ChunkGroup) { + if let GroupKind::LambdaAsLastExpressionInList { indentation: Some(indentation), .. } = + group.kind + { + let previous_indentation = self.indentation; + self.indentation = indentation; + self.format_chunks_group_impl_without_lambda_handling(group); + self.indentation = previous_indentation; + } else { + self.format_chunks_group_impl_without_lambda_handling(group); + } + } + + pub(super) fn format_chunks_group_impl_without_lambda_handling( + &mut self, + mut group: ChunkGroup, + ) { + let chunks_width = group.width(); + let total_width = self.current_line_width() + chunks_width; + + if total_width > self.max_width { + // If this is a method call that doesn't fit in the current line, we check if + // everything that follows up to the left parentheses fits in the current line. + // If so, we write that and we'll end up formatting the arguments in multiple + // lines, instead of splitting this entire call chain in multiple lines. + // + // For example, a call like this: + // + // foo.bar.baz.qux(1) + // + // if it exceeds the maximum width, will end up being formatted like this: + // + // foo.bar.baz.qux( + // 1, + // ) + // + // instead of like this (many more lines): + // + // foo + // .bar + // .baz + // .qux(1) + // + // This is something that rustfmt seems to do too. + if let GroupKind::MethodCall { + width_until_left_paren_inclusive, + has_newlines_before_left_paren: false, + lhs: false, + } = group.kind + { + let total_width = self.current_line_width() + width_until_left_paren_inclusive; + if total_width <= self.max_width { + // Check if this method call has another call or method call nested in it. + // If not, it means tis is the last nested call and after it we'll need to start + // writing at least one closing parentheses. So the argument list will actually + // have one less character available for writing, and that's why we (temporarily) decrease + // max width. + let expression_list_group = group.first_group().unwrap(); + let has_expression_list_or_call_group = + expression_list_group.has_expression_list_or_method_call_group(); + if !has_expression_list_or_call_group { + self.max_width -= 1; + } + + // When a method call's group is formed, we indent after the first dot. But with that + // indentation, and the arguments indentation, we'll end up with too much indentation, + // so here we decrease it to compensate that. + self.decrease_indentation(); + self.format_chunk_group_in_one_line(group); + self.increase_indentation(); + + if !has_expression_list_or_call_group { + self.max_width += 1; + } + return; + } + } + + // If this is an expression list with a single expression, see if we can fit whatever + // comes next until a line in the current line. For example, if we have this: + // + // foo(bar(baz(1))) + // + // then `foo(...)` is an ExpressionList. We check if `foo(` fits in the current line. + // If yes, we write it in the current line and continue. Then we'll find `bar(...)`, + // which is also an ExpressionList, and if `bar(` fits the current line, we'll write it, + // etc. But we only do this if we have nested calls (nested expression lists, etc.) + // + // This is to avoid formatting the above like this: + // + // foo( + // bar( + // baz( + // 1, + // ), + // ), + // ) + // + // (rustfmt seems to do the same thing) + if let GroupKind::ExpressionList { prefix_width, expressions_count: 1 } = group.kind { + if let Some(inner_group) = group.first_group() { + if inner_group.kind.is_expression_list() || inner_group.kind.is_method_call() { + let total_width = self.current_line_width() + + prefix_width + + inner_group.width_until_line().0; + if total_width <= self.max_width { + self.decrease_indentation(); + self.format_chunk_group_in_one_line(group); + self.increase_indentation(); + return; + } + } + } + } + } + + if group.force_multiple_lines { + self.format_chunk_group_in_multiple_lines(group); + return; + } + + // if chunks.has_newlines() { + // When formatting an expression list we have to check if the last argument is a lambda, + // because we format that in a special way: + // 1. to compute the group width we'll consider only the `|...| {` part of the lambda + // 2. If it fits in a line, we'll format this expression list in a single line + // 3. However, an expression list is instructed to increase indentation after, say, + // `(` or `[` (depending on the expression list) and then the `{` part of a lambda + // will also increase the indentation, resulting in too much indentation. + // 4. For that reason we adjust the lambda to be formatted with the indentation + // we have right that (that is, that of the call that holds the lambda). + // We do that by setting the `indentation` field of the LambdaAsLastExpressionInList. + // + // Note that this logic is a bit complex because for method calls, the arguments list + // is in a group so all arguments can potentially be formatted in a single line, and + // that group has the `ExpressionList` kind. The method call itself has the `MethodCall` + // kind. So when determining the first line width of a method call with a lambda as + // the last argument we have to find the nested ExpressionList and do some nested calls. + if (group.kind.is_expression_list() || group.kind.is_method_call()) + && group.has_lambda_as_last_expression_in_list() + { + let chunks_width = group.expression_list_width(); + let total_width = self.current_line_width() + chunks_width; + if total_width <= self.max_width { + group.set_lambda_as_last_expression_in_list_indentation(self.indentation); + self.format_chunk_group_in_one_line(group); + return; + } + } + + if group.has_newlines() { + self.format_chunk_group_in_multiple_lines(group); + return; + } + + // Check if the group first in the remainder of the current line. + if total_width > self.max_width { + // If this chunk is the value of an assignment (either a normal assignment or a let statement) + // and it doesn't fit the current line, we check if it fits the next line with an increased + // indentation. + // + // That way this: + // + // let x = foo(1, 2); + // ^ + // assume the max width is here + // + // is formatted like this: + // + // let x = + // foo(1, 2); + // + // instead of: + // + // let x = foo( + // 1, + // 2, + // ) + if group.kind == GroupKind::AssignValue { + let total_width_next_line = + (self.indentation as usize + 1) * self.config.tab_spaces + chunks_width; + if total_width_next_line <= self.max_width { + // We might have trailing spaces + // (for example a space after the `=` of a let statement or an assignment) + self.trim_spaces(); + self.write_line_without_skipping_whitespace_and_comments(); + self.increase_indentation(); + self.write_indentation(); + self.format_chunk_group_in_one_line(group); + self.decrease_indentation(); + return; + } + } + + // If a lambda body doesn't fit in the current line and it's not a block, + // we can turn it into a block and write it in the next line, so its contents fit. + if let GroupKind::LambdaBody { is_block: false } = group.kind { + // Try to format it again in the next line, but we don't want to recurse + // infinitely so we change the group kind. + group.kind = GroupKind::Regular; + self.write("{"); + self.trim_spaces(); + self.increase_indentation(); + self.write_line(); + self.write_indentation(); + self.format_chunk_group_impl(group); + + // If this lambda was in an expression list and it was formatted in multiple + // lines, it might be that the trailing comma happened after the lambda body: + // + // foo( + // 1, + // |lambda| body, + // ) + // + // Because we attach commas to the last text to avoid splitting it, the body + // in this case is "body,", so if we end up writing it as a block it will + // look like this: + // + // foo( + // 1, + // |lambda| { + // body, + // } + // ) + // + // So, if after writing the body we find a comma (there will be at most one) + // we remove it, but place it after the right brace, so it looks like this: + // + // foo( + // 1, + // |lambda| { + // body + // }, + // ) + let comma_trimmed = self.trim_comma(); + self.decrease_indentation(); + self.write_line(); + self.write_indentation(); + self.write("}"); + if comma_trimmed { + self.write(","); + } + return; + } + + self.format_chunk_group_in_multiple_lines(group); + return; + } + + self.format_chunk_group_in_one_line(group); + } + + pub(super) fn format_chunk_group_in_one_line(&mut self, group: ChunkGroup) { + for chunk in group.chunks { + match chunk { + Chunk::Text(text_chunk) | Chunk::Verbatim(text_chunk) => { + self.write(&text_chunk.string); + } + Chunk::TrailingComment(text_chunk) | Chunk::LeadingComment(text_chunk) => { + self.write(&text_chunk.string); + self.write(" "); + } + Chunk::Group(chunks) => self.format_chunk_group_impl(chunks), + Chunk::SpaceOrLine => self.write(" "), + Chunk::IncreaseIndentation => self.increase_indentation(), + Chunk::DecreaseIndentation => self.decrease_indentation(), + Chunk::PushIndentation => self.push_indentation(), + Chunk::PopIndentation => self.pop_indentation(), + Chunk::TrailingComma | Chunk::Line { .. } => (), + } + } + } + + pub(super) fn format_chunk_group_in_multiple_lines(&mut self, group: ChunkGroup) { + let chunks = group.prepare_for_multiple_lines(); + + let mut last_was_space_or_line = false; + + for chunk in chunks.chunks { + if last_was_space_or_line { + if chunks.one_chunk_per_line { + self.write_line_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } else { + // "+ 1" because we still need to add a space before the next chunk + if self.current_line_width() + chunk.width() + 1 > self.max_width { + self.write_line_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } else { + self.write_space_without_skipping_whitespace_and_comments(); + } + } + } + + last_was_space_or_line = false; + + match chunk { + Chunk::Text(text_chunk) => { + if text_chunk.has_newlines { + self.write_chunk_lines(&text_chunk.string); + } else { + // If we didn't exceed the max width, but this chunk will, insert a newline, + // increase indentation and indent (the indentation will be undone + // after `format_chunks` finishes). + // This is the logic to automatically wrap a line when a ChunkGroup doesn't + // have Line or SpaceOrLine in it. + if self.current_line_width() <= self.max_width + && self.current_line_width() + text_chunk.width > self.max_width + && !self.buffer.ends_with_space() + { + self.write_line_without_skipping_whitespace_and_comments(); + self.increase_indentation(); + self.write_indentation(); + } + self.write(&text_chunk.string); + } + } + Chunk::Verbatim(text_chunk) => { + self.write(&text_chunk.string); + } + Chunk::TrailingComment(text_chunk) => { + self.write_chunk_lines(&text_chunk.string); + self.write_line_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } + Chunk::LeadingComment(text_chunk) => { + self.write_chunk_lines(text_chunk.string.trim()); + self.write_line_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } + Chunk::Group(mut group) => { + if chunks.force_multiline_on_children_with_same_tag_if_multiline + && chunks.tag == group.tag + { + group.force_multiple_lines = true; + group.force_multiline_on_children_with_same_tag_if_multiline = true; + } + + self.format_chunk_group_impl(group); + } + Chunk::Line { two } => { + if two { + self.write_multiple_lines_without_skipping_whitespace_and_comments(); + } else { + self.write_line_without_skipping_whitespace_and_comments(); + } + self.write_indentation(); + } + Chunk::SpaceOrLine => { + last_was_space_or_line = true; + } + Chunk::IncreaseIndentation => { + self.increase_indentation(); + } + Chunk::DecreaseIndentation => { + self.decrease_indentation(); + } + Chunk::PushIndentation => { + self.push_indentation(); + } + Chunk::PopIndentation => { + self.pop_indentation(); + } + Chunk::TrailingComma => { + unreachable!( + "TrailingComma should have been removed by `prepare_for_multiple_lines`" + ) + } + } + } + } + + /// Appends the string to the current buffer line by line, with some pre-checks. + fn write_chunk_lines(&mut self, string: &str) { + for (index, line) in string.lines().enumerate() { + // Don't indent the first line (it should already be indented). + // Also don't indent if the current line already has a space as the last char + // (it means it's already indented) + if index > 0 && !self.buffer.ends_with_space() { + self.write_line_without_skipping_whitespace_and_comments(); + // Only indent if the line doesn't start with a space. When that happens + // it's likely a block comment part that we don't want to modify. + if !line.starts_with(' ') { + self.write_indentation(); + } + } + + // If we already have a space in the buffer and the line starts with a space, + // don't repeat that space. + if self.buffer.ends_with_space() && line.starts_with(' ') { + self.write(line.trim_start()); + } else { + self.write(line); + } + } + } + + /// Returns a new GroupTag that is unique compared to other `new_group_tag` calls. + pub(super) fn new_group_tag(&mut self) -> GroupTag { + let tag = GroupTag(self.group_tag_counter); + self.group_tag_counter += 1; + tag + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/config.rs b/noir/noir-repo/tooling/nargo_fmt/src/config.rs index 5e38dc7d8b0..6a1a019f18d 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/config.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/config.rs @@ -45,7 +45,6 @@ config! { max_width: usize, 100, "Maximum width of each line"; tab_spaces: usize, 4, "Number of spaces per tab"; remove_nested_parens: bool, true, "Remove nested parens"; - error_on_lost_comment: bool, false, "Error if unable to get comments"; short_array_element_width_threshold: usize, 10, "Width threshold for an array element to be considered short"; array_width: usize, 100, "Maximum width of an array literal before falling back to vertical formatting"; fn_call_width: usize, 60, "Maximum width of the args of a function call before falling back to vertical formatting"; diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter.rs new file mode 100644 index 00000000000..558dab2829e --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter.rs @@ -0,0 +1,310 @@ +use buffer::Buffer; +use noirc_frontend::{ + ast::Ident, + hir::resolution::errors::Span, + lexer::Lexer, + token::{Keyword, SpannedToken, Token}, + ParsedModule, +}; + +use crate::Config; + +mod alias; +mod attribute; +mod buffer; +mod comments_and_whitespace; +mod doc_comments; +mod expression; +mod function; +mod generics; +mod global; +mod impls; +mod item; +mod lvalue; +mod module; +mod path; +mod pattern; +mod statement; +mod structs; +mod trait_impl; +mod traits; +mod type_expression; +mod types; +mod use_tree; +mod visibility; +mod where_clause; + +pub(crate) struct Formatter<'a> { + pub(crate) config: &'a Config, + source: &'a str, + lexer: Lexer<'a>, + token: Token, + token_span: Span, + + /// The current indentation level. + /// We allow it to be negative because in some cases we just want to decrease indentation + /// to preemptively cancel out an indentation that will come later which we don't want to take effect, + /// and we don't want to panic when reaching those negative values. + pub(crate) indentation: i32, + + /// When formatting chunks we sometimes need to remember the current indentation + /// and restore it later. This is what this stack is used for. + indentation_stack: Vec, + + /// Whenever a comment is written, this counter is incremented. + /// In this way we can know if comments were written while formatting some code: + /// we remember the previous value, format, then see if it increased. + /// This is used, for example, when transforming `foo::{bar}` into `foo::bar`: + /// we only do that if there were no comments between `{` and `}`. + written_comments_count: usize, + + /// If we find a comment like this one: + /// + /// // noir-fmt:ignore + /// + /// we won't format the next node (in some cases: only applies to statements and items). + ignore_next: bool, + + /// A counter to create GroupTags. + pub(crate) group_tag_counter: usize, + + /// We keep a copy of the config's max width because when we format chunk groups + /// we somethings change this so that a group has less space to write to. + pub(crate) max_width: usize, + + /// This is the buffer where we write the formatted code. + pub(crate) buffer: Buffer, +} + +impl<'a> Formatter<'a> { + pub(crate) fn new(source: &'a str, config: &'a Config) -> Self { + let lexer = Lexer::new(source).skip_comments(false).skip_whitespaces(false); + let mut formatter = Self { + config, + source, + lexer, + token: Token::EOF, + token_span: Default::default(), + indentation: 0, + indentation_stack: Vec::new(), + written_comments_count: 0, + ignore_next: false, + group_tag_counter: 0, + max_width: config.max_width, + buffer: Buffer::default(), + }; + formatter.bump(); + formatter + } + + pub(crate) fn format_program(&mut self, parsed_module: ParsedModule) { + self.skip_whitespace(); + self.skip_comments_and_whitespace_impl( + true, // write lines + true, // at beginning + ); + + self.format_parsed_module(parsed_module, self.ignore_next); + } + + pub(crate) fn format_parsed_module( + &mut self, + parsed_module: ParsedModule, + mut ignore_next: bool, + ) { + if !parsed_module.inner_doc_comments.is_empty() { + self.format_inner_doc_comments(); + } + + for item in parsed_module.items { + self.format_item(item, ignore_next); + self.write_line(); + ignore_next = self.ignore_next; + } + + self.write_line(); + } + + pub(crate) fn write_identifier(&mut self, ident: Ident) { + self.skip_comments_and_whitespace(); + + let Token::Ident(..) = self.token else { + panic!("Expected identifier, got {:?}", self.token); + }; + self.write(&ident.0.contents); + self.bump(); + } + + pub(crate) fn write_identifier_or_integer(&mut self, ident: Ident) { + self.skip_comments_and_whitespace(); + + if !matches!(self.token, Token::Ident(..) | Token::Int(..)) { + panic!("Expected identifier or integer, got {:?}", self.token); + } + self.write(&ident.0.contents); + self.bump(); + } + + pub(crate) fn write_left_paren(&mut self) { + self.write_token(Token::LeftParen); + } + + pub(crate) fn write_right_paren(&mut self) { + self.write_token(Token::RightParen); + } + + pub(crate) fn write_left_brace(&mut self) { + self.write_token(Token::LeftBrace); + } + + pub(crate) fn write_right_brace(&mut self) { + self.write_token(Token::RightBrace); + } + + pub(crate) fn write_left_bracket(&mut self) { + self.write_token(Token::LeftBracket); + } + + pub(crate) fn write_right_bracket(&mut self) { + self.write_token(Token::RightBracket); + } + + pub(crate) fn write_comma(&mut self) { + self.write_token(Token::Comma); + } + + pub(crate) fn write_semicolon(&mut self) { + self.write_token(Token::Semicolon); + } + + /// Writes the given keyword, if the current token is that keyword + /// (so this is a check that we are producing a token we expect to be in the source + /// we are traversing). Then advances to the next token. + /// + /// Calls `write_token` so comments and whitespaces are skipped before writing the keyword. + pub(crate) fn write_keyword(&mut self, keyword: Keyword) { + self.write_token(Token::Keyword(keyword)); + } + + /// Writes the given token, if the current token is the same as the given one + /// (so this is a check that we are producing a token we expect to be in the source + /// we are traversing). Then advances to the next token. + /// + /// Before writing the token any comments and spaces are skipped. This is so that + /// a caller can call `write_token`, `write_keyword`, `write_space`, etc., without + /// having to explicitly call `skip_comments_and_whitespace` in between those calls. + pub(crate) fn write_token(&mut self, token: Token) { + self.skip_comments_and_whitespace(); + if self.token == token { + self.write_current_token(); + self.bump(); + } else { + panic!("Expected token {:?}, got: {:?}", token, self.token); + } + } + + /// Writes the current token but doesn't advance to the next one. + pub(crate) fn write_current_token(&mut self) { + self.write(&self.token.to_string()); + } + + /// Writes the current token trimming its end but doesn't advance to the next one. + /// Mainly used when writing comment lines, because we never want trailing spaces + /// inside comments. + pub(crate) fn write_current_token_trimming_end(&mut self) { + self.write(self.token.to_string().trim_end()); + } + + /// Writes the current token but without turning it into a string using `to_string()`. + /// Instead, we check the token's span and format what's in the original source there + /// (useful when formatting integer tokens, because a token like 0xFF ends up being an + /// integer with a value 255, but we don't want to change 0xFF to 255). + pub(crate) fn write_current_token_as_in_source(&mut self) { + self.write_source_span(self.token_span); + } + + /// Writes whatever is in the given span relative to the file's source that's being formatted. + pub(crate) fn write_source_span(&mut self, span: Span) { + self.write(&self.source[span.start() as usize..span.end() as usize]); + } + + /// Writes the current indentation to the buffer, but only if the buffer + /// is empty or it ends with a newline (otherwise we'd be indenting when not needed). + pub(crate) fn write_indentation(&mut self) { + if !(self.buffer.is_empty() || self.buffer.ends_with_newline()) { + return; + } + + for _ in 0..self.indentation { + for _ in 0..self.config.tab_spaces { + self.write(" "); + } + } + } + + /// Writes whatever is in the source at the given span without formatting it, + /// then advances the lexer until past the end of the span. + /// This is mainly used to avoid formatting items and statements when a + /// `noir-fmt:ignore` comment is found. + pub(super) fn write_and_skip_span_without_formatting(&mut self, span: Span) { + self.write_source_span(span); + + while self.token_span.start() < span.end() { + self.bump(); + } + } + + /// Writes a string to the buffer. + pub(crate) fn write(&mut self, str: &str) { + self.buffer.write(str); + } + + pub(crate) fn current_line_width(&self) -> usize { + self.buffer.current_line_width() + } + + pub(crate) fn increase_indentation(&mut self) { + self.indentation += 1; + } + + pub(crate) fn decrease_indentation(&mut self) { + self.indentation -= 1; + } + + pub(crate) fn push_indentation(&mut self) { + self.indentation_stack.push(self.indentation); + } + + pub(crate) fn pop_indentation(&mut self) { + self.indentation = self.indentation_stack.pop().unwrap(); + } + + pub(crate) fn is_at_keyword(&self, keyword: Keyword) -> bool { + self.is_at(Token::Keyword(keyword)) + } + + pub(crate) fn is_at(&self, token: Token) -> bool { + self.token == token + } + + /// Advances to the next token (the current token is not written). + pub(crate) fn bump(&mut self) -> Token { + self.ignore_next = false; + + let next_token = self.read_token_internal(); + self.token_span = next_token.to_span(); + std::mem::replace(&mut self.token, next_token.into_token()) + } + + pub(crate) fn read_token_internal(&mut self) -> SpannedToken { + let token = self.lexer.next(); + if let Some(token) = token { + match token { + Ok(token) => token, + Err(err) => panic!("Expected lexer not to error, but got: {:?}", err), + } + } else { + SpannedToken::new(Token::EOF, Default::default()) + } + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/alias.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/alias.rs new file mode 100644 index 00000000000..d4c63ebdd9e --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/alias.rs @@ -0,0 +1,41 @@ +use noirc_frontend::{ + ast::NoirTypeAlias, + token::{Keyword, Token}, +}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_type_alias(&mut self, type_alias: NoirTypeAlias) { + self.write_indentation(); + self.format_item_visibility(type_alias.visibility); + self.write_keyword(Keyword::Type); + self.write_space(); + self.write_identifier(type_alias.name); + self.format_generics(type_alias.generics); + self.write_space(); + self.write_token(Token::Assign); + self.write_space(); + self.format_type(type_alias.typ); + self.write_semicolon(); + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_type_alias() { + let src = " pub type Foo = i32 ; "; + let expected = "pub type Foo = i32;\n"; + assert_format(src, expected); + } + + #[test] + fn format_generic_type_alias() { + let src = " pub type Foo < A, B > = i32 ; "; + let expected = "pub type Foo = i32;\n"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/attribute.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/attribute.rs new file mode 100644 index 00000000000..c13ba2a8c4c --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/attribute.rs @@ -0,0 +1,30 @@ +use noirc_frontend::token::Token; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_attributes(&mut self) { + loop { + self.skip_comments_and_whitespace(); + + if let Token::Attribute(_) = self.token { + self.write_indentation(); + self.write_current_token(); + self.bump(); + self.write_line(); + } else { + break; + } + } + } + + pub(super) fn format_inner_attribute(&mut self) { + self.skip_comments_and_whitespace(); + let Token::InnerAttribute(..) = self.token else { + panic!("Expected inner attribute, got {:?}", self.token); + }; + self.write_indentation(); + self.write_current_token(); + self.bump(); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/buffer.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/buffer.rs new file mode 100644 index 00000000000..e4740311bf6 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/buffer.rs @@ -0,0 +1,64 @@ +/// A buffer to write to. +/// It keeps track of the current line width and provides a few useful methods +/// to deal with the buffer contents. +#[derive(Default, Debug)] +pub(crate) struct Buffer { + buffer: String, + + /// How many characters we've written so far in the current line + /// (useful to avoid exceeding the configurable maximum) + current_line_width: usize, +} + +impl Buffer { + pub(crate) fn is_empty(&self) -> bool { + self.buffer.is_empty() + } + + pub(crate) fn ends_with_newline(&self) -> bool { + self.buffer.ends_with('\n') + } + + pub(crate) fn ends_with_double_newline(&self) -> bool { + self.buffer.ends_with("\n\n") + } + + pub(crate) fn ends_with_space(&self) -> bool { + self.buffer.ends_with(' ') + } + + pub(crate) fn write(&mut self, str: &str) { + self.buffer.push_str(str); + + if str.ends_with('\n') { + self.current_line_width = 0; + } else { + self.current_line_width += str.chars().count(); + } + } + + /// Trim spaces from the end of the buffer. + pub(super) fn trim_spaces(&mut self) { + while self.buffer.ends_with(' ') { + self.buffer.truncate(self.buffer.len() - 1); + } + } + + /// Trim commas from the end of the buffer. Returns true if a comma was trimmed. + pub(super) fn trim_comma(&mut self) -> bool { + if self.buffer.ends_with(',') { + self.buffer.truncate(self.buffer.len() - 1); + true + } else { + false + } + } + + pub(crate) fn contents(self) -> String { + self.buffer + } + + pub(crate) fn current_line_width(&self) -> usize { + self.current_line_width + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs new file mode 100644 index 00000000000..e5f15bc397e --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs @@ -0,0 +1,859 @@ +use noirc_frontend::token::Token; + +use super::Formatter; + +#[cfg(windows)] +const NEWLINE: &str = "\r\n"; +#[cfg(not(windows))] +const NEWLINE: &str = "\n"; + +impl<'a> Formatter<'a> { + /// Writes a single space, skipping any whitespace and comments. + /// That is, suppose the next token is a big whitespace, possibly with multiple lines. + /// Those are skipped but only one space is written. In this way if we have + /// "mod foo" it's transformed to "mod foo". + /// If there are comments in between `mod` and `foo` they are written, though! + /// No comment is ever lost. + /// + /// A space is not appended to the buffer is it already ends with a space. + pub(crate) fn write_space(&mut self) { + self.skip_comments_and_whitespace(); + self.write_space_without_skipping_whitespace_and_comments(); + } + + /// Writes a single space, but doesn't skip whitespace and comments before doing that. + /// + /// A space is not appended to the buffer is it already ends with a space. + pub(crate) fn write_space_without_skipping_whitespace_and_comments(&mut self) { + if !self.buffer.ends_with_newline() && !self.buffer.ends_with_space() { + self.write(" "); + } + } + + pub(crate) fn skip_whitespace(&mut self) { + while let Token::Whitespace(..) = &self.token { + self.bump(); + } + } + + /// Only skips whitespace if it doesn't have newlines in it. + /// Note that this doesn't write whitespace or comments at all. + pub(crate) fn skip_whitespace_if_it_is_not_a_newline(&mut self) { + while let Token::Whitespace(whitespace) = &self.token { + if whitespace.contains('\n') { + break; + } + self.bump(); + } + } + + /// Skips comments and whitespace, writing newlines if there are any. + /// If there are multiple consecutive newlines, only one is written. + pub(crate) fn skip_comments_and_whitespace(&mut self) { + self.skip_comments_and_whitespace_impl( + false, // write multiple lines + false, // at beginning + ); + } + + /// Similar to skip_comments_and_whitespace, but will write two lines if + /// multiple newlines are found (but at most two lines at a time). + pub(crate) fn skip_comments_and_whitespace_writing_multiple_lines_if_found(&mut self) { + self.skip_comments_and_whitespace_impl( + true, // write multiple lines + false, // at beginning + ); + } + + pub(crate) fn skip_comments_and_whitespace_impl( + &mut self, + write_multiple_lines: bool, + at_beginning: bool, + ) { + // Number of newlines we just skipped. + let mut number_of_newlines = 0; + + // Did we just passed some whitespace? + let mut passed_whitespace = false; + + // Was the last token we processed a block comment? + let mut last_was_block_comment = false; + + let mut ignore_next = false; + + loop { + match &self.token { + Token::Whitespace(whitespace) => { + number_of_newlines = whitespace.chars().filter(|char| *char == '\n').count(); + passed_whitespace = whitespace.ends_with(' '); + + if last_was_block_comment && number_of_newlines > 0 { + if number_of_newlines > 1 { + self.write_multiple_lines_without_skipping_whitespace_and_comments(); + } else { + self.write_line_without_skipping_whitespace_and_comments(); + } + + self.bump(); + + // Only indent for what's coming next if it's a comment + // (otherwise a closing brace must come and we wouldn't want to indent that) + if matches!( + &self.token, + Token::LineComment(_, None) | Token::BlockComment(_, None), + ) { + self.write_indentation(); + } + + number_of_newlines = 0; + passed_whitespace = false; + } else { + self.bump(); + } + + last_was_block_comment = false; + } + Token::LineComment(comment, None) => { + if comment.trim() == "noir-fmt:ignore" { + ignore_next = true; + } + + // Here we check if we need to write one line, two lines or none after the + // end of the line comment. + if number_of_newlines > 1 && write_multiple_lines { + self.write_multiple_lines_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } else if number_of_newlines > 0 { + self.write_line_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } else if !(at_beginning && self.buffer.is_empty()) { + // We write a space before a line comment so if you have code like this: + // "1// comment" it's transformed to "1 // comment". + // What if there was already a space? It's all good, `write_space` + // will never write two consecutive spaces. + self.write_space_without_skipping_whitespace_and_comments(); + } + + self.write_current_token_trimming_end(); + self.write_line_without_skipping_whitespace_and_comments(); + number_of_newlines = 1; + self.bump(); + passed_whitespace = false; + last_was_block_comment = false; + self.written_comments_count += 1; + } + Token::BlockComment(comment, None) => { + if comment.trim() == "noir-fmt:ignore" { + ignore_next = true; + } + + // Here we check if we need to write one line, two lines or none after the + // end of the block comment. + if number_of_newlines > 1 && write_multiple_lines { + self.write_multiple_lines_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } else if number_of_newlines > 0 { + self.write_line_without_skipping_whitespace_and_comments(); + self.write_indentation(); + } else if passed_whitespace { + // We write a space before a line comment so if you have code like this: + // "1/* comment */" it's transformed to "1 /* comment */". + // What if there was already a space? It's all good, `write_space` + // will never write two consecutive spaces. + self.write_space_without_skipping_whitespace_and_comments(); + } + self.write_current_token(); + self.bump(); + passed_whitespace = false; + last_was_block_comment = true; + self.written_comments_count += 1; + } + _ => break, + } + } + + // Case when we passed some whitespace with newlines but no comments followed it. + if number_of_newlines > 1 && write_multiple_lines { + self.write_multiple_lines_without_skipping_whitespace_and_comments(); + } + + self.ignore_next = ignore_next; + } + + /// Returns the number of newlines that come next, if we are at a whitespace + /// token (otherwise returns 0). + pub(crate) fn following_newlines_count(&self) -> usize { + let Token::Whitespace(whitespace) = &self.token else { + return 0; + }; + + whitespace.chars().filter(|char| *char == '\n').count() + } + + /// Writes a single newline, if the last thing we wrote wasn't also a newline + /// (this prevents multiple consecutive newlines, though that's still possible to + /// do if you call `write_multiple_lines_...`). + /// + /// Any whitespace or comments found right at and after the current token are "skipped" + /// (whitespace is discarded, comments are written). + pub(crate) fn write_line(&mut self) { + self.skip_comments_and_whitespace_impl( + true, // writing newline + false, // at beginning + ); + self.write_line_without_skipping_whitespace_and_comments(); + } + + pub(crate) fn write_line_without_skipping_whitespace_and_comments(&mut self) -> bool { + if !self.buffer.ends_with_newline() && !self.buffer.ends_with_space() { + self.write(NEWLINE); + true + } else { + false + } + } + + // Modifies the current buffer so that it will always have two newlines at the end. + pub(crate) fn write_multiple_lines_without_skipping_whitespace_and_comments(&mut self) { + if self.buffer.ends_with_double_newline() { + // Nothing + } else if self.buffer.ends_with_newline() { + self.write(NEWLINE); + } else { + self.write(NEWLINE); + self.write(NEWLINE); + } + } + + /// Trim spaces from the end of the buffer. + pub(crate) fn trim_spaces(&mut self) { + self.buffer.trim_spaces(); + } + + /// Trim commas from the end of the buffer. Returns true if a comma was trimmed. + pub(crate) fn trim_comma(&mut self) -> bool { + self.buffer.trim_comma() + } +} + +#[cfg(test)] +mod tests { + use crate::{assert_format, assert_format_with_max_width}; + + #[test] + fn format_array_in_global_with_line_comments() { + let src = "global x = [ // hello + 1 , 2 ] ;"; + let expected = "global x = [ + // hello + 1, 2, +]; +"; + assert_format(src, expected); + } + + #[test] + fn format_array_in_global_with_line_comments_2() { + let src = "global x = [ // hello + [ 1 , 2 ] ] ;"; + let expected = "global x = [ + // hello + [1, 2], +]; +"; + assert_format(src, expected); + } + + #[test] + fn format_array_in_global_with_line_comments_3() { + let src = "global x = + [ + // hello + [1, 2], + ]; +"; + let expected = "global x = [ + // hello + [1, 2], +]; +"; + assert_format(src, expected); + } + + #[test] + fn format_array_in_global_with_line_comments_4() { + let src = "global x = + [ + 1, // world + 2, 3, + ]; +"; + let expected = "global x = [ + 1, // world + 2, 3, +]; +"; + assert_format(src, expected); + } + + #[test] + fn format_array_in_global_with_block_comments() { + let src = "global x = [ /* hello */ + 1 , 2 ] ;"; + let expected = "global x = [ + /* hello */ + 1, 2, +]; +"; + assert_format_with_max_width(src, expected, 20); + } + + #[test] + fn format_if_with_comment_after_condition() { + let src = "global x = if 123 // some comment + { 456 } ;"; + let expected = "global x = if 123 // some comment +{ + 456 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_if_with_comment_after_else() { + let src = "global x = if 123 { 456 } else // some comment + { 789 };"; + let expected = "global x = if 123 { + 456 +} else // some comment +{ + 789 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_function_when_some_args_are_multiline_because_of_line_comments() { + let src = "fn foo ( a: i32, // comment + b: i32 + ) { } "; + let expected = "fn foo( + a: i32, // comment + b: i32, +) {} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_when_some_args_are_multiline_because_of_line_comments_2() { + let src = "fn foo ( a: i32, // comment + // another + b: i32 // another comment + ) { } "; + let expected = "fn foo( + a: i32, // comment + // another + b: i32, // another comment +) {} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_when_some_args_are_multiline_because_of_block_comments() { + let src = "fn foo ( a: i32 /* + some + comment */, b: i32 + ) { } "; + let expected = "fn foo( + a: i32 /* + some + comment */, + b: i32, +) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_comment_after_parameters() { + let src = "fn main() + // hello + {}"; + let expected = "fn main() +// hello +{} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_line_comment_in_parameters() { + let src = "fn main( + // hello + ) + {}"; + let expected = "fn main( + // hello +) {} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_line_comment_on_top_of_parameter() { + let src = "fn main( +// hello +unit: () +) {}"; + let expected = "fn main( + // hello + unit: (), +) {} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_block_comment_in_params() { + let src = "fn main(/* test */) {}"; + let expected = "fn main(/* test */) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_body_and_block_comment() { + let src = "fn main() { + /* foo */ + 1 }"; + let expected = "fn main() { + /* foo */ + 1 +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_body_one_expr_trailing_comment() { + let src = "mod moo { fn main() { 1 // yes + } }"; + let expected = "mod moo { + fn main() { + 1 // yes + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_body_one_expr_semicolon_trailing_comment() { + let src = "mod moo { fn main() { 1 ; // yes + } }"; + let expected = "mod moo { + fn main() { + 1; // yes + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_many_exprs_trailing_comments() { + let src = "mod moo { fn main() { 1 ; // yes + 2 ; // no + 3 // maybe + } }"; + let expected = "mod moo { + fn main() { + 1; // yes + 2; // no + 3 // maybe + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_block_comment_after_two_newlines() { + let src = "fn foo() { + 1; + + /* world */ + 2 +} +"; + let expected = "fn foo() { + 1; + + /* world */ + 2 +} +"; + assert_format(src, expected); + } + + #[test] + fn format_comment_on_top_of_let_followed_by_statement() { + let src = "fn foo() { + 1; + + // Comment + let x = 1; +} +"; + let expected = "fn foo() { + 1; + + // Comment + let x = 1; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_module_declaration_with_block_comments() { + let src = " mod/*a*/ foo /*b*/ ; "; + let expected = "mod/*a*/ foo /*b*/;\n"; + assert_format(src, expected); + } + + #[test] + fn format_module_declaration_with_inline_comments() { + let src = " mod // a + foo // b + ; "; + let expected = "mod // a +foo // b +; +"; + assert_format(src, expected); + } + + #[test] + fn format_submodule_with_line_comments_in_separate_line() { + let src = " #[foo] pub mod foo { +// one +#[hello] +mod bar; +// two +}"; + let expected = "#[foo] +pub mod foo { + // one + #[hello] + mod bar; + // two +} +"; + assert_format(src, expected); + } + + #[test] + fn format_submodule_with_line_comment_in_same_line() { + let src = " #[foo] pub mod foo { // one +mod bar; +}"; + let expected = "#[foo] +pub mod foo { // one + mod bar; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_submodule_with_block_comment() { + let src = " #[foo] pub mod foo { /* one */ +/* two */ +mod bar; +}"; + let expected = "#[foo] +pub mod foo { /* one */ + /* two */ + mod bar; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_submodule_with_block_comment_2() { + let src = "mod foo { + /* one */ +}"; + let expected = "mod foo { + /* one */ +} +"; + assert_format(src, expected); + } + + #[test] + fn keeps_spaces_between_comments() { + let src = " mod foo { + +// hello + +// world + +} "; + let expected = "mod foo { + + // hello + + // world + +} +"; + assert_format(src, expected); + } + + #[test] + fn comment_with_leading_space() { + let src = " // comment + // hello +mod foo ; "; + let expected = "// comment +// hello +mod foo; +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_block_statement_with_inline_block_comment() { + let src = " fn foo() { { /* hello */ } } "; + let expected = "fn foo() { + { /* hello */ } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_struct_with_block_comments() { + let src = " struct Foo { + /* hello */ + } + "; + let expected = "struct Foo { /* hello */ }\n"; + assert_format(src, expected); + } + + #[test] + fn format_struct_with_just_comments() { + let src = " mod foo { struct Foo { +// hello + } } + "; + let expected = "mod foo { + struct Foo { + // hello + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_block_comment_no_whitespace_in_block_single_line() { + let src = "global x = {/*foo*/};"; + let expected = "global x = { /*foo*/ };\n"; + assert_format(src, expected); + } + + #[test] + fn format_block_comment_no_whitespace_but_newline_in_block_single_line() { + let src = "global x = {/*foo*/ + };"; + let expected = "global x = { /*foo*/ };\n"; + assert_format(src, expected); + } + + #[test] + fn format_line_comment_in_block_same_line() { + let src = "global x = { // foo + };"; + let expected = "global x = { // foo +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_line_comment_in_block_separate_line() { + let src = "global x = { + // foo + };"; + let expected = "global x = { + // foo +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_block_comment_in_parenthesized_expression() { + let src = "global x = ( /* foo */ 1 );"; + let expected = "global x = ( /* foo */ 1);\n"; + assert_format(src, expected); + } + + #[test] + fn format_line_comment_in_parenthesized() { + let src = "global x = ( // hello + 1 );"; + let expected = "global x = ( + // hello + 1 +);\n"; + assert_format(src, expected); + } + + #[test] + fn format_index_with_comment() { + let src = "global x = foo[// hello + 1];"; + let expected = "global x = foo[ + // hello + 1 +];\n"; + assert_format(src, expected); + } + + #[test] + fn format_comment_in_infix_between_lhs_and_operator() { + let src = "global x = 1/* comment */+ 2 ;"; + let expected = "global x = 1 /* comment */ + 2;\n"; + assert_format(src, expected); + } + + #[test] + fn format_comment_in_constructor_inside_function() { + let src = "fn foo() { MyStruct {/*test*/}; } "; + let expected = "fn foo() { + MyStruct { /*test*/ }; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_block_comment_before_constructor_field() { + let src = "global x = Foo {/*comment*/field}; "; + let expected = "global x = Foo { /*comment*/ field };\n"; + assert_format(src, expected); + } + + #[test] + fn format_line_comment_before_constructor_field() { + let src = "global x = Foo { // foo + field}; "; + let expected = "global x = Foo { + // foo + field, +};\n"; + assert_format(src, expected); + } + + #[test] + fn format_comment_in_empty_constructor() { + let src = "global x = Foo { // comment + }; "; + let expected = "global x = Foo { // comment +};\n"; + assert_format(src, expected); + } + + #[test] + fn format_comment_after_parenthesized() { + let src = "global x = ( + 1 + // hello + ) + ; "; + let expected = "global x = ( + 1 + // hello +);\n"; + assert_format(src, expected); + } + + #[test] + fn format_comment_in_single_element_tuple() { + let src = "global x = ( 1 /* hello */ , );"; + let expected = "global x = (1 /* hello */,);\n"; + assert_format(src, expected); + } + + #[test] + fn format_comment_after_impl_function() { + let src = "impl Foo { fn foo() {} + // bar + }"; + let expected = "impl Foo { + fn foo() {} + // bar +} +"; + assert_format(src, expected); + } + + #[test] + fn format_comment_after_trait_impl_function() { + let src = "impl Foo for Bar { fn foo() {} + // bar + }"; + let expected = "impl Foo for Bar { + fn foo() {} + // bar +} +"; + assert_format(src, expected); + } + + #[test] + fn format_comment_after_trait_function() { + let src = "trait Foo { fn foo() {} + // bar + }"; + let expected = "trait Foo { + fn foo() {} + // bar +} +"; + assert_format(src, expected); + } + + #[test] + fn keeps_newlines_after_comment_at_the_beginning() { + let src = "// foo + +global x = 1; +"; + let expected = src; + assert_format(src, expected); + } + + #[test] + fn keeps_newlines_after_comment_at_the_beginning_2() { + let src = " + + // foo + +global x = 1; +"; + let expected = "// foo + +global x = 1; +"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/doc_comments.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/doc_comments.rs new file mode 100644 index 00000000000..ac2cae10c78 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/doc_comments.rs @@ -0,0 +1,72 @@ +use noirc_frontend::token::{DocStyle, Token}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_inner_doc_comments(&mut self) { + loop { + self.skip_comments_and_whitespace(); + + match self.token { + Token::LineComment(_, Some(DocStyle::Inner)) + | Token::BlockComment(_, Some(DocStyle::Inner)) => { + self.write_indentation(); + self.write_current_token_trimming_end(); + self.bump(); + self.write_line(); + } + _ => break, + } + } + } + + pub(super) fn format_outer_doc_comments(&mut self) { + loop { + self.skip_comments_and_whitespace(); + + match self.token { + Token::LineComment(_, Some(DocStyle::Outer)) + | Token::BlockComment(_, Some(DocStyle::Outer)) => { + self.write_indentation(); + self.write_current_token_trimming_end(); + self.bump(); + self.write_line(); + } + _ => break, + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_inner_doc_comments() { + let src = " #![hello] #![world]"; + let expected = "#![hello]\n#![world]\n"; + assert_format(src, expected); + } + + #[test] + fn format_inner_doc_comments_with_line_comments() { + let src = " #![hello] // foo + // bar + #![world]"; + let expected = "#![hello] // foo +// bar +#![world] +"; + assert_format(src, expected); + } + + #[test] + fn format_inner_doc_comments_with_block_comments() { + let src = " #![hello] /* foo */ #![world]"; + let expected = "#![hello] /* foo */ +#![world] +"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs new file mode 100644 index 00000000000..448481047df --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/expression.rs @@ -0,0 +1,2134 @@ +use noirc_frontend::{ + ast::{ + ArrayLiteral, BinaryOpKind, BlockExpression, CallExpression, CastExpression, + ConstructorExpression, Expression, ExpressionKind, IfExpression, IndexExpression, + InfixExpression, Lambda, Literal, MemberAccessExpression, MethodCallExpression, + PrefixExpression, TypePath, UnaryOp, UnresolvedTypeData, + }, + token::{Keyword, Token}, +}; + +use crate::chunks::{Chunk, ChunkFormatter, ChunkGroup, GroupKind, GroupTag, TextChunk}; + +use super::Formatter; + +#[derive(Debug)] +struct FormattedLambda { + group: ChunkGroup, + first_line_width: usize, +} + +impl<'a, 'b> ChunkFormatter<'a, 'b> { + pub(super) fn format_expression(&mut self, expression: Expression, group: &mut ChunkGroup) { + group.leading_comment(self.skip_comments_and_whitespace_chunk()); + + match expression.kind { + ExpressionKind::Literal(literal) => self.format_literal(literal, group), + ExpressionKind::Block(block) => { + group.group(self.format_block_expression( + block, false, // force multiple lines + )); + } + ExpressionKind::Prefix(prefix_expression) => { + group.group(self.format_prefix(*prefix_expression)); + } + ExpressionKind::Index(index_expression) => { + group.group(self.format_index_expression(*index_expression)); + } + ExpressionKind::Call(call) => group.group(self.format_call(*call)), + ExpressionKind::MethodCall(method_call) => { + group.group(self.format_method_call(*method_call)); + } + ExpressionKind::Constructor(constructor) => { + group.group(self.format_constructor(*constructor)); + } + ExpressionKind::MemberAccess(member_access) => { + group.group(self.format_member_access(*member_access)); + } + ExpressionKind::Cast(cast_expression) => { + group.group(self.format_cast(*cast_expression)); + } + ExpressionKind::Infix(infix_expression) => { + group.group(self.format_infix_expression(*infix_expression)); + } + ExpressionKind::If(if_expression) => { + group.group(self.format_if_expression( + *if_expression, + false, // force multiple lines + )); + } + ExpressionKind::Variable(path) => { + group.text(self.chunk(|formatter| { + formatter.format_path(path); + })); + } + ExpressionKind::Tuple(exprs) => group.group(self.format_tuple(exprs)), + ExpressionKind::Lambda(lambda) => group.group(self.format_lambda(*lambda).group), + ExpressionKind::Parenthesized(expression) => { + group.group(self.format_parenthesized_expression(*expression)); + } + ExpressionKind::Quote(..) => { + group.group(self.format_quote()); + } + ExpressionKind::Unquote(..) => { + unreachable!("Should not be present in the AST") + } + ExpressionKind::Comptime(block_expression, _span) => { + group.group(self.format_comptime_expression( + block_expression, + false, // force multiple lines + )); + } + ExpressionKind::Unsafe(block_expression, _span) => { + group.group(self.format_unsafe_expression( + block_expression, + false, // force multiple lines + )); + } + ExpressionKind::AsTraitPath(as_trait_path) => { + group.text(self.chunk(|formatter| formatter.format_as_trait_path(as_trait_path))); + } + ExpressionKind::TypePath(type_path) => { + group.group(self.format_type_path(type_path)); + } + ExpressionKind::Resolved(..) + | ExpressionKind::Interned(..) + | ExpressionKind::InternedStatement(..) + | ExpressionKind::Error => unreachable!("Should not be present in the AST"), + } + } + + fn format_literal(&mut self, literal: Literal, group: &mut ChunkGroup) { + match literal { + Literal::Unit => group.text(self.chunk(|formatter| { + formatter.write_left_paren(); + formatter.write_right_paren(); + })), + Literal::Bool(_) | Literal::Str(_) | Literal::FmtStr(_) | Literal::RawStr(..) => group + .text(self.chunk(|formatter| { + formatter.write_current_token_as_in_source(); + formatter.bump(); + })), + Literal::Integer(..) => group.text(self.chunk(|formatter| { + if formatter.is_at(Token::Minus) { + formatter.write_token(Token::Minus); + formatter.skip_comments_and_whitespace(); + } + formatter.write_current_token_as_in_source(); + formatter.bump(); + })), + Literal::Array(array_literal) => group.group(self.format_array_literal( + array_literal, + false, // is slice + )), + Literal::Slice(array_literal) => { + group.group(self.format_array_literal( + array_literal, + true, // is slice + )); + } + } + } + + fn format_array_literal(&mut self, literal: ArrayLiteral, is_slice: bool) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + group.text(self.chunk(|formatter| { + if is_slice { + formatter.write_token(Token::Ampersand); + } + formatter.write_left_bracket(); + })); + + match literal { + ArrayLiteral::Standard(exprs) => { + group.kind = GroupKind::ExpressionList { + prefix_width: group.width(), + expressions_count: exprs.len(), + }; + + let maximum_element_width = self.format_expressions_separated_by_comma( + exprs, false, // force trailing comma + &mut group, + ); + group.one_chunk_per_line = + maximum_element_width > self.config.short_array_element_width_threshold; + } + ArrayLiteral::Repeated { repeated_element, length } => { + group.increase_indentation(); + group.line(); + + self.format_expression(*repeated_element, &mut group); + group.semicolon(self); + group.space(self); + self.format_expression(*length, &mut group); + + group.decrease_indentation(); + group.line(); + } + } + + group.text(self.chunk(|formatter| formatter.write_right_bracket())); + + group + } + + fn format_tuple(&mut self, exprs: Vec) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.one_chunk_per_line = false; + + let force_trailing_comma = exprs.len() == 1; + + group.text(self.chunk(|formatter| { + formatter.write_left_paren(); + })); + + group.kind = GroupKind::ExpressionList { + prefix_width: group.width(), + expressions_count: exprs.len(), + }; + + self.format_expressions_separated_by_comma(exprs, force_trailing_comma, &mut group); + + group.text(self.chunk(|formatter| formatter.write_right_paren())); + + group + } + + fn format_lambda(&mut self, lambda: Lambda) -> FormattedLambda { + let mut group = ChunkGroup::new(); + + let params_and_return_type_chunk = self.chunk(|formatter| { + formatter.write_token(Token::Pipe); + for (index, (pattern, typ)) in lambda.parameters.into_iter().enumerate() { + if index > 0 { + formatter.write_comma(); + formatter.write_space(); + } + formatter.format_pattern(pattern); + if typ.typ != UnresolvedTypeData::Unspecified { + formatter.write_token(Token::Colon); + formatter.write_space(); + formatter.format_type(typ); + } + } + formatter.skip_comments_and_whitespace(); + if formatter.is_at(Token::Comma) { + formatter.bump(); + } + formatter.write_token(Token::Pipe); + formatter.write_space(); + if lambda.return_type.typ != UnresolvedTypeData::Unspecified { + formatter.write_token(Token::Arrow); + formatter.write_space(); + formatter.format_type(lambda.return_type); + formatter.write_space(); + } + }); + + let params_and_return_type_chunk_width = params_and_return_type_chunk.width; + + group.text(params_and_return_type_chunk); + + let body_is_block = matches!(lambda.body.kind, ExpressionKind::Block(..)); + + let mut body_group = ChunkGroup::new(); + body_group.kind = GroupKind::LambdaBody { is_block: body_is_block }; + + self.format_expression(lambda.body, &mut body_group); + group.group(body_group); + + let first_line_width = params_and_return_type_chunk_width + + (if body_is_block { + // 1 because we already have `|param1, param2, ..., paramN| ` (including the space) + // so all that's left is a `{`. + 1 + } else { + // The body is not a block so we can write it right away + 0 + }); + + FormattedLambda { group, first_line_width } + } + + fn format_parenthesized_expression(&mut self, expr: Expression) -> ChunkGroup { + let is_nested_parenthesized = matches!(expr.kind, ExpressionKind::Parenthesized(..)); + + let mut group = ChunkGroup::new(); + let left_paren_chunk = self.chunk(|formatter| { + formatter.write_left_paren(); + }); + + let mut expr_group = ChunkGroup::new(); + let mut has_comments = false; + + let comment_after_left_paren_chunk = self.skip_comments_and_whitespace_chunk(); + if !comment_after_left_paren_chunk.string.trim().is_empty() { + has_comments = true; + } + + expr_group.leading_comment(comment_after_left_paren_chunk); + + self.format_expression(expr, &mut expr_group); + + let comment_before_right_parent_chunk = self.skip_comments_and_whitespace_chunk(); + if !comment_before_right_parent_chunk.string.trim().is_empty() { + has_comments = true; + } + + let right_paren_chunk = self.chunk(|formatter| { + formatter.write_right_paren(); + }); + + if is_nested_parenthesized && !has_comments && self.config.remove_nested_parens { + group.chunks.extend(expr_group.chunks); + } else { + group.text(left_paren_chunk); + group.increase_indentation(); + group.line(); + group.chunks.extend(expr_group.chunks); + group.text(comment_before_right_parent_chunk); + group.decrease_indentation(); + group.line(); + group.text(right_paren_chunk); + } + + group + } + + pub(super) fn format_quote(&mut self) -> ChunkGroup { + // We use the current token rather than the Tokens we got from `Token::Quote` because + // the current token has whitespace and comments in it, while the one we got from + // the parser doesn't. + let Token::Quote(tokens) = self.bump() else { + panic!("Expected current token to be Quote"); + }; + + let mut group = ChunkGroup::new(); + group.verbatim(self.chunk(|formatter| { + formatter.write("quote {"); + for token in tokens.0 { + formatter.write_source_span(token.to_span()); + } + formatter.write("}"); + })); + group + } + + pub(super) fn format_comptime_expression( + &mut self, + block: BlockExpression, + force_multiple_lines: bool, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::Comptime); + formatter.write_space(); + })); + group.group(self.format_block_expression(block, force_multiple_lines)); + group + } + + pub(super) fn format_unsafe_expression( + &mut self, + block: BlockExpression, + force_multiple_lines: bool, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::Unsafe); + formatter.write_space(); + })); + group.group(self.format_block_expression(block, force_multiple_lines)); + group + } + + pub(super) fn format_type_path(&mut self, type_path: TypePath) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.text(self.chunk(|formatter| { + formatter.format_type(type_path.typ); + formatter.write_token(Token::DoubleColon); + formatter.write_identifier(type_path.item); + if !type_path.turbofish.is_empty() { + formatter.write_token(Token::DoubleColon); + formatter.format_generic_type_args(type_path.turbofish); + } + })); + group + } + + /// Returns the maximum width of each expression to format. For example, + /// if the list is [1, 234, 56], the maximum width is 3 (that of `234`). + pub(super) fn format_expressions_separated_by_comma( + &mut self, + exprs: Vec, + force_trailing_comma: bool, + group: &mut ChunkGroup, + ) -> usize { + if exprs.is_empty() { + if let Some(inner_group) = self.empty_block_contents_chunk() { + group.group(inner_group); + } + 0 + } else { + let exprs_len = exprs.len(); + let mut expr_index = 0; + let mut max_width = 0; + + self.format_items_separated_by_comma( + exprs, + force_trailing_comma, + false, // surround with spaces + group, + |formatter, expr, chunks| { + // If the last expression in the list is a lambda, we format it but we mark + // the chunk in a special way: it likely has newlines, but we don't want + // those newlines to affect the parent group. For example: + // + // foo(1, 2, |x| { + // let y = x + 1; + // y * 2 + // }) + if expr_index == exprs_len - 1 { + if let ExpressionKind::Lambda(lambda) = expr.kind { + let mut lambda_group = formatter.format_lambda(*lambda); + lambda_group.group.kind = GroupKind::LambdaAsLastExpressionInList { + first_line_width: lambda_group.first_line_width, + indentation: None, + }; + chunks.group(lambda_group.group); + return; + } + } + expr_index += 1; + + let chunks_len_before_expression = chunks.chunks.len(); + + formatter.format_expression(expr, chunks); + + let chunks_len_after_expression = chunks.chunks.len(); + let expression_width: usize = (chunks_len_before_expression + ..chunks_len_after_expression) + .map(|index| chunks.chunks[index].width()) + .sum(); + if expression_width > max_width { + max_width = expression_width; + } + }, + ); + + max_width + } + } + + pub(super) fn format_items_separated_by_comma( + &mut self, + items: Vec, + force_trailing_comma: bool, + surround_with_spaces: bool, + group: &mut ChunkGroup, + mut format_item: F, + ) where + F: FnMut(&mut Self, Item, &mut ChunkGroup), + { + let mut comments_chunk = self.skip_comments_and_whitespace_chunk(); + + // If the comment is not empty but doesn't have newlines, it's surely `/* comment */`. + // We format that with spaces surrounding it so it looks, for example, like `Foo { /* comment */ field ..`. + if !comments_chunk.string.trim().is_empty() && !comments_chunk.has_newlines { + // Note: there's no space after `{}` because space will be produced by format_items_separated_by_comma + comments_chunk.string = if surround_with_spaces { + format!(" {}", comments_chunk.string.trim()) + } else { + format!(" {} ", comments_chunk.string.trim()) + }; + group.text(comments_chunk); + + group.increase_indentation(); + if surround_with_spaces { + group.space_or_line(); + } else { + group.line(); + } + } else { + group.increase_indentation(); + if surround_with_spaces { + group.space_or_line(); + } else { + group.line(); + } + + group.trailing_comment(comments_chunk); + } + + for (index, expr) in items.into_iter().enumerate() { + if index > 0 { + group.text_attached_to_last_group(self.chunk(|formatter| { + formatter.write_comma(); + })); + group.trailing_comment(self.skip_comments_and_whitespace_chunk()); + group.space_or_line(); + } + format_item(self, expr, group); + } + + let chunk = self.chunk(|formatter| { + formatter.skip_comments_and_whitespace(); + + // Trailing comma + if formatter.is_at(Token::Comma) { + formatter.bump(); + formatter.skip_comments_and_whitespace(); + } + }); + + // Make sure to put a trailing comma before the last parameter comments, if there were any + if !force_trailing_comma { + group.trailing_comma(); + } + + group.text(chunk); + + if force_trailing_comma { + group.text(TextChunk::new(",".to_string())); + } + + group.decrease_indentation(); + if surround_with_spaces { + group.space_or_line(); + } else { + group.line(); + } + } + + fn format_constructor(&mut self, constructor: ConstructorExpression) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.text(self.chunk(|formatter| { + formatter.format_type(constructor.typ); + formatter.write_space(); + formatter.write_left_brace(); + })); + + if constructor.fields.is_empty() { + if let Some(inner_group) = self.empty_block_contents_chunk() { + group.group(inner_group); + } + } else { + self.format_items_separated_by_comma( + constructor.fields, + false, // force trailing comma + true, // surround with spaces + &mut group, + |formatter, (name, value), chunks| { + chunks.text(formatter.chunk(|formatter| { + formatter.write_identifier(name); + formatter.skip_comments_and_whitespace(); + })); + + if formatter.is_at(Token::Colon) { + chunks.text(formatter.chunk(|formatter| { + formatter.write_token(Token::Colon); + formatter.write_space(); + })); + formatter.format_expression(value, chunks); + } + }, + ); + } + group.text(self.chunk(|formatter| { + formatter.write_right_brace(); + })); + + group + } + + fn format_member_access(&mut self, member_access: MemberAccessExpression) -> ChunkGroup { + let group_tag = self.new_group_tag(); + + let mut group = self.format_member_access_impl( + member_access, + false, // nested + group_tag, + ); + group.force_multiline_on_children_with_same_tag_if_multiline = true; + group + } + + fn format_member_access_impl( + &mut self, + member_access: MemberAccessExpression, + nested: bool, + group_tag: GroupTag, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.tag = Some(group_tag); + + if !nested { + group.push_indentation(); + } + + // If we have code like `foo.bar.baz.qux`, where `member_access.lhs` is also a MemberAccessExpression, + // we'll format it with the same tag. Once the lhs is not a MemberAccessExpression, we'll format it + // and add an increase in indentation, but just once so that it ends up being formatted like this + // in case it needs to be formatted in multiple lines: + // + // foo.bar + // .baz + // .qux + // + // Note that we do the same if the lhs is a MethodCallExpression. + // + // Also note that we don't format it like this: + // + // foo + // .bar + // .baz + // .qux + // + // For that, we check if the lhs'lhs is also a MemberAccess/MethodCall to determine where we need + // to put a line and an indentation. + let mut increase_indentation = false; + + match member_access.lhs.kind { + ExpressionKind::MemberAccess(lhs_member_access) => { + group.group(self.format_member_access_impl( + *lhs_member_access, + true, // nested + group_tag, + )); + } + ExpressionKind::MethodCall(lhs_method_call) => { + group.group(self.format_method_call_impl( + *lhs_method_call, + true, // nested + group_tag, + )); + } + _ => { + self.format_expression(member_access.lhs, &mut group); + + increase_indentation = true; + } + }; + + group.trailing_comment(self.skip_comments_and_whitespace_chunk()); + + if increase_indentation { + group.increase_indentation(); + } + + group.line(); + + group.text(self.chunk(|formatter| { + formatter.write_token(Token::Dot); + formatter.write_identifier_or_integer(member_access.rhs); + })); + + if !nested { + group.pop_indentation(); + } + + group + } + + fn format_cast(&mut self, cast_expression: CastExpression) -> ChunkGroup { + let mut group = ChunkGroup::new(); + self.format_expression(cast_expression.lhs, &mut group); + group.text(self.chunk(|formatter| { + formatter.write_space(); + formatter.write_keyword(Keyword::As); + formatter.write_space(); + formatter.format_type(cast_expression.r#type); + })); + group + } + + fn format_prefix(&mut self, prefix: PrefixExpression) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.text(self.chunk(|formatter| { + if let UnaryOp::MutableReference = prefix.operator { + formatter.write_current_token(); + formatter.bump(); + formatter.skip_comments_and_whitespace(); + formatter.write_current_token(); + formatter.bump(); + formatter.write_space(); + } else { + formatter.write_current_token(); + formatter.bump(); + } + })); + self.format_expression(prefix.rhs, &mut group); + group + } + + fn format_infix_expression(&mut self, infix: InfixExpression) -> ChunkGroup { + let group_tag = self.new_group_tag(); + + let mut group = self.format_infix_expression_with_group_tag( + infix, group_tag, false, // nested + ); + group.force_multiline_on_children_with_same_tag_if_multiline = true; + group + } + + fn format_infix_expression_with_group_tag( + &mut self, + infix: InfixExpression, + group_tag: GroupTag, + nested: bool, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.tag = Some(group_tag); + + if !nested { + group.push_indentation(); + } + + // If we have code like `a + b + c + d`, that's always parsed as `((a + b) + c) + d` where each + // parentheses denotes an InfixExpression. So, if the lhs of the current infix expression is also + // an infix expression with the same operator, we format it with the same tag. + // If the lhs is not an infix expression or has a different operator, we format it normally, + // and afterwards signal an increase in indentation. That way if this infix expression has + // to be formatted in multiple lines, we'll only indent after the first operand + // (we still produce "space or line" after each operator). + let increase_indentation = match infix.lhs.kind { + ExpressionKind::Infix(lhs_infix) if lhs_infix.operator == infix.operator => { + group.group(self.format_infix_expression_with_group_tag( + *lhs_infix, group_tag, true, // nested + )); + false + } + _ => { + self.format_expression(infix.lhs, &mut group); + true + } + }; + + let mut comment_chunk_after_lhs = self.skip_comments_and_whitespace_chunk(); + + // If the comment is not empty but doesn't have newlines, it's surely `/* comment */`. + // We format that with spaces surrounding it so it looks like `a /* comment */ + b`. + if !comment_chunk_after_lhs.string.trim().is_empty() + && !comment_chunk_after_lhs.has_newlines + { + // Note: there's no space after `{}` because a bit below comes "space_or_line". + comment_chunk_after_lhs.string = format!(" {}", comment_chunk_after_lhs.string.trim()); + group.text(comment_chunk_after_lhs); + } else { + group.trailing_comment(comment_chunk_after_lhs); + } + + if increase_indentation { + group.increase_indentation(); + } + + group.space_or_line(); + group.text(self.chunk(|formatter| { + let tokens_count = + if infix.operator.contents == BinaryOpKind::ShiftRight { 2 } else { 1 }; + for _ in 0..tokens_count { + formatter.write_current_token(); + formatter.bump(); + } + formatter.write_space(); + })); + + self.format_expression(infix.rhs, &mut group); + + if !nested { + group.pop_indentation(); + } + + group + } + + pub(super) fn format_if_expression( + &mut self, + if_expression: IfExpression, + mut force_multiple_lines: bool, + ) -> ChunkGroup { + let group_tag = self.new_group_tag(); + let mut group = self.format_if_expression_with_group_tag( + if_expression, + &mut force_multiple_lines, + group_tag, + ); + + if force_multiple_lines || group.width() > self.config.single_line_if_else_max_width { + force_if_chunks_to_multiple_lines(&mut group, group_tag); + } + + group + } + + pub(super) fn format_if_expression_with_group_tag( + &mut self, + if_expression: IfExpression, + force_multiple_lines: &mut bool, + group_tag: GroupTag, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.tag = Some(group_tag); + + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::If); + formatter.write_space(); + })); + + self.format_expression(if_expression.condition, &mut group); + + let comment_chunk_after_condition = self.skip_comments_and_whitespace_chunk(); + if comment_chunk_after_condition.has_newlines { + *force_multiple_lines = true; + group.trailing_comment(comment_chunk_after_condition); + } else { + group.space(self); + } + + let ExpressionKind::Block(consequence_block) = if_expression.consequence.kind else { + panic!("Expected if expression consequence to be a block"); + }; + + if let Some(alternative) = &if_expression.alternative { + match &alternative.kind { + ExpressionKind::Block(block) => { + if block.statements.len() > 1 { + *force_multiple_lines = true; + } + } + ExpressionKind::If(..) => { + *force_multiple_lines = true; + } + _ => panic!("Unexpected if alternative expression kind"), + } + } + + let mut consequence_group = + self.format_block_expression(consequence_block, *force_multiple_lines); + consequence_group.tag = Some(group_tag); + group.group(consequence_group); + + if let Some(alternative) = if_expression.alternative { + group.text(self.chunk(|formatter| { + formatter.write_space(); + formatter.write_keyword(Keyword::Else); + })); + + let comment_chunk_after_else = self.skip_comments_and_whitespace_chunk(); + if comment_chunk_after_else.has_newlines { + *force_multiple_lines = true; + group.trailing_comment(comment_chunk_after_else); + } else { + group.space(self); + } + + let mut alternative_group = match alternative.kind { + ExpressionKind::Block(block) => { + self.format_block_expression(block, *force_multiple_lines) + } + ExpressionKind::If(if_expression) => self.format_if_expression_with_group_tag( + *if_expression, + force_multiple_lines, + group_tag, + ), + _ => panic!("Unexpected if alternative expression kind"), + }; + + alternative_group.tag = Some(group_tag); + group.group(alternative_group); + } + + group + } + + fn format_index_expression(&mut self, index: IndexExpression) -> ChunkGroup { + let mut group = ChunkGroup::new(); + self.format_expression(index.collection, &mut group); + group.text(self.chunk(|formatter| { + formatter.write_left_bracket(); + })); + + // If we have: + // + // foo[ // bar + // 1] + // + // and there were newlines in the comment section, we format it like this: + // + // foo[ + // // bar + // 1 + // ] + // + // That is, we first put a newline before the comment so it looks a bit better. + // This is a rare scenario, but we had a test for this before the formatter was + // rewritten, so... + let comments_chunk = self.skip_comments_and_whitespace_chunk(); + let comments_chunk_has_newlines = comments_chunk.has_newlines; + + if comments_chunk_has_newlines { + group.increase_indentation(); + group.line(); + } + + group.leading_comment(comments_chunk); + + self.format_expression(index.index, &mut group); + + if comments_chunk_has_newlines { + group.decrease_indentation(); + group.line(); + } + + group.text(self.chunk(|formatter| { + formatter.write_right_bracket(); + })); + group + } + + fn format_call(&mut self, call: CallExpression) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + self.format_expression(*call.func, &mut group); + + group.text(self.chunk(|formatter| { + if call.is_macro_call { + formatter.write_token(Token::Bang); + } + formatter.write_left_paren(); + })); + + group.kind = GroupKind::ExpressionList { + prefix_width: group.width(), + expressions_count: call.arguments.len(), + }; + + // Format arguments in a separate group so we can calculate the arguments + // width and determine if we need to format this call in multiple lines. + let mut args_group = ChunkGroup::new(); + self.format_expressions_separated_by_comma( + call.arguments, + false, // force trailing comma + &mut args_group, + ); + + if args_group.width() > self.config.fn_call_width { + group.force_multiple_lines = true; + } + + // We no longer need this subgroup, so put all its chunks into the main chunks + group.chunks.extend(args_group.chunks); + + group.text(self.chunk(|formatter| { + formatter.write_right_paren(); + })); + + group + } + + fn format_method_call(&mut self, method_call: MethodCallExpression) -> ChunkGroup { + let group_tag = self.new_group_tag(); + + let mut group = self.format_method_call_impl( + method_call, + false, // nested + group_tag, + ); + group.force_multiline_on_children_with_same_tag_if_multiline = true; + group + } + + fn format_method_call_impl( + &mut self, + method_call: MethodCallExpression, + nested: bool, + group_tag: GroupTag, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.tag = Some(group_tag); + + if !nested { + group.push_indentation(); + } + + // The logic here is similar to that of `format_member_access_with_group_tag`, so + // please that function inner comments for details. + let mut increase_indentation_before_dot = false; + + match method_call.object.kind { + ExpressionKind::MethodCall(lhs_method_call) => { + group.group(self.format_method_call_impl( + *lhs_method_call, + true, // nested + group_tag, + )); + } + ExpressionKind::MemberAccess(lhs_member_access) => { + group.group(self.format_member_access_impl( + *lhs_member_access, + true, // nested + group_tag, + )); + } + _ => { + self.format_expression(method_call.object, &mut group); + + increase_indentation_before_dot = true; + } + } + + group.trailing_comment(self.skip_comments_and_whitespace_chunk()); + + if increase_indentation_before_dot { + group.increase_indentation(); + } + + group.line(); + + group.text(self.chunk(|formatter| { + formatter.write_token(Token::Dot); + formatter.write_identifier(method_call.method_name); + if method_call.is_macro_call { + formatter.write_token(Token::Bang); + } + if let Some(generics) = method_call.generics { + formatter.format_turbofish(generics); + } + formatter.write_left_paren(); + })); + + group.kind = GroupKind::MethodCall { + width_until_left_paren_inclusive: group.width(), + has_newlines_before_left_paren: group.has_newlines(), + lhs: nested, + }; + + let mut args_group = ChunkGroup::new(); + args_group.kind = GroupKind::ExpressionList { + prefix_width: 0, + expressions_count: method_call.arguments.len(), + }; + self.format_expressions_separated_by_comma( + method_call.arguments, + false, // force trailing comma + &mut args_group, + ); + group.group(args_group); + + group.text(self.chunk(|formatter| { + formatter.write_right_paren(); + })); + + if !nested { + group.pop_indentation(); + } + + group + } + + pub(super) fn format_block_expression( + &mut self, + block: BlockExpression, + force_multiple_lines: bool, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.text(self.chunk(|formatter| { + formatter.write_left_brace(); + })); + self.format_block_expression_contents(block, force_multiple_lines, &mut group); + group.text(self.chunk(|formatter| { + formatter.write_right_brace(); + })); + group + } + + pub(super) fn format_block_expression_contents( + &mut self, + block: BlockExpression, + force_multiple_lines: bool, + group: &mut ChunkGroup, + ) { + if block.is_empty() { + if let Some(block_group) = self.empty_block_contents_chunk() { + group.chunks.extend(block_group.chunks); + } + } else { + self.format_non_empty_block_expression_contents(block, force_multiple_lines, group); + } + } + + pub(super) fn format_non_empty_block_expression_contents( + &mut self, + block: BlockExpression, + force_multiple_lines: bool, + group: &mut ChunkGroup, + ) { + group.force_multiple_lines = force_multiple_lines || block.statements.len() > 1; + let surround_with_spaces = !group.force_multiple_lines && block.statements.len() == 1; + + group.increase_indentation(); + if surround_with_spaces { + group.space_or_line(); + } else { + group.line(); + } + + for (index, statement) in block.statements.into_iter().enumerate() { + let mut ignore_next = false; + + if index > 0 { + let count = self.following_newlines_count(); + if count > 0 { + // If newlines follow, we first add a line, then add the comment chunk + group.lines(count > 1); + group.leading_comment(self.skip_comments_and_whitespace_chunk()); + ignore_next = self.ignore_next; + } else { + // Otherwise, add the comment first as it's a trailing comment + group.trailing_comment(self.skip_comments_and_whitespace_chunk()); + ignore_next = self.ignore_next; + group.line(); + } + } + + self.format_statement(statement, group, ignore_next); + } + + group.text(self.chunk(|formatter| { + formatter.skip_comments_and_whitespace(); + })); + + group.decrease_indentation(); + + if surround_with_spaces { + group.space_or_line(); + } else { + group.line(); + } + } + + pub(super) fn empty_block_contents_chunk(&mut self) -> Option { + let mut group = ChunkGroup::new(); + group.increase_indentation(); + let mut chunk = self.chunk(|formatter| { + formatter.skip_comments_and_whitespace_writing_multiple_lines_if_found(); + }); + + if chunk.string.trim().is_empty() { + // We only found whitespace until the next non-whitespace-non-comment token, + // so there's nothing to write. + None + } else { + if chunk.string.trim_start().starts_with("//") { + group.text(chunk); + group.decrease_indentation(); + group.line(); + } else { + chunk.string = format!(" {} ", chunk.string.trim()); + group.text(chunk); + group.decrease_indentation(); + } + Some(group) + } + } +} + +impl<'a> Formatter<'a> { + pub(super) fn format_empty_block_contents(&mut self) { + if let Some(chunks) = self.chunk_formatter().empty_block_contents_chunk() { + self.format_chunk_group(chunks); + } + } +} + +fn force_if_chunks_to_multiple_lines(group: &mut ChunkGroup, group_tag: GroupTag) { + if group.tag == Some(group_tag) { + group.force_multiple_lines = true; + } + + for chunk in group.chunks.iter_mut() { + if let Chunk::Group(inner_group) = chunk { + force_if_chunks_to_multiple_lines(inner_group, group_tag); + } + } +} + +#[cfg(test)] +mod tests { + use crate::{assert_format, assert_format_with_config, assert_format_with_max_width, Config}; + + #[test] + fn format_unit() { + let src = "global x = ( ) ;"; + let expected = "global x = ();\n"; + assert_format(src, expected); + } + + #[test] + fn format_false() { + let src = "global x = false ;"; + let expected = "global x = false;\n"; + assert_format(src, expected); + } + + #[test] + fn format_true() { + let src = "global x = true ;"; + let expected = "global x = true;\n"; + assert_format(src, expected); + } + + #[test] + fn format_integer() { + let src = "global x = 42 ;"; + let expected = "global x = 42;\n"; + assert_format(src, expected); + } + + #[test] + fn format_negative_integer() { + let src = "global x = - 42 ;"; + let expected = "global x = -42;\n"; + assert_format(src, expected); + } + + #[test] + fn format_ref_mut_integer() { + let src = "global x = & mut 42 ;"; + let expected = "global x = &mut 42;\n"; + assert_format(src, expected); + } + + #[test] + fn format_hex_integer() { + let src = "global x = 0xff ;"; + let expected = "global x = 0xff;\n"; + assert_format(src, expected); + } + + #[test] + fn format_string() { + let src = "global x = \"hello\" ;"; + let expected = "global x = \"hello\";\n"; + assert_format(src, expected); + } + + #[test] + fn format_fmtstr() { + let src = "global x = f\"hello\" ;"; + let expected = "global x = f\"hello\";\n"; + assert_format(src, expected); + } + + #[test] + fn format_standard_array() { + let src = "global x = [ 1 , 2 , 3 , ] ;"; + let expected = "global x = [1, 2, 3];\n"; + assert_format(src, expected); + } + + #[test] + fn format_standard_slice() { + let src = "global x = & [ 1 , 2 , 3 , ] ;"; + let expected = "global x = &[1, 2, 3];\n"; + assert_format(src, expected); + } + + #[test] + fn format_repeated_array() { + let src = "global x = [ 1 ; 3 ] ;"; + let expected = "global x = [1; 3];\n"; + assert_format(src, expected); + } + + #[test] + fn format_long_array_in_global() { + let src = "global x = [ 1 , 2 , 3 , 4, 5, ] ;"; + let expected = "global x = + [1, 2, 3, 4, 5]; +"; + assert_format_with_max_width(src, expected, 20); + } + + #[test] + fn format_long_array_in_global_in_mod() { + let src = "mod moo { mod bar { global x = [ 1 , 2 , 3 , 4, 5, ] ; } }"; + let expected = "mod moo { + mod bar { + global x = [ + 1, 2, 3, 4, + 5, + ]; + } +} +"; + assert_format_with_max_width(src, expected, 25); + } + + #[test] + fn format_long_array_in_global_2() { + let src = "global x = [ 1 , 2 , 3 , 4, 5, ] ; + +global y = 1; + "; + let expected = "global x = + [1, 2, 3, 4, 5]; + +global y = 1; +"; + assert_format_with_max_width(src, expected, 20); + } + + #[test] + fn format_very_long_array_in_global() { + let src = "global x = [ 1 , 2 , 3 , 4, 5, 6, 789, 123, 234, 345] ;"; + let expected = "global x = [ + 1, 2, 3, 4, 5, 6, + 789, 123, 234, 345, +]; +"; + assert_format_with_max_width(src, expected, 25); + } + + #[test] + fn format_long_array_element() { + let src = "global x = [ 123, 1234, 12345, 123, 1234, 12345, 123456, 123] ;"; + let expected = "global x = [ + 123, + 1234, + 12345, + 123, + 1234, + 12345, + 123456, + 123, +]; +"; + + let config = + Config { short_array_element_width_threshold: 5, max_width: 30, ..Default::default() }; + assert_format_with_config(src, expected, config); + } + + #[test] + fn format_cast() { + let src = "global x = 1 as u8 ;"; + let expected = "global x = 1 as u8;\n"; + assert_format(src, expected); + } + + #[test] + fn format_variable() { + let src = "global x = y ;"; + let expected = "global x = y;\n"; + assert_format(src, expected); + } + + #[test] + fn format_tuple() { + let src = "global x = ( 1 , 2 , 3 , ) ;"; + let expected = "global x = (1, 2, 3);\n"; + assert_format(src, expected); + } + + #[test] + fn format_tuple_length_one() { + let src = "global x = ( 1 , ) ;"; + let expected = "global x = (1,);\n"; + assert_format(src, expected); + } + + #[test] + fn format_as_trait_path() { + let src = "global x = < i32 as foo > :: bar ;"; + let expected = "global x = ::bar;\n"; + assert_format(src, expected); + } + + #[test] + fn format_index() { + let src = "global x = foo [ bar ] ;"; + let expected = "global x = foo[bar];\n"; + assert_format(src, expected); + } + + #[test] + fn format_long_index() { + let src = "global x = foo [ bar [ baz [ qux [ one [ two ]]]] ] ; global y = 1;"; + let expected = "global x = foo[bar[baz[ + qux[one[two]]]]]; +global y = 1; +"; + assert_format_with_max_width(src, expected, 25); + } + + #[test] + fn format_long_index_2() { + let src = "global x = foo [ bar ] [ baz ] [ qux ] [ one ] [ two ] ; global y = 1;"; + let expected = "global x = foo[bar][baz] + [qux][one][two]; +global y = 1; +"; + assert_format_with_max_width(src, expected, 25); + } + + #[test] + fn format_prefix() { + let src = "global x = - a ;"; + let expected = "global x = -a;\n"; + assert_format(src, expected); + } + + #[test] + fn format_infix() { + let src = "global x = a + b ;"; + let expected = "global x = a + b;\n"; + assert_format(src, expected); + } + + #[test] + fn format_long_infix_same_operator_1() { + let src = "global x = one + two + three;"; + let expected = "global x = one + + two + + three; +"; + assert_format_with_max_width(src, expected, "one + two + three".len() - 1); + } + + #[test] + fn format_long_infix_same_operator_2() { + let src = "global x = one + two + three + four;"; + let expected = "global x = one + + two + + three + + four; +"; + assert_format_with_max_width(src, expected, "one + two + three + four".len() - 1); + } + + #[test] + fn format_long_infix_same_operator_3() { + let src = "fn foo() { one + two + three + four }"; + let expected = "fn foo() { + one + + two + + three + + four +} +"; + assert_format_with_max_width(src, expected, "one + two + three + four".len() - 1); + } + + #[test] + fn format_empty_block() { + let src = "global x = { } ;"; + let expected = "global x = {};\n"; + assert_format(src, expected); + } + + #[test] + fn format_block_with_one_statement() { + let src = "global x = { 1 } ;"; + let expected = "global x = { 1 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_block_with_two_statements() { + let src = "global x = { 1; 2 } ;"; + let expected = "global x = { + 1; + 2 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_call() { + let src = "global x = foo :: bar ( 1, 2 ) ;"; + let expected = "global x = foo::bar(1, 2);\n"; + assert_format(src, expected); + } + + #[test] + fn format_call_with_turbofish() { + let src = "global x = foo :: bar :: < Field, i32 > ( 1, 2 ) ;"; + let expected = "global x = foo::bar::(1, 2);\n"; + assert_format(src, expected); + } + + #[test] + fn format_call_with_maximum_width() { + let src = "global x = foo :: bar ( 1, 2, 3 ) ;"; + let expected = "global x = foo::bar( + 1, + 2, + 3, +);\n"; + + let config = Config { fn_call_width: "1, 2, 3".len() - 1, ..Default::default() }; + assert_format_with_config(src, expected, config); + } + + #[test] + fn format_call_with_maximum_width_2() { + let src = "global x = foo::bar::baz( );"; + let expected = "global x = foo::bar::baz();\n"; + assert_format_with_max_width(src, expected, "foo::bar::baz".len() - 1); + } + + #[test] + fn format_nested_call_with_maximum_width() { + let src = "fn foo() { foo(bar(123, 456, 789)) } "; + let expected = "fn foo() { + foo(bar( + 123, + 456, + 789, + )) +} +"; + assert_format_with_max_width(src, expected, " foo(bar(".len()); + } + + #[test] + fn format_nested_call_with_maximum_width_2() { + let src = "fn foo() { + let note_interface_impl = s.as_type().get_trait_impl(quote { crate::note::note_interface::NoteInterface<$serialized_len_type> } + .as_trait_constraint()); +} +"; + let expected = "fn foo() { + let note_interface_impl = s.as_type().get_trait_impl( + quote { crate::note::note_interface::NoteInterface<$serialized_len_type> } + .as_trait_constraint(), + ); +} +"; + assert_format(src, expected); + } + + #[test] + fn format_nested_call_with_maximum_width_3() { + let src = "mod foo { + fn bar() { + assert(foo(bar.baz(x12345))); + } +} +"; + let expected = "mod foo { + fn bar() { + assert(foo(bar.baz( + x12345, + ))); + } +} +"; + assert_format_with_max_width(src, expected, 33); + } + + #[test] + fn format_nested_call_with_maximum_width_4() { + let src = "mod foo { + fn bar() { + assert(foo(bar_baz(x1, x2))); + } +} +"; + let expected = "mod foo { + fn bar() { + assert(foo(bar_baz( + x1, + x2, + ))); + } +} +"; + assert_format_with_max_width(src, expected, 33); + } + + #[test] + fn format_call_with_maximum_width_comma_exceeds() { + let src = "global x = foo::bar( + baz::qux(1, 2, 3), +);"; + let expected = "global x = foo::bar( + baz::qux( + 1, + 2, + 3, + ), +); +"; + assert_format_with_max_width(src, expected, " baz::qux(1, 2, 3),".len() - 1); + } + + #[test] + fn format_call_with_maximum_width_comma_exceeds_2() { + let src = "global x = foo::bar( + |x, y| { some_chunk_of_code }, +);"; + let expected = "global x = foo::bar(|x, y| { + some_chunk_of_code +}); +"; + assert_format_with_max_width(src, expected, " |x, y| { some_chunk_of_code },".len() - 1); + } + + #[test] + fn format_nested_call_max_width() { + let src = "global _callStackItem1 = context.call_public_function( + context.this_address(), + comptime { + FunctionSelector::from_signature(\"broadcast(Field)\") + }, + [owner] + );"; + let expected = "global _callStackItem1 = context.call_public_function( + context.this_address(), + comptime { FunctionSelector::from_signature(\"broadcast(Field)\") }, + [owner], +); +"; + assert_format(src, expected); + } + + #[test] + fn format_method_call() { + let src = "global x = bar . baz ( 1, 2 ) ;"; + let expected = "global x = bar.baz(1, 2);\n"; + assert_format(src, expected); + } + + #[test] + fn format_method_call_with_long_arguments() { + let src = "global x = bar . baz ( 123456789, 123456789, 123456789, 123456789, 123456789, 123456789, 123456789 ) ;"; + let expected = "global x = bar.baz( + 123456789, + 123456789, + 123456789, + 123456789, + 123456789, + 123456789, + 123456789, +); +"; + assert_format_with_max_width(src, expected, 40); + } + + #[test] + fn format_method_call_with_generics() { + let src = "global x = bar . baz :: < T > ( 1, 2 ) ;"; + let expected = "global x = bar.baz::(1, 2);\n"; + assert_format(src, expected); + } + + #[test] + fn format_method_call_chain() { + let src = "global x = bar . baz ( 1, 2 ) . qux ( 1 , 2, 3) . one ( 5, 6) ;"; + let expected = "global x = bar + .baz(1, 2) + .qux(1, 2, 3) + .one(5, 6); +"; + assert_format_with_max_width(src, expected, 25); + } + + #[test] + fn format_method_call_chain_2() { + let src = "fn foo() { bar . baz ( 1, 2 ) . qux ( 1 , 2, 3) . one ( 5, 6) }"; + let expected = "fn foo() { + bar.baz(1, 2).qux(1, 2, 3).one( + 5, + 6, + ) +} +"; + assert_format_with_max_width(src, expected, " bar.baz(1, 2).qux(1, 2, 3).one(".len()); + } + + #[test] + fn format_method_call_chain_3() { + let src = "fn foo() { assert(p4_affine.eq(Gaffine::new(6890855772600357754907169075114257697580319025794532037257385534741338397365, 4338620300185947561074059802482547481416142213883829469920100239455078257889))); }"; + let expected = "fn foo() { + assert(p4_affine.eq(Gaffine::new( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889, + ))); +} +"; + assert_format(src, expected); + } + + #[test] + fn format_method_call_with_maximum_width() { + let src = "global x = foo::bar.baz( );"; + let expected = "global x = foo::bar + .baz(); +"; + assert_format_with_max_width(src, expected, "foo::bar.baz".len() - 1); + } + + #[test] + fn format_nested_method_call_with_maximum_width() { + let src = "fn foo() { foo.bar(baz.qux(123, 456, 789)) } "; + let expected = "fn foo() { + foo.bar(baz.qux( + 123, + 456, + 789, + )) +} +"; + assert_format_with_max_width(src, expected, " foo.bar(bar.qux(".len()); + } + + #[test] + fn format_nested_method_call_with_maximum_width_2() { + let src = "fn foo() { + assert( + p4_affine.eq(Gaffine::new( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889, + )), + ); +} +"; + let expected = "fn foo() { + assert(p4_affine.eq(Gaffine::new( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889, + ))); +} +"; + assert_format(src, expected); + } + + #[test] + fn format_member_access() { + let src = "global x = bar . baz ;"; + let expected = "global x = bar.baz;\n"; + assert_format(src, expected); + } + + #[test] + fn format_long_member_access_alone() { + let src = "global x = foo . bar . baz . qux . final ;"; + let expected = "global x = foo + .bar + .baz + .qux + .final; +"; + assert_format_with_max_width(src, expected, "foo.bar.baz.qux.final".len() - 1); + } + + #[test] + fn format_long_member_access_and_method_call_chain() { + let src = "global x = foo . bar(1, 2) . baz . qux(2, 3) . this_is_a_long_name ;"; + let expected = "global x = foo + .bar(1, 2) + .baz + .qux(2, 3) + .this_is_a_long_name; +"; + assert_format_with_max_width(src, expected, 25); + } + + #[test] + fn format_long_member_access_and_method_call_chain_2() { + let src = "fn burn() { + storage + .at(from) + .sub(from_keys.npk_m, U128::from_integer(amount)) + .emit(encode_and_encrypt_note!()); +} +"; + let expected = "fn burn() { + storage.at(from).sub(from_keys.npk_m, U128::from_integer(amount)).emit( + encode_and_encrypt_note!(), + ); +} +"; + assert_format(src, expected); + } + + #[test] + fn format_tuple_member_access() { + let src = "global x = bar . 0 ;"; + let expected = "global x = bar.0;\n"; + assert_format(src, expected); + } + + #[test] + fn format_parenthesized() { + let src = "global x = ( 1 ) ;"; + let expected = "global x = (1);\n"; + assert_format(src, expected); + } + + #[test] + fn format_unsafe_one_expression() { + let src = "global x = unsafe { 1 } ;"; + let expected = "global x = unsafe { 1 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_unsafe_two_expressions() { + let src = "global x = unsafe { 1; 2 } ;"; + let expected = "global x = unsafe { + 1; + 2 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_comptime_one_expression() { + let src = "global x = comptime { 1 } ;"; + let expected = "global x = comptime { 1 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_comptime_two_expressions() { + let src = "global x = comptime { 1; 2 } ;"; + let expected = "global x = comptime { + 1; + 2 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_constructor() { + let src = "global x = Foo { } ;"; + let expected = "global x = Foo {};\n"; + assert_format(src, expected); + } + + #[test] + fn format_constructor() { + let src = "global x = Foo { one: 1 , two : 2 , three } ;"; + let expected = "global x = Foo { one: 1, two: 2, three };\n"; + assert_format(src, expected); + } + + #[test] + fn format_constructor_with_turbofish() { + let src = "global x = Foo :: < Bar > { one } ;"; + let expected = "global x = Foo:: { one };\n"; + assert_format(src, expected); + } + + #[test] + fn format_type_path() { + let src = "global x = Field :: max ;"; + let expected = "global x = Field::max;\n"; + assert_format(src, expected); + } + + #[test] + fn format_type_path_with_turbofish() { + let src = "global x = Field :: max :: < i32 > ;"; + let expected = "global x = Field::max::;\n"; + assert_format(src, expected); + } + + #[test] + fn format_if_expression_without_else_one_expression() { + let src = "global x = if 1 { 2 } ;"; + let expected = "global x = if 1 { 2 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_if_expression_without_else_two_expressions() { + let src = "global x = if 1 { 2; 3 } ;"; + let expected = "global x = if 1 { + 2; + 3 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_if_expression_with_else() { + let src = "global x = if 1 { 2 } else { 3 };"; + let expected = "global x = if 1 { 2 } else { 3 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_if_expression_with_else_multiple_exprs() { + let src = "global x = if 1 { 2 } else { 3; 4 };"; + let expected = "global x = if 1 { + 2 +} else { + 3; + 4 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_if_expression_else_if() { + let src = "global x = if 1 { 2 } else if 3 { 4 };"; + let expected = "global x = if 1 { + 2 +} else if 3 { + 4 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_if_with_configurable_maximum_if_width() { + let src = "global x = if 123 { 456 } else { 789 };"; + let expected = "global x = if 123 { + 456 +} else { + 789 +};\n"; + + let config = Config { + single_line_if_else_max_width: "if 123 { 456 } else { 789 }".len() - 1, + ..Config::default() + }; + assert_format_with_config(src, expected, config); + } + + #[test] + fn format_if_with_configurable_maximum_if_width_2() { + let src = "global x = if foo(123) { 456 } else { 789 };"; + let expected = "global x = if foo(123) { + 456 +} else { + 789 +};\n"; + + let config = Config { + single_line_if_else_max_width: "if foo(123) { 456 } else { 789 }".len() - 1, + ..Config::default() + }; + assert_format_with_config(src, expected, config); + } + + #[test] + fn format_quote() { + let src = "global x = quote { 1 2 3 $four $(five) };"; + let expected = "global x = quote { 1 2 3 $four $(five) };\n"; + assert_format(src, expected); + } + + #[test] + fn format_quote_with_newlines() { + let src = "fn foo() { + quote { + + foo + + bar + + } +} +"; + let expected = src; + assert_format(src, expected); + } + + #[test] + fn format_lambda_no_parameters() { + let src = "global x = | | 1 ;"; + let expected = "global x = || 1;\n"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_with_parameters() { + let src = "global x = | x , y : Field , z | 1 ;"; + let expected = "global x = |x, y: Field, z| 1;\n"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_with_block() { + let src = "global x = | | { 1 } ;"; + let expected = "global x = || { 1 };\n"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_with_block_multiple_statements() { + let src = "global x = | a, b | { 1; 2 } ;"; + let expected = "global x = |a, b| { + 1; + 2 +}; +"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_as_last_call_argument() { + let src = "global x = foo(1, |x| { 1; 2 });"; + let expected = "global x = foo(1, |x| { + 1; + 2 +}); +"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_as_last_method_call_argument() { + let src = "global x = foo.bar(1, |x| { 1; 2 });"; + let expected = "global x = foo.bar(1, |x| { + 1; + 2 +}); +"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_as_last_method_call_argument_2() { + let src = "fn foo(){ + m.structs().any(|s: StructDefinition| s.has_named_attribute(\"storage\") | s.has_named_attribute(\"storage_no_init\"), + ) +} +"; + let expected = "fn foo() { + m.structs().any(|s: StructDefinition| { + s.has_named_attribute(\"storage\") | s.has_named_attribute(\"storage_no_init\") + }) +} +"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_as_last_method_call_argument_3() { + let src = "mod moo { + fn foo() { + let mut sorted_write_tuples = unsafe { + get_sorted_tuple( + final_public_data_writes.storage, + |(_, leaf_a): (u32, PublicDataTreeLeaf), (_, leaf_b): (u32, PublicDataTreeLeaf)| full_field_less_than( + 1, 2, + ), + ) + }; + } +} +"; + let expected = "mod moo { + fn foo() { + let mut sorted_write_tuples = unsafe { + get_sorted_tuple( + final_public_data_writes.storage, + |(_, leaf_a): (u32, PublicDataTreeLeaf), (_, leaf_b): (u32, PublicDataTreeLeaf)| { + full_field_less_than(1, 2) + }, + ) + }; + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_as_last_method_call_chain_argument() { + let src = "global x = foo.bar(1).baz(2, |x| { 1; 2 });"; + let expected = "global x = foo.bar(1).baz(2, |x| { + 1; + 2 +}); +"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_as_last_method_call_chain_argument_2() { + let src = "fn foo() { expr.as_unsafe().map(|exprs| { a; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa }) } + "; + let expected = "fn foo() { + expr.as_unsafe().map(|exprs| { + a; + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + }) +} +"; + assert_format(src, expected); + } + + #[test] + fn format_lambda_as_last_method_call_has_to_wrap() { + let src = "global foo = bar(1, 2, 3, |argument| { 1; 2 });"; + let expected = "global foo = bar( + 1, + 2, + 3, + |argument| { + 1; + 2 + }, +); +"; + assert_format_with_max_width(src, expected, src.len() - 10); + } + + #[test] + fn removes_nested_parens() { + let src = "global x = ( ( ( ( ) ) ) ) ;"; + let expected = "global x = (());\n"; + assert_format(src, expected); + } + + #[test] + fn does_not_remove_nested_parens_if_not_told_so() { + let src = "global x = ( ( ( ( ) ) ) ) ;"; + let expected = "global x = (((())));\n"; + + let config = Config { remove_nested_parens: false, ..Config::default() }; + assert_format_with_config(src, expected, config); + } + + #[test] + fn attaches_comma_to_last_group() { + let src = " mod moo { + fn foo() { + [ + Foo { a: 1 }, Foo { a: 1 } + ]; + bar; + } +} +"; + let expected = "mod moo { + fn foo() { + [ + Foo { + a: 1, + }, + Foo { + a: 1, + }, + ]; + bar; + } +} +"; + assert_format_with_max_width(src, expected, " Foo { a: 1 },".len() - 1); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/function.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/function.rs new file mode 100644 index 00000000000..1dc9ead42e0 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/function.rs @@ -0,0 +1,538 @@ +use noirc_frontend::{ + ast::{ + BlockExpression, FunctionReturnType, Ident, ItemVisibility, NoirFunction, Param, + UnresolvedGenerics, UnresolvedTraitConstraint, Visibility, + }, + token::{Keyword, Token}, +}; + +use super::Formatter; +use crate::chunks::{ChunkGroup, TextChunk}; + +pub(super) struct FunctionToFormat { + pub(super) visibility: ItemVisibility, + pub(super) name: Ident, + pub(super) generics: UnresolvedGenerics, + pub(super) parameters: Vec, + pub(super) return_type: FunctionReturnType, + pub(super) return_visibility: Visibility, + pub(super) where_clause: Vec, + pub(super) body: Option, +} + +impl<'a> Formatter<'a> { + pub(super) fn format_function(&mut self, func: NoirFunction) { + self.format_function_impl(FunctionToFormat { + visibility: func.def.visibility, + name: func.def.name, + generics: func.def.generics, + parameters: func.def.parameters, + return_type: func.def.return_type, + return_visibility: func.def.return_visibility, + where_clause: func.def.where_clause, + body: Some(func.def.body), + }); + } + + pub(super) fn format_function_impl(&mut self, func: FunctionToFormat) { + let has_where_clause = !func.where_clause.is_empty(); + + self.format_attributes(); + self.write_indentation(); + self.format_function_modifiers(func.visibility); + self.write_keyword(Keyword::Fn); + self.write_space(); + self.write_identifier(func.name); + self.format_generics(func.generics); + self.write_left_paren(); + + // When the function has no parameters we can format everything in a single line + if func.parameters.is_empty() { + self.increase_indentation(); + self.skip_comments_and_whitespace(); + self.decrease_indentation(); + + let group = ChunkGroup::new(); + self.format_function_right_paren_until_left_brace_or_semicolon( + func.return_type, + func.return_visibility, + has_where_clause, + false, // has parameters + func.body.is_none(), // semicolon + group, + ); + } else { + let mut group = ChunkGroup::new(); + self.format_function_parameters(func.parameters, &mut group); + self.format_function_right_paren_until_left_brace_or_semicolon( + func.return_type, + func.return_visibility, + has_where_clause, + true, // has parameters + func.body.is_none(), // semicolon + group, + ); + } + + if has_where_clause { + self.format_where_clause( + func.where_clause, + func.body.is_some(), // write trailing comma and newline + ); + if func.body.is_some() { + self.write_left_brace(); + } else { + self.write_semicolon(); + } + } + + if let Some(body) = func.body { + self.format_function_body(body); + self.write_right_brace(); + } + } + + pub(super) fn format_function_modifiers(&mut self, visibility: ItemVisibility) { + // For backwards compatibility, unconstrained might come before visibility. + // We'll remember this but put it after the visibility. + let unconstrained = if self.is_at_keyword(Keyword::Unconstrained) { + self.bump(); + self.skip_comments_and_whitespace(); + true + } else { + false + }; + + self.format_item_visibility(visibility); + + if unconstrained { + self.write("unconstrained "); + } else if self.is_at_keyword(Keyword::Unconstrained) { + self.write_keyword(Keyword::Unconstrained); + self.write_space(); + } + + if self.is_at_keyword(Keyword::Comptime) { + self.write_keyword(Keyword::Comptime); + self.write_space(); + } + } + + pub(super) fn format_function_parameters( + &mut self, + parameters: Vec, + group: &mut ChunkGroup, + ) { + self.chunk_formatter().format_items_separated_by_comma( + parameters, + false, // force trailing comma + false, // surround with spaces + group, + |formatter, param, group| { + group.text(formatter.chunk(|formatter| { + formatter.format_function_param(param); + })); + }, + ); + } + + fn format_function_param(&mut self, param: Param) { + self.format_pattern(param.pattern); + self.skip_comments_and_whitespace(); + + // There might not be a colon if the parameter is self + if self.is_at(Token::Colon) { + self.write_token(Token::Colon); + self.write_space(); + self.format_visibility(param.visibility); + self.format_type(param.typ); + } + } + + /// Returns whether the left brace of semicolon was written + /// (we don't write it when there's a comment before those tokens) + pub(super) fn format_function_right_paren_until_left_brace_or_semicolon( + &mut self, + return_type: FunctionReturnType, + visibility: Visibility, + has_where_clause: bool, + has_parameters: bool, + semicolon: bool, + mut group: ChunkGroup, + ) { + let mut chunk_formatter = self.chunk_formatter(); + + group.text(chunk_formatter.chunk(|formatter| { + formatter.write_right_paren(); + formatter.format_function_return_type(return_type, visibility); + })); + + // The following code is a bit long because it takes into account three scenarios: + // + // 1. + // fn foo() -> Field {} + // + // 2. + // fn foo() -> Field // comment + // {} + // + // 3. + // fn foo() -> Field + // // comment + // {} + // + // We want to preserve the above formatting when there are trailing comments, + // possibly considering a trailing comment in the same line to count towards the + // maximum width of the line. + // + // For that, we take the comment chunk and depending on whether it has leading newlines + // or if it even exists we take different paths. + let comment_chunk = chunk_formatter.skip_comments_and_whitespace_chunk(); + let comment_chunk = TextChunk::new(comment_chunk.string.trim_end().to_string()); + + let comment_starts_with_newline = comment_chunk.string.trim_matches(' ').starts_with('\n'); + if comment_starts_with_newline { + // After the return type we found a newline and a comment. We want to format the group + // right away, then keep formatting everything else (at that point there's no need to + // use chunks anymore). + self.format_chunk_group(group); + + let mut comment_group = ChunkGroup::new(); + comment_group.text(comment_chunk); + self.format_chunk_group(comment_group); + self.write_line(); + + // If there's no where clause the left brace goes on the same line as the function signature + if !has_where_clause { + self.skip_stray_where_keyword(); + + if semicolon { + self.write_semicolon(); + } else { + self.write_left_brace(); + } + } + return; + } + + let wrote_comment = !comment_chunk.string.trim().is_empty(); + group.text(comment_chunk); + + // If there's no where clause the left brace goes on the same line as the function signature + if !has_where_clause { + group.text(chunk_formatter.chunk(|formatter| { + formatter.skip_stray_where_keyword(); + })); + } + + if !has_where_clause && !wrote_comment { + if semicolon { + group.semicolon(&mut chunk_formatter); + } else { + group.text(chunk_formatter.chunk(|formatter| { + formatter.write_space(); + formatter.write_left_brace(); + })); + } + } + + if has_parameters { + self.format_chunk_group(group); + } else { + self.format_chunk_group_in_one_line(group); + } + + if wrote_comment { + self.write_line(); + if semicolon { + self.write_semicolon(); + } else { + self.write_left_brace(); + } + } + } + + fn skip_stray_where_keyword(&mut self) { + // There might still be a where keyword that we'll remove + if self.is_at_keyword(Keyword::Where) { + self.bump(); + self.skip_comments_and_whitespace(); + } + } + + fn format_function_return_type( + &mut self, + return_type: FunctionReturnType, + visibility: Visibility, + ) { + match return_type { + FunctionReturnType::Default(..) => (), + FunctionReturnType::Ty(typ) => { + self.write_space(); + self.write_token(Token::Arrow); + self.write_space(); + self.format_visibility(visibility); + self.format_type(typ); + } + } + } + + pub(super) fn format_function_body(&mut self, body: BlockExpression) { + if body.is_empty() { + self.format_empty_block_contents(); + } else { + let mut group = ChunkGroup::new(); + self.chunk_formatter().format_non_empty_block_expression_contents( + body, true, // force multiple lines + &mut group, + ); + self.format_chunk_group(group); + } + } +} + +#[cfg(test)] +mod tests { + use crate::{assert_format, assert_format_with_max_width}; + + #[test] + fn format_simple_function() { + let src = "mod moo { + /// hello +#[attr] pub fn foo ( ) { } }"; + let expected = "mod moo { + /// hello + #[attr] + pub fn foo() {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_args() { + let src = "fn foo ( x: i32 , y:i32 , ) { } "; + let expected = "fn foo(x: i32, y: i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_args_that_exceed_max_width() { + let src = "fn foo ( this_is_long: i32 , like_really_long:i32 , ) { } "; + let expected = "fn foo( + this_is_long: i32, + like_really_long: i32, +) {}\n"; + assert_format_with_max_width(src, expected, 40); + } + + #[test] + fn format_function_with_modifiers() { + let src = "pub unconstrained comptime fn foo ( ) { }"; + let expected = "pub unconstrained comptime fn foo() {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_unconstrained_before_pub() { + let src = "unconstrained pub fn foo ( ) { }"; + let expected = "pub unconstrained fn foo() {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_generics() { + let src = "fn foo < A, B, >( ) { }"; + let expected = "fn foo() {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_return_type() { + let src = "fn foo( ) -> Field { }"; + let expected = "fn foo() -> Field {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_parameter_pub_visibility() { + let src = "fn foo( x : pub u8 ) { }"; + let expected = "fn foo(x: pub u8) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_parameter_calldata_visibility() { + let src = "fn foo( x : call_data ( 1 ) u8 ) { }"; + let expected = "fn foo(x: call_data(1) u8) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_parameter_return_data_visibility() { + let src = "fn foo( x : return_data u8 ) { }"; + let expected = "fn foo(x: return_data u8) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_return_visibility() { + let src = "fn foo( ) -> pub Field { }"; + let expected = "fn foo() -> pub Field {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_empty_where_clause() { + let src = "mod foo { fn foo( ) where { } } "; + let expected = "mod foo { + fn foo() {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_where_clause() { + let src = "mod foo { fn foo( ) where T : Foo , U : Bar { } } "; + let expected = "mod foo { + fn foo() + where + T: Foo, + U: Bar, + {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_where_clause_multiple_bounds() { + let src = "mod foo { fn foo( ) where T : Foo+Bar , U : Baz + Qux { } } "; + let expected = "mod foo { + fn foo() + where + T: Foo + Bar, + U: Baz + Qux, + {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_body() { + let src = "fn main() { 1; 2; 3 }"; + let expected = "fn main() { + 1; + 2; + 3 +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_body_newlines() { + let src = "fn main() { + + 1; + + 2; + + 3 + + }"; + let expected = "fn main() { + 1; + + 2; + + 3 +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_body_one_expr() { + let src = "mod moo { fn main() { 1 } }"; + let expected = "mod moo { + fn main() { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_empty_body_multiple_lines() { + let src = "fn foo() { + + }"; + let expected = "fn foo() {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_trailing_comment_in_same_line_before_left_brace() { + let src = "fn foo(x: Field) // comment + { + }"; + let expected = "fn foo(x: Field) // comment +{} +"; + assert_format(src, expected); + } + + #[test] + fn format_function_with_trailing_comment_in_separate_line_before_left_brace() { + let src = "fn foo(x: Field) + // comment + { + }"; + let expected = "fn foo(x: Field) +// comment +{} +"; + assert_format(src, expected); + } + + #[test] + fn format_long_function_signature_no_parameters() { + let src = "fn foo() -> Field {}"; + let expected = "fn foo() -> Field {}\n"; + assert_format_with_max_width(src, expected, 15); + } + + #[test] + fn does_not_format_function_if_there_is_a_directive_not_to() { + let src = "// noir-fmt:ignore +fn foo() { let x = 1 ; + } + +fn bar() { let y = 2 ; + } + +// noir-fmt:ignore +fn baz() { let z = 3 ; + } + +"; + let expected = "// noir-fmt:ignore +fn foo() { let x = 1 ; + } + +fn bar() { + let y = 2; +} + +// noir-fmt:ignore +fn baz() { let z = 3 ; + } + +"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/generics.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/generics.rs new file mode 100644 index 00000000000..4ee5a743942 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/generics.rs @@ -0,0 +1,96 @@ +use noirc_frontend::{ + ast::{GenericTypeArgKind, GenericTypeArgs, UnresolvedGeneric}, + token::{Keyword, Token}, +}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_generics(&mut self, generics: Vec) { + self.skip_comments_and_whitespace(); + + if self.token != Token::Less { + return; + } + + self.write_token(Token::Less); + for (index, generic) in generics.into_iter().enumerate() { + if index > 0 { + self.write_comma(); + self.write_space(); + } + self.format_generic(generic); + } + self.skip_comments_and_whitespace(); + + // Trailing comma + if self.is_at(Token::Comma) { + self.bump(); + } + + self.write_token(Token::Greater); + } + + fn format_generic(&mut self, generic: UnresolvedGeneric) { + self.skip_comments_and_whitespace(); + match generic { + UnresolvedGeneric::Variable(ident) => { + self.write_identifier(ident); + } + UnresolvedGeneric::Numeric { ident, typ } => { + self.write_keyword(Keyword::Let); + self.write_space(); + self.write_identifier(ident); + self.write_token(Token::Colon); + self.write_space(); + self.format_type(typ); + } + UnresolvedGeneric::Resolved(..) => { + unreachable!("Resolved generics should not be present in the AST") + } + } + } + + pub(super) fn format_generic_type_args(&mut self, mut generics: GenericTypeArgs) { + self.skip_comments_and_whitespace(); + if self.token != Token::Less { + return; + } + + self.write_token(Token::Less); + + for (index, kind) in generics.kinds.into_iter().enumerate() { + self.skip_comments_and_whitespace(); + + if index > 0 { + self.write_token(Token::Comma); + self.write_space(); + } + + match kind { + GenericTypeArgKind::Ordered => { + let typ = generics.ordered_args.remove(0); + self.format_type(typ); + } + GenericTypeArgKind::Named => { + let (name, typ) = generics.named_args.remove(0); + self.write_identifier(name); + self.write_space(); + self.write_token(Token::Assign); + self.write_space(); + self.format_type(typ); + } + } + } + + self.skip_comments_and_whitespace(); + + // Don't include a trailing comma if there is one + if self.is_at(Token::Comma) { + self.bump(); + self.skip_comments_and_whitespace(); + } + + self.write_token(Token::Greater); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/global.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/global.rs new file mode 100644 index 00000000000..783629c8e32 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/global.rs @@ -0,0 +1,102 @@ +use noirc_frontend::{ + ast::{ItemVisibility, LetStatement, Pattern}, + token::Keyword, +}; + +use super::Formatter; +use crate::chunks::{ChunkFormatter, ChunkGroup}; + +impl<'a> Formatter<'a> { + pub(super) fn format_global( + &mut self, + let_statement: LetStatement, + visibility: ItemVisibility, + ) { + let group = self.chunk_formatter().format_global(let_statement, visibility); + self.write_indentation(); + self.format_chunk_group(group); + } +} + +impl<'a, 'b> ChunkFormatter<'a, 'b> { + pub(super) fn format_global( + &mut self, + let_statement: LetStatement, + visibility: ItemVisibility, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.text(self.chunk(|formatter| { + formatter.format_item_visibility(visibility); + })); + + if let_statement.comptime { + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::Comptime); + formatter.write_space(); + })); + } + + let pattern = let_statement.pattern; + let pattern = match pattern { + Pattern::Identifier(..) => pattern, + Pattern::Mutable(pattern, _span, _) => { + // `mut global x` is represented in the AST with a mutable pattern. + // A mutable pattern would be `mut x` but here we have `mut global x`, + // so in that case we write `mut` now, then the pattern we'll write doesn't + // have the `mut` part. + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::Mut); + formatter.write_space(); + })); + + *pattern + } + Pattern::Tuple(..) | Pattern::Struct(..) | Pattern::Interned(..) => { + unreachable!("Global pattern cannot be a tuple, struct or interned") + } + }; + + group.group(self.format_let_or_global( + Keyword::Global, + pattern, + let_statement.r#type, + Some(let_statement.expression), + Vec::new(), // Attributes + )); + + group + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_global_without_type() { + let src = " pub global x = 1 ; "; + let expected = "pub global x = 1;\n"; + assert_format(src, expected); + } + + #[test] + fn format_global_with_type() { + let src = " pub global x : Field = 1 ; "; + let expected = "pub global x: Field = 1;\n"; + assert_format(src, expected); + } + + #[test] + fn format_comptime_global() { + let src = " pub comptime global x : Field = 1 ; "; + let expected = "pub comptime global x: Field = 1;\n"; + assert_format(src, expected); + } + + #[test] + fn format_comptime_mut_global() { + let src = " pub comptime mut global x : Field = 1 ; "; + let expected = "pub comptime mut global x: Field = 1;\n"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/impls.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/impls.rs new file mode 100644 index 00000000000..1c2c25c9200 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/impls.rs @@ -0,0 +1,123 @@ +use noirc_frontend::{ast::TypeImpl, token::Keyword}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_impl(&mut self, type_impl: TypeImpl) { + let has_where_clause = !type_impl.where_clause.is_empty(); + + self.write_indentation(); + self.write_keyword(Keyword::Impl); + self.format_generics(type_impl.generics); + self.write_space(); + self.format_type(type_impl.object_type); + + if has_where_clause { + self.format_where_clause( + type_impl.where_clause, + true, // write trailing comma and newline + ); + } else { + self.write_space(); + } + self.write_left_brace(); + + if type_impl.methods.is_empty() { + self.format_empty_block_contents(); + } else { + self.increase_indentation(); + self.write_line(); + + for (index, (documented_method, _span)) in type_impl.methods.into_iter().enumerate() { + if index > 0 { + self.write_line(); + } + + let doc_comments = documented_method.doc_comments; + let method = documented_method.item; + if !doc_comments.is_empty() { + self.format_outer_doc_comments(); + } + self.format_function(method); + } + + self.skip_comments_and_whitespace(); + self.decrease_indentation(); + self.write_line(); + self.write_indentation(); + } + + self.write_right_brace(); + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_empty_impl() { + let src = " mod moo { impl Foo { } }"; + let expected = "mod moo { + impl Foo {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_impl_with_generics() { + let src = " mod moo { impl < A, B > Foo < A, B > { } }"; + let expected = "mod moo { + impl Foo {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_impl_with_where_clause() { + let src = " mod moo { impl Foo where A: B { } }"; + let expected = "mod moo { + impl Foo + where + A: B, + {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_impl_with_functions() { + let src = " mod moo { impl Foo { +/// hello +pub fn foo () { 1 } + +/// world +pub ( crate ) fn bar () { + } + +fn one(self) {} +fn two(mut self) {} +fn three(&mut self) {} + } }"; + let expected = "mod moo { + impl Foo { + /// hello + pub fn foo() { + 1 + } + + /// world + pub(crate) fn bar() {} + + fn one(self) {} + fn two(mut self) {} + fn three(&mut self) {} + } +} +"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/item.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/item.rs new file mode 100644 index 00000000000..072f45278ee --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/item.rs @@ -0,0 +1,45 @@ +use noirc_frontend::parser::{Item, ItemKind}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_item(&mut self, item: Item, mut ignore_next: bool) { + self.skip_comments_and_whitespace(); + + ignore_next |= self.ignore_next; + + if !item.doc_comments.is_empty() { + self.format_outer_doc_comments(); + self.skip_comments_and_whitespace(); + } + + ignore_next |= self.ignore_next; + + if ignore_next { + self.write_and_skip_span_without_formatting(item.span); + return; + } + + match item.kind { + ItemKind::Import(use_tree, item_visibility) => { + self.format_import(use_tree, item_visibility); + } + ItemKind::Function(noir_function) => self.format_function(noir_function), + ItemKind::Struct(noir_struct) => self.format_struct(noir_struct), + ItemKind::Trait(noir_trait) => self.format_trait(noir_trait), + ItemKind::TraitImpl(noir_trait_impl) => self.format_trait_impl(noir_trait_impl), + ItemKind::Impl(type_impl) => self.format_impl(type_impl), + ItemKind::TypeAlias(noir_type_alias) => self.format_type_alias(noir_type_alias), + ItemKind::Global(let_statement, visibility) => { + self.format_global(let_statement, visibility); + } + ItemKind::ModuleDecl(module_declaration) => { + self.format_module_declaration(module_declaration); + } + ItemKind::Submodules(parsed_sub_module) => { + self.format_submodule(parsed_sub_module); + } + ItemKind::InnerAttribute(..) => self.format_inner_attribute(), + } + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/lvalue.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/lvalue.rs new file mode 100644 index 00000000000..15fb7f5fa26 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/lvalue.rs @@ -0,0 +1,44 @@ +use noirc_frontend::{ast::LValue, token::Token}; + +use super::Formatter; +use crate::chunks::ChunkGroup; + +impl<'a> Formatter<'a> { + pub(super) fn format_lvalue(&mut self, lvalue: LValue) { + // Parenthesized l-values exist but are not represented in the AST + while let Token::LeftParen = self.token { + self.write_left_paren(); + } + + match lvalue { + LValue::Ident(ident) => self.write_identifier(ident), + LValue::MemberAccess { object, field_name, span: _ } => { + self.format_lvalue(*object); + self.write_token(Token::Dot); + self.write_identifier_or_integer(field_name); + } + LValue::Index { array, index, span: _ } => { + self.format_lvalue(*array); + self.write_left_bracket(); + let mut group = ChunkGroup::new(); + self.chunk_formatter().format_expression(index, &mut group); + self.format_chunk_group(group); + self.write_right_bracket(); + } + LValue::Dereference(lvalue, _span) => { + self.write_token(Token::Star); + self.format_lvalue(*lvalue); + } + LValue::Interned(..) => { + unreachable!("Should not be present in the AST") + } + } + + self.skip_comments_and_whitespace(); + + // Parenthesized l-values exist but are not represented in the AST + while let Token::RightParen = self.token { + self.write_right_paren(); + } + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/module.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/module.rs new file mode 100644 index 00000000000..00ac9fe2f47 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/module.rs @@ -0,0 +1,142 @@ +use noirc_frontend::{ + ast::ModuleDeclaration, parser::ParsedSubModule, token::Keyword, ParsedModule, +}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_module_declaration(&mut self, module_declaration: ModuleDeclaration) { + if !module_declaration.outer_attributes.is_empty() { + self.format_attributes(); + } + self.write_indentation(); + self.format_item_visibility(module_declaration.visibility); + self.write_keyword(Keyword::Mod); + self.write_space(); + self.write_identifier(module_declaration.ident); + self.write_semicolon(); + } + + pub(super) fn format_submodule(&mut self, submodule: ParsedSubModule) { + if !submodule.outer_attributes.is_empty() { + self.format_attributes(); + } + self.write_indentation(); + self.format_item_visibility(submodule.visibility); + if submodule.is_contract { + self.write_keyword(Keyword::Contract); + } else { + self.write_keyword(Keyword::Mod); + } + self.write_space(); + self.write_identifier(submodule.name); + self.write_space(); + if parsed_module_is_empty(&submodule.contents) { + self.write_left_brace(); + self.increase_indentation(); + + let comments_count_before = self.written_comments_count; + self.skip_comments_and_whitespace_writing_multiple_lines_if_found(); + self.decrease_indentation(); + if self.written_comments_count > comments_count_before { + self.write_line(); + self.write_indentation(); + } + self.write_right_brace(); + } else { + self.write_left_brace(); + self.increase_indentation(); + self.write_line(); + self.format_parsed_module(submodule.contents, self.ignore_next); + self.decrease_indentation(); + self.write_indentation(); + self.write_right_brace(); + } + } +} + +fn parsed_module_is_empty(parsed_module: &ParsedModule) -> bool { + parsed_module.inner_doc_comments.is_empty() && parsed_module.items.is_empty() +} + +#[cfg(test)] +mod tests { + use crate::{assert_format, assert_format_with_config, Config}; + + #[test] + fn format_module_declaration() { + let src = " mod foo ; "; + let expected = "mod foo;\n"; + assert_format(src, expected); + } + + #[test] + fn format_module_declaration_with_doc_comments() { + let src = " /// hello +/// world +mod foo ; "; + let expected = "/// hello +/// world +mod foo;\n"; + assert_format(src, expected); + } + + #[test] + fn format_module_declaration_with_pub_visibility() { + let src = " pub mod foo ;"; + let expected = "pub mod foo;\n"; + assert_format(src, expected); + } + + #[test] + fn format_module_declaration_with_pub_crate_visibility() { + let src = " pub ( crate ) mod foo ;"; + let expected = "pub(crate) mod foo;\n"; + assert_format(src, expected); + } + + #[test] + fn format_empty_submodule() { + let src = "mod foo { }"; + let expected = "mod foo {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_empty_subcontract() { + let src = "contract foo { }"; + let expected = "contract foo {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_multiple_modules() { + let src = " mod foo { +// hello +mod bar { +// world +} +} "; + let expected = "mod foo { + // hello + mod bar { + // world + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_submodule_with_configurable_tab_spaces() { + let src = " mod foo { + mod bar ; + }"; + let expected = "mod foo { + mod bar; +} +"; + let config = Config { tab_spaces: 2, ..Config::default() }; + assert_format_with_config(src, expected, config); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/path.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/path.rs new file mode 100644 index 00000000000..2a46467bf72 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/path.rs @@ -0,0 +1,59 @@ +use noirc_frontend::{ + ast::{Path, PathKind, UnresolvedType}, + token::{Keyword, Token}, +}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_path(&mut self, path: Path) { + self.skip_comments_and_whitespace(); + + match path.kind { + PathKind::Plain => (), + PathKind::Crate => { + self.write_keyword(Keyword::Crate); + self.write_token(Token::DoubleColon); + } + PathKind::Dep => { + self.write_keyword(Keyword::Dep); + self.write_token(Token::DoubleColon); + } + PathKind::Super => { + self.write_keyword(Keyword::Super); + self.write_token(Token::DoubleColon); + } + } + + for (index, segment) in path.segments.into_iter().enumerate() { + if index > 0 { + self.write_token(Token::DoubleColon); + } + self.write_identifier(segment.ident); + + if let Some(generics) = segment.generics { + self.format_turbofish(generics); + } + } + } + + pub(super) fn format_turbofish(&mut self, generics: Vec) { + self.write_token(Token::DoubleColon); + self.write_token(Token::Less); + for (index, typ) in generics.into_iter().enumerate() { + if index > 0 { + self.write_comma(); + self.write_space(); + } + self.format_type(typ); + } + + // Skip trailing comma, if any + self.skip_comments_and_whitespace(); + if self.is_at(Token::Comma) { + self.bump(); + } + + self.write_token(Token::Greater); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/pattern.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/pattern.rs new file mode 100644 index 00000000000..9a76612109b --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/pattern.rs @@ -0,0 +1,162 @@ +use noirc_frontend::{ + ast::{Ident, Pattern}, + token::{Keyword, Token}, +}; + +use super::Formatter; +use crate::chunks::ChunkGroup; + +impl<'a> Formatter<'a> { + pub(super) fn format_pattern(&mut self, pattern: Pattern) { + self.skip_comments_and_whitespace(); + + // Special case: `&mut self` (this is reflected in the param type, not the pattern) + if self.is_at(Token::Ampersand) { + self.write_token(Token::Ampersand); + self.write_keyword(Keyword::Mut); + self.write_space(); + } + + match pattern { + Pattern::Identifier(ident) => self.write_identifier(ident), + Pattern::Mutable(pattern, _span, _) => { + self.write_keyword(Keyword::Mut); + self.write_space(); + self.format_pattern(*pattern); + } + Pattern::Tuple(patterns, _span) => { + let patterns_len = patterns.len(); + + self.write_left_paren(); + for (index, pattern) in patterns.into_iter().enumerate() { + if index > 0 { + self.write_comma(); + self.write_space(); + } + self.format_pattern(pattern); + } + + // Check for trailing comma + self.skip_comments_and_whitespace(); + if self.is_at(Token::Comma) { + if patterns_len == 1 { + self.write_comma(); + } else { + self.bump(); + } + } + + self.write_right_paren(); + } + Pattern::Struct(path, fields, _span) => { + self.format_path(path); + self.write_space(); + self.write_left_brace(); + if fields.is_empty() { + self.format_empty_block_contents(); + } else { + let mut group = ChunkGroup::new(); + self.chunk_formatter().format_items_separated_by_comma( + fields, + false, // force trailing comma, + true, // surround with spaces + &mut group, + |formatter, (name, pattern), chunks| { + let is_identifier_pattern = is_identifier_pattern(&pattern, &name); + + chunks.text(formatter.chunk(|formatter| { + formatter.write_identifier(name); + formatter.skip_comments_and_whitespace(); + })); + if formatter.is_at(Token::Colon) { + let value_chunk = formatter.chunk(|formatter| { + formatter.write_token(Token::Colon); + formatter.write_space(); + formatter.format_pattern(pattern); + }); + if !is_identifier_pattern { + chunks.text(value_chunk); + } + } + }, + ); + self.format_chunk_group(group); + } + + self.write_right_brace(); + } + Pattern::Interned(..) => { + unreachable!("Should not be present in the AST") + } + } + } +} + +fn is_identifier_pattern(pattern: &Pattern, ident: &Ident) -> bool { + if let Pattern::Identifier(pattern_ident) = pattern { + pattern_ident == ident + } else { + false + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_identifier_pattern() { + let src = "fn foo( x : i32) {}"; + let expected = "fn foo(x: i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_mutable_pattern() { + let src = "fn foo( mut x : i32) {}"; + let expected = "fn foo(mut x: i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_tuple_pattern_no_trailing_comma() { + let src = "fn foo( ( x , y ) : i32) {}"; + let expected = "fn foo((x, y): i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_tuple_pattern_trailing_comma() { + let src = "fn foo( ( x , y , ) : i32) {}"; + let expected = "fn foo((x, y): i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_tuple_pattern_one_element() { + let src = "fn foo( ( x , ) : i32) {}"; + let expected = "fn foo((x,): i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_struct_pattern_empty() { + let src = "fn foo( Foo { } : i32) {}"; + let expected = "fn foo(Foo {}: i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_struct_pattern() { + let src = "fn foo( Foo { x : one , y : two } : i32) {}"; + let expected = "fn foo(Foo { x: one, y: two }: i32) {}\n"; + assert_format(src, expected); + } + + #[test] + fn format_struct_pattern_no_pattern() { + let src = "fn foo( Foo { x , y : y } : i32) {}"; + let expected = "fn foo(Foo { x, y }: i32) {}\n"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs new file mode 100644 index 00000000000..036066e346f --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/statement.rs @@ -0,0 +1,682 @@ +use noirc_frontend::{ + ast::{ + AssignStatement, ConstrainKind, ConstrainStatement, Expression, ExpressionKind, + ForLoopStatement, ForRange, LetStatement, Pattern, Statement, StatementKind, + UnresolvedType, UnresolvedTypeData, + }, + token::{Keyword, SecondaryAttribute, Token}, +}; + +use crate::chunks::{ChunkFormatter, ChunkGroup, GroupKind}; + +impl<'a, 'b> ChunkFormatter<'a, 'b> { + pub(super) fn format_statement( + &mut self, + statement: Statement, + group: &mut ChunkGroup, + mut ignore_next: bool, + ) { + group.leading_comment(self.skip_comments_and_whitespace_chunk()); + + ignore_next |= self.ignore_next; + + if ignore_next { + group.text(self.chunk(|formatter| { + formatter.write_and_skip_span_without_formatting(statement.span); + })); + return; + } + + match statement.kind { + StatementKind::Let(let_statement) => { + group.group(self.format_let_statement(let_statement)); + } + StatementKind::Constrain(constrain_statement) => { + group.group(self.format_constrain_statement(constrain_statement)); + } + StatementKind::Expression(expression) => match expression.kind { + ExpressionKind::Block(block) => group.group(self.format_block_expression( + block, true, // force multiple lines + )), + ExpressionKind::Unsafe(block, _) => { + group.group(self.format_unsafe_expression( + block, true, // force multiple lines + )); + } + ExpressionKind::If(if_expression) => { + group.group(self.format_if_expression( + *if_expression, + true, // force multiple lines + )); + } + _ => self.format_expression(expression, group), + }, + StatementKind::Assign(assign_statement) => { + group.group(self.format_assign(assign_statement)); + } + StatementKind::For(for_loop_statement) => { + group.group(self.format_for_loop(for_loop_statement)); + } + StatementKind::Break => { + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::Break); + formatter.write_semicolon(); + })); + } + StatementKind::Continue => { + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::Continue); + formatter.write_semicolon(); + })); + } + StatementKind::Comptime(statement) => { + group.group(self.format_comptime_statement(*statement)); + } + StatementKind::Semi(expression) => { + group.group(self.format_semi_statement(expression)); + } + StatementKind::Interned(..) | StatementKind::Error => { + unreachable!("Should not be present in the AST") + } + } + } + + fn format_let_statement(&mut self, let_statement: LetStatement) -> ChunkGroup { + self.format_let_or_global( + Keyword::Let, + let_statement.pattern, + let_statement.r#type, + Some(let_statement.expression), + let_statement.attributes, + ) + } + + pub(super) fn format_let_or_global( + &mut self, + keyword: Keyword, + pattern: Pattern, + typ: UnresolvedType, + value: Option, + attributes: Vec, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + group.text(self.chunk(|formatter| { + if !attributes.is_empty() { + formatter.format_attributes(); + } + formatter.write_keyword(keyword); + formatter.write_space(); + formatter.format_pattern(pattern); + if typ.typ != UnresolvedTypeData::Unspecified { + formatter.write_token(Token::Colon); + formatter.write_space(); + formatter.format_type(typ); + } + })); + + if let Some(value) = value { + group.text(self.chunk(|formatter| { + formatter.write_space(); + formatter.write_token(Token::Assign); + formatter.write_space(); + })); + + let mut value_group = ChunkGroup::new(); + value_group.kind = GroupKind::AssignValue; + self.format_expression(value, &mut value_group); + value_group.semicolon(self); + group.group(value_group); + } else { + group.semicolon(self); + } + + group + } + + fn format_constrain_statement( + &mut self, + constrain_statement: ConstrainStatement, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + let keyword = match constrain_statement.kind { + ConstrainKind::Assert => Keyword::Assert, + ConstrainKind::AssertEq => Keyword::AssertEq, + ConstrainKind::Constrain => { + unreachable!("constrain always produces an error, and the formatter doesn't run when there are errors") + } + }; + + group.text(self.chunk(|formatter| { + formatter.write_keyword(keyword); + formatter.write_left_paren(); + })); + + group.kind = GroupKind::ExpressionList { + prefix_width: group.width(), + expressions_count: constrain_statement.arguments.len(), + }; + + self.format_expressions_separated_by_comma( + constrain_statement.arguments, + false, // force trailing comma + &mut group, + ); + + group.text(self.chunk(|formatter| { + formatter.write_right_paren(); + formatter.write_semicolon(); + })); + + group + } + + fn format_assign(&mut self, assign_statement: AssignStatement) -> ChunkGroup { + let mut group = ChunkGroup::new(); + let mut is_op_assign = false; + + group.text(self.chunk(|formatter| { + formatter.format_lvalue(assign_statement.lvalue); + formatter.write_space(); + if formatter.is_at(Token::Assign) { + formatter.write_token(Token::Assign); + } else { + while formatter.token != Token::Assign { + formatter.write_current_token(); + formatter.bump(); + formatter.skip_comments_and_whitespace(); + } + formatter.write_token(Token::Assign); + is_op_assign = true; + } + formatter.write_space(); + })); + + let mut value_group = ChunkGroup::new(); + value_group.kind = GroupKind::AssignValue; + + if is_op_assign { + let ExpressionKind::Infix(infix) = assign_statement.expression.kind else { + panic!("Expected an infix expression for op assign"); + }; + self.format_expression(infix.rhs, &mut value_group); + } else { + self.format_expression(assign_statement.expression, &mut value_group); + } + value_group.semicolon(self); + group.group(value_group); + + group + } + + fn format_for_loop(&mut self, for_loop: ForLoopStatement) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::For); + formatter.write_space(); + formatter.write_identifier(for_loop.identifier); + formatter.write_space(); + formatter.write_keyword(Keyword::In); + formatter.write_space(); + })); + + match for_loop.range { + ForRange::Range(for_bounds) => { + self.format_expression(for_bounds.start, &mut group); + group.text(self.chunk(|formatter| { + formatter.skip_comments_and_whitespace(); + formatter.write_current_token(); + formatter.bump(); + })); + self.format_expression(for_bounds.end, &mut group); + } + ForRange::Array(expression) => { + self.format_expression(expression, &mut group); + } + } + + group.space(self); + + let ExpressionKind::Block(block) = for_loop.block.kind else { + panic!("Expected a block expression for for loop body"); + }; + + group.group(self.format_block_expression( + block, true, // force multiple lines + )); + + // If there's a trailing semicolon, remove it + group.text(self.chunk(|formatter| { + formatter.skip_whitespace_if_it_is_not_a_newline(); + if formatter.is_at(Token::Semicolon) { + formatter.bump(); + } + })); + + group + } + + fn format_comptime_statement(&mut self, statement: Statement) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + // A comptime statement can be a let, a block or a for. + // We always want to force multiple lines except for let. + group.force_multiple_lines = !matches!(statement.kind, StatementKind::Let(..)); + + group.text(self.chunk(|formatter| { + formatter.write_keyword(Keyword::Comptime); + formatter.write_space(); + })); + self.format_statement( + statement, &mut group, false, // ignore next + ); + group + } + + fn format_semi_statement(&mut self, expression: Expression) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + self.format_expression(expression, &mut group); + + group.text(self.chunk(|formatter| { + formatter.skip_comments_and_whitespace(); + })); + + group.semicolon(self); + + group + } +} + +#[cfg(test)] +mod tests { + use crate::{assert_format, assert_format_with_max_width}; + + #[test] + fn format_expression_statement() { + let src = " fn foo() { 1 } "; + let expected = "fn foo() { + 1 +} +"; + assert_format(src, expected); + } + + #[test] + fn format_semi_statement() { + let src = " fn foo() { 1 ; } "; + let expected = "fn foo() { + 1; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_break_statement() { + let src = " fn foo() { break ; } "; + let expected = "fn foo() { + break; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_continue_statement() { + let src = " fn foo() { continue ; } "; + let expected = "fn foo() { + continue; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_let_statement_no_type() { + let src = " fn foo() { let x = 1 ; } "; + let expected = "fn foo() { + let x = 1; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_let_statement_with_type() { + let src = " fn foo() { let x : Field = 1 ; } "; + let expected = "fn foo() { + let x: Field = 1; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_let_statement_with_attribute() { + let src = " fn foo() { #[allow(unused_variables)] let x = 1 ; } "; + let expected = "fn foo() { + #[allow(unused_variables)] + let x = 1; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_assign() { + let src = " fn foo() { x = 2 ; } "; + let expected = "fn foo() { + x = 2; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_assign_to_member() { + let src = " fn foo() { x . y = 2 ; } "; + let expected = "fn foo() { + x.y = 2; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_assign_to_tuple_member() { + let src = " fn foo() { x . 0 = 2 ; } "; + let expected = "fn foo() { + x.0 = 2; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_assign_to_index() { + let src = " fn foo() { x [ y ] = 2 ; } "; + let expected = "fn foo() { + x[y] = 2; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_assign_to_dereference() { + let src = " fn foo() { * x = 2 ; } "; + let expected = "fn foo() { + *x = 2; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_assign_with_parentheses() { + let src = " fn foo() { ( array[0] )[1] = 2; } "; + let expected = "fn foo() { + (array[0])[1] = 2; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_op_assign() { + let src = " fn foo() { x + = 2 ; } "; + let expected = "fn foo() { + x += 2; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_comptime_let_statement() { + let src = " fn foo() { comptime let x = 1 ; } "; + let expected = "fn foo() { + comptime let x = 1; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_block_statement() { + let src = " fn foo() { { } } "; + let expected = "fn foo() { + {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_block_statement() { + let src = " fn foo() { { 1 ; 2 } } "; + let expected = "fn foo() { + { + 1; + 2 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_unsafe_statement() { + let src = " fn foo() { unsafe { 1 } } "; + let expected = "fn foo() { + unsafe { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_comptime_statement_one_statement() { + let src = " fn foo() { comptime { 1 } } "; + let expected = "fn foo() { + comptime { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_comptime_block_statement() { + let src = " fn foo() { comptime { 1 ; 2 } } "; + let expected = "fn foo() { + comptime { + 1; + 2 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_for_array() { + let src = " fn foo() { for x in array { 1 } } "; + let expected = "fn foo() { + for x in array { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_for_array_trailing_semicolon() { + let src = " fn foo() { for x in array { 1 } ; } "; + let expected = "fn foo() { + for x in array { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_for_range_exclusive() { + let src = " fn foo() { for x in 1 .. 10 { 1 } } "; + let expected = "fn foo() { + for x in 1..10 { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_for_range_inclusive() { + let src = " fn foo() { for x in 1 ..= 10 { 1 } } "; + let expected = "fn foo() { + for x in 1..=10 { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_two_for_separated_by_multiple_lines() { + let src = " fn foo() { for x in array { 1 } + + for x in array { 1 } + + } "; + let expected = "fn foo() { + for x in array { + 1 + } + + for x in array { + 1 + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_assert() { + let src = r#" fn foo() { assert ( true , "hello" ) ; } "#; + let expected = r#"fn foo() { + assert(true, "hello"); +} +"#; + assert_format(src, expected); + } + + #[test] + fn format_assert_eq() { + let src = r#" fn foo() { assert ( 1 , 2 , "hello" ) ; } "#; + let expected = r#"fn foo() { + assert(1, 2, "hello"); +} +"#; + assert_format(src, expected); + } + + #[test] + fn format_if_statement() { + let src = r#" fn foo() { if 1 { 2 } } "#; + let expected = r#"fn foo() { + if 1 { + 2 + } +} +"#; + assert_format(src, expected); + } + + #[test] + fn does_not_format_statement_if_there_is_a_directive_not_to() { + let src = "fn foo() { + // noir-fmt:ignore + let x = + 1 ; + + let y = + 2 ; + + // noir-fmt:ignore + let z = + 3 ; +}\n"; + let expected = "fn foo() { + // noir-fmt:ignore + let x = + 1 ; + + let y = 2; + + // noir-fmt:ignore + let z = + 3 ; +}\n"; + assert_format(src, expected); + } + + #[test] + fn attaches_semicolon_to_last_group_in_let_statement() { + let src = "fn foo() { + let x = foo(1, 2); +} +"; + let expected = "fn foo() { + let x = + foo(1, 2); +} +"; + assert_format_with_max_width(src, expected, " let x = foo(1, 2);".len() - 1); + } + + #[test] + fn attaches_semicolon_to_last_group_in_semi_statement() { + let src = "fn foo() { + foo(1, 2, 3, 4, 5); +} +"; + let expected = "fn foo() { + foo( + 1, + 2, + 3, + 4, + 5, + ); +} +"; + assert_format_with_max_width(src, expected, " foo(1, 2, 3, 4, 5);".len() - 1); + } + + #[test] + fn attaches_semicolon_to_last_group_in_assign() { + let src = "fn foo() { + a_long_variable = foo(1, 2); +} +"; + let expected = "fn foo() { + a_long_variable = + foo(1, 2); +} +"; + assert_format_with_max_width(src, expected, " a_long_variable = foo(1, 2);".len() - 1); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/structs.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/structs.rs new file mode 100644 index 00000000000..54bfc88264d --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/structs.rs @@ -0,0 +1,200 @@ +use noirc_frontend::{ + ast::NoirStruct, + token::{Keyword, Token}, +}; + +use super::Formatter; +use crate::chunks::ChunkGroup; + +impl<'a> Formatter<'a> { + pub(super) fn format_struct(&mut self, noir_struct: NoirStruct) { + if !noir_struct.attributes.is_empty() { + self.format_attributes(); + } + self.write_indentation(); + self.format_item_visibility(noir_struct.visibility); + self.write_keyword(Keyword::Struct); + self.write_space(); + self.write_identifier(noir_struct.name); + self.format_generics(noir_struct.generics); + self.skip_comments_and_whitespace(); + + // A case like `struct Foo;` + if self.is_at(Token::Semicolon) { + self.write_semicolon(); + return; + } + + // A case like `struct Foo { ... }` + self.write_space(); + self.write_left_brace(); + + if noir_struct.fields.is_empty() { + self.format_empty_block_contents(); + } else { + self.increase_indentation(); + self.write_line(); + + for (index, documented_field) in noir_struct.fields.into_iter().enumerate() { + if index > 0 { + self.write_comma(); + self.write_line(); + } + + let doc_comments = documented_field.doc_comments; + if !doc_comments.is_empty() { + self.format_outer_doc_comments(); + } + + let field = documented_field.item; + self.write_indentation(); + self.format_item_visibility(field.visibility); + self.write_identifier(field.name); + self.write_token(Token::Colon); + self.write_space(); + self.format_type(field.typ); + } + + // Take the comment chunk so we can put it after a trailing comma we add, in case there's no comma + let mut group = ChunkGroup::new(); + let mut comments_and_whitespace_chunk = + self.chunk_formatter().skip_comments_and_whitespace_chunk(); + comments_and_whitespace_chunk.string = + comments_and_whitespace_chunk.string.trim_end().to_string(); + group.text(comments_and_whitespace_chunk); + + if self.is_at(Token::Comma) { + self.bump(); + } + self.write(","); + + self.format_chunk_group(group); + self.skip_comments_and_whitespace(); + + self.decrease_indentation(); + self.write_line(); + self.write_indentation(); + } + + self.write_right_brace(); + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_empty_struct_semicolon() { + let src = " mod moo { + /// hello + #[foo] pub ( crate ) struct Foo ; }"; + let expected = "mod moo { + /// hello + #[foo] + pub(crate) struct Foo; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_struct_with_generics() { + let src = " mod moo { struct Foo < A, B, let N : u32 > ; }"; + let expected = "mod moo { + struct Foo; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_struct_with_fields() { + let src = " mod moo { struct Foo { +// hello +/// comment + pub field : Field , + // comment +pub another : ( ), + } }"; + let expected = "mod moo { + struct Foo { + // hello + /// comment + pub field: Field, + // comment + pub another: (), + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_struct_with_multiple_newlines() { + let src = " mod moo { + + + struct Foo { + + +x: Field , + + +y: Field + + +} + + +}"; + let expected = "mod moo { + + struct Foo { + + x: Field, + + y: Field, + } + +} +"; + assert_format(src, expected); + } + + #[test] + fn format_two_structs() { + let src = " struct Foo { } struct Bar {} + "; + let expected = "struct Foo {} +struct Bar {} +"; + assert_format(src, expected); + } + + #[test] + fn format_struct_field_without_trailing_comma_but_comment() { + let src = "struct Foo { + field: Field // comment + }"; + let expected = "struct Foo { + field: Field, // comment +} +"; + assert_format(src, expected); + } + + #[test] + fn format_comment_after_last_struct_field() { + let src = "struct Foo { + field: Field + /* comment */ + }"; + let expected = "struct Foo { + field: Field, + /* comment */ +} +"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/trait_impl.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/trait_impl.rs new file mode 100644 index 00000000000..73d9a61b3d4 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/trait_impl.rs @@ -0,0 +1,218 @@ +use noirc_frontend::{ + ast::{ + FunctionDefinition, ItemVisibility, NoirFunction, NoirTraitImpl, Pattern, TraitImplItem, + TraitImplItemKind, + }, + token::{Keyword, Token}, +}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_trait_impl(&mut self, trait_impl: NoirTraitImpl) { + let has_where_clause = !trait_impl.where_clause.is_empty(); + + self.write_indentation(); + self.write_keyword(Keyword::Impl); + self.format_generics(trait_impl.impl_generics); + self.write_space(); + self.format_path(trait_impl.trait_name); + self.format_generic_type_args(trait_impl.trait_generics); + self.write_space(); + self.write_keyword(Keyword::For); + self.write_space(); + self.format_type(trait_impl.object_type); + + if has_where_clause { + self.format_where_clause( + trait_impl.where_clause, + true, // write trailing comma and newline + ); + } else { + self.write_space(); + } + self.write_left_brace(); + + if trait_impl.items.is_empty() { + self.format_empty_block_contents(); + } else { + self.increase_indentation(); + self.write_line(); + + for (index, documented_item) in trait_impl.items.into_iter().enumerate() { + if index > 0 { + self.write_line(); + } + + let doc_comments = documented_item.doc_comments; + let item = documented_item.item; + if !doc_comments.is_empty() { + self.format_outer_doc_comments(); + } + self.format_trait_impl_item(item); + } + + self.skip_comments_and_whitespace(); + self.decrease_indentation(); + self.write_line(); + self.write_indentation(); + } + + self.write_right_brace(); + } + + fn format_trait_impl_item(&mut self, item: TraitImplItem) { + match item.kind { + TraitImplItemKind::Function(noir_function) => { + // Trait impl functions are public, but there's no `pub` keyword in the source code, + // so to format it we pass a private one. + let def = + FunctionDefinition { visibility: ItemVisibility::Private, ..noir_function.def }; + let noir_function = NoirFunction { def, ..noir_function }; + self.format_function(noir_function); + } + TraitImplItemKind::Constant(name, typ, value) => { + let pattern = Pattern::Identifier(name); + let chunks = self.chunk_formatter().format_let_or_global( + Keyword::Let, + pattern, + typ, + Some(value), + Vec::new(), // Attributes + ); + + self.write_indentation(); + self.format_chunk_group(chunks); + } + TraitImplItemKind::Type { name, alias } => { + self.write_indentation(); + self.write_keyword(Keyword::Type); + self.write_space(); + self.write_identifier(name); + self.write_space(); + self.write_token(Token::Assign); + self.write_space(); + self.format_type(alias); + self.write_semicolon(); + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_empty_trait_impl() { + let src = " mod moo { impl Foo for Bar { } }"; + let expected = "mod moo { + impl Foo for Bar {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_trait_impl_with_trait_generics() { + let src = " mod moo { impl Foo < T > for Bar { } }"; + let expected = "mod moo { + impl Foo for Bar {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_trait_impl_with_impl_generics() { + let src = " mod moo { impl Default for Option { +} }"; + let expected = "mod moo { + impl Default for Option {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_trait_impl_with_where_clause() { + let src = " mod moo { impl Foo < T > for Bar where T : Baz { } }"; + let expected = "mod moo { + impl Foo for Bar + where + T: Baz, + {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_trait_impl_with_where_clause_with_trait_bound_generics() { + let src = "impl Into for U where T: From { }"; + let expected = "impl Into for U +where + T: From, +{} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_impl_function() { + let src = " mod moo { impl Foo for Bar { + /// Some doc comment +fn foo ( ) { } + } }"; + let expected = "mod moo { + impl Foo for Bar { + /// Some doc comment + fn foo() {} + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_impl_constant_without_type() { + let src = " mod moo { impl Foo for Bar { + let X =42 ; + } }"; + let expected = "mod moo { + impl Foo for Bar { + let X = 42; + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_impl_constant_with_type() { + let src = " mod moo { impl Foo for Bar { + let X : i32=42 ; + } }"; + let expected = "mod moo { + impl Foo for Bar { + let X: i32 = 42; + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_impl_type() { + let src = " mod moo { impl Foo for Bar { + type X = i32 ; + } }"; + let expected = "mod moo { + impl Foo for Bar { + type X = i32; + } +} +"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/traits.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/traits.rs new file mode 100644 index 00000000000..1379596b483 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/traits.rs @@ -0,0 +1,298 @@ +use noirc_frontend::{ + ast::{NoirTrait, Param, Pattern, TraitItem, Visibility}, + token::{Keyword, Token}, +}; + +use super::{function::FunctionToFormat, Formatter}; + +impl<'a> Formatter<'a> { + pub(super) fn format_trait(&mut self, noir_trait: NoirTrait) { + if !noir_trait.attributes.is_empty() { + self.format_attributes(); + } + self.write_indentation(); + self.format_item_visibility(noir_trait.visibility); + self.write_keyword(Keyword::Trait); + self.write_space(); + self.write_identifier(noir_trait.name); + self.format_generics(noir_trait.generics); + + if !noir_trait.bounds.is_empty() { + self.skip_comments_and_whitespace(); + self.write_token(Token::Colon); + self.write_space(); + + for (index, trait_bound) in noir_trait.bounds.into_iter().enumerate() { + if index > 0 { + self.write_space(); + self.write_token(Token::Plus); + self.write_space(); + } + self.format_trait_bound(trait_bound); + } + } + + if !noir_trait.where_clause.is_empty() { + self.format_where_clause(noir_trait.where_clause, true); + } + + self.write_space(); + self.write_left_brace(); + if noir_trait.items.is_empty() { + self.increase_indentation(); + self.skip_comments_and_whitespace(); + self.decrease_indentation(); + } else { + self.increase_indentation(); + self.write_line(); + + for (index, documented_item) in noir_trait.items.into_iter().enumerate() { + if index > 0 { + self.write_line(); + } + + let doc_comments = documented_item.doc_comments; + let item = documented_item.item; + if !doc_comments.is_empty() { + self.format_outer_doc_comments(); + } + self.format_trait_item(item); + } + + self.skip_comments_and_whitespace(); + self.decrease_indentation(); + self.write_line(); + self.write_indentation(); + } + self.write_right_brace(); + } + + fn format_trait_item(&mut self, item: TraitItem) { + match item { + TraitItem::Function { + is_unconstrained: _, + visibility, + is_comptime: _, + name, + generics, + parameters, + return_type, + where_clause, + body, + } => { + let parameters = parameters + .into_iter() + .map(|(name, typ)| Param { + visibility: Visibility::Private, + pattern: Pattern::Identifier(name), + typ, + span: Default::default(), // Doesn't matter + }) + .collect(); + + let func = FunctionToFormat { + visibility, + name, + generics, + parameters, + return_type, + return_visibility: Visibility::Private, + where_clause, + body, + }; + self.format_function_impl(func); + } + TraitItem::Constant { name, typ, default_value } => { + let pattern = Pattern::Identifier(name); + let chunks = self.chunk_formatter().format_let_or_global( + Keyword::Let, + pattern, + typ, + default_value, + Vec::new(), // Attributes + ); + self.write_indentation(); + self.format_chunk_group(chunks); + } + TraitItem::Type { name } => { + self.write_indentation(); + self.write_keyword(Keyword::Type); + self.write_space(); + self.write_identifier(name); + self.write_semicolon(); + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::assert_format; + + #[test] + fn format_empty_trait() { + let src = " mod moo { /// Comment + pub trait Foo { } }"; + let expected = "mod moo { + /// Comment + pub trait Foo {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_empty_trait_with_generics() { + let src = " mod moo { trait Foo < A, B, > { } }"; + let expected = "mod moo { + trait Foo {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_parents() { + let src = " mod moo { trait Foo : Bar + Baz { } }"; + let expected = "mod moo { + trait Foo: Bar + Baz {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_where_clause() { + let src = " mod moo { trait Foo < T > where T : Bar { } }"; + let expected = "mod moo { + trait Foo + where + T: Bar, + {} +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_type() { + let src = " mod moo { trait Foo { + /// hello + type X; + } }"; + let expected = "mod moo { + trait Foo { + /// hello + type X; + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_constant_no_value() { + let src = " mod moo { trait Foo { + let x : i32 ; + } }"; + let expected = "mod moo { + trait Foo { + let x: i32; + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_constant_with_value() { + let src = " mod moo { trait Foo { + let x : i32 = 1 ; + } }"; + let expected = "mod moo { + trait Foo { + let x: i32 = 1; + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_function_without_body() { + let src = " mod moo { trait Foo { + /// hello + pub fn foo ( ); + } }"; + let expected = "mod moo { + trait Foo { + /// hello + pub fn foo(); + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_function_with_body() { + let src = " mod moo { trait Foo { + /// hello + pub fn foo ( ) { 1 } + } }"; + let expected = "mod moo { + trait Foo { + /// hello + pub fn foo() { + 1 + } + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_function_with_params() { + let src = " mod moo { trait Foo { + /// hello + pub fn foo ( x : i32 , y : Field ); + } }"; + let expected = "mod moo { + trait Foo { + /// hello + pub fn foo(x: i32, y: Field); + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_trait_with_function_with_where_clause() { + let src = " mod moo { trait Foo { + fn foo () where T : Bar; + } }"; + let expected = "mod moo { + trait Foo { + fn foo() + where + T: Bar; + } +} +"; + assert_format(src, expected); + } + + #[test] + fn format_multiple_traits() { + let src = " trait Foo {} + + trait Bar {}"; + let expected = "trait Foo {} + +trait Bar {} +"; + assert_format(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/type_expression.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/type_expression.rs new file mode 100644 index 00000000000..87ba1430f10 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/type_expression.rs @@ -0,0 +1,40 @@ +use noirc_frontend::{ast::UnresolvedTypeExpression, token::Token}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_type_expression(&mut self, type_expr: UnresolvedTypeExpression) { + self.skip_comments_and_whitespace(); + + // Parenthesized type expressions exist but are not represented in the AST + while let Token::LeftParen = self.token { + self.write_left_paren(); + } + + match type_expr { + UnresolvedTypeExpression::Variable(path) => self.format_path(path), + UnresolvedTypeExpression::Constant(..) => { + self.write_current_token(); + self.bump(); + } + UnresolvedTypeExpression::BinaryOperation(lhs, _operator, rhs, _span) => { + self.format_type_expression(*lhs); + self.write_space(); + self.write_current_token(); + self.bump(); + self.write_space(); + self.format_type_expression(*rhs); + } + UnresolvedTypeExpression::AsTraitPath(..) => { + unreachable!("Should not be present in the AST") + } + } + + self.skip_comments_and_whitespace(); + + // Parenthesized type expressions exist but are not represented in the AST + while let Token::RightParen = self.token { + self.write_right_paren(); + } + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/types.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/types.rs new file mode 100644 index 00000000000..d2b5c4ab793 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/types.rs @@ -0,0 +1,355 @@ +use noirc_frontend::{ + ast::{AsTraitPath, UnresolvedType, UnresolvedTypeData}, + token::{Keyword, Token}, +}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_type(&mut self, typ: UnresolvedType) { + self.skip_comments_and_whitespace(); + + match typ.typ { + UnresolvedTypeData::Unit => { + self.write_left_paren(); + self.write_right_paren(); + } + UnresolvedTypeData::Bool => { + self.write_keyword(Keyword::Bool); + } + UnresolvedTypeData::Integer(..) | UnresolvedTypeData::FieldElement => { + self.write_current_token(); + self.bump(); + } + UnresolvedTypeData::Array(type_expr, typ) => { + self.write_left_bracket(); + self.format_type(*typ); + self.write_semicolon(); + self.write_space(); + self.format_type_expression(type_expr); + self.write_right_bracket(); + } + UnresolvedTypeData::Slice(typ) => { + self.write_left_bracket(); + self.format_type(*typ); + self.write_right_bracket(); + } + UnresolvedTypeData::Expression(type_expr) => { + self.format_type_expression(type_expr); + } + UnresolvedTypeData::String(type_expr) => { + self.write_keyword(Keyword::String); + self.write_token(Token::Less); + self.format_type_expression(type_expr); + self.write_token(Token::Greater); + } + UnresolvedTypeData::FormatString(type_expr, typ) => { + self.write_keyword(Keyword::FormatString); + self.write_token(Token::Less); + self.format_type_expression(type_expr); + self.write_comma(); + self.write_space(); + self.format_type(*typ); + self.write_token(Token::Greater); + } + UnresolvedTypeData::Parenthesized(typ) => { + self.write_left_paren(); + self.format_type(*typ); + self.write_right_paren(); + } + UnresolvedTypeData::Named(path, generic_type_args, _) => { + self.format_path(path); + if !generic_type_args.is_empty() { + self.skip_comments_and_whitespace(); + + // Apparently some Named types with generics have `::` before the generics + // while others don't, so we have to account for both cases. + if self.is_at(Token::DoubleColon) { + self.write_token(Token::DoubleColon); + } + self.format_generic_type_args(generic_type_args); + } + } + UnresolvedTypeData::TraitAsType(path, generic_type_args) => { + self.write_keyword(Keyword::Impl); + self.write_space(); + self.format_path(path); + self.format_generic_type_args(generic_type_args); + } + UnresolvedTypeData::MutableReference(typ) => { + self.write_token(Token::Ampersand); + self.write_keyword(Keyword::Mut); + self.write_space(); + self.format_type(*typ); + } + UnresolvedTypeData::Tuple(types) => { + let types_len = types.len(); + + self.write_left_paren(); + for (index, typ) in types.into_iter().enumerate() { + if index > 0 { + self.write_comma(); + self.write_space(); + } + self.format_type(typ); + } + + self.skip_comments_and_whitespace(); + if self.is_at(Token::Comma) { + if types_len == 1 { + self.write_comma(); + } else { + self.bump(); + } + } + + self.write_right_paren(); + } + UnresolvedTypeData::Function(args, return_type, env, unconstrained) => { + if unconstrained { + self.write_keyword(Keyword::Unconstrained); + self.write_space(); + } + + self.write_keyword(Keyword::Fn); + self.skip_comments_and_whitespace(); + + if self.is_at(Token::LeftBracket) { + self.write_left_bracket(); + self.format_type(*env); + self.write_right_bracket(); + } + + self.write_left_paren(); + for (index, arg) in args.into_iter().enumerate() { + if index > 0 { + self.write_comma(); + self.write_space(); + } + self.format_type(arg); + } + + self.skip_comments_and_whitespace(); + // Remove trailing comma if there's one + if self.is_at(Token::Comma) { + self.bump(); + } + + self.write_right_paren(); + self.skip_comments_and_whitespace(); + if self.is_at(Token::Arrow) { + self.write_space(); + self.write_token(Token::Arrow); + self.write_space(); + self.format_type(*return_type); + } + } + UnresolvedTypeData::Quoted(..) => { + self.write_current_token(); + self.bump(); + } + UnresolvedTypeData::AsTraitPath(as_trait_path) => { + self.format_as_trait_path(*as_trait_path); + } + UnresolvedTypeData::Resolved(..) + | UnresolvedTypeData::Interned(..) + | UnresolvedTypeData::Error => unreachable!("Should not be present in the AST"), + UnresolvedTypeData::Unspecified => panic!("Unspecified type should have been handled"), + } + } + + pub(super) fn format_as_trait_path(&mut self, as_trait_path: AsTraitPath) { + self.write_token(Token::Less); + self.format_type(as_trait_path.typ); + self.write_space(); + self.write_keyword(Keyword::As); + self.write_space(); + self.format_path(as_trait_path.trait_path); + self.format_generic_type_args(as_trait_path.trait_generics); + self.write_token(Token::Greater); + self.write_token(Token::DoubleColon); + self.write_identifier(as_trait_path.impl_item); + } +} + +#[cfg(test)] +mod tests { + use noirc_frontend::parser; + + use crate::Config; + + fn assert_format_type(src: &str, expected: &str) { + let module_src = format!("type X = {};", src); + let (parsed_module, errors) = parser::parse_program(&module_src); + if !errors.is_empty() { + panic!("Expected no errors, got: {:?}", errors); + } + let result = crate::format(&module_src, parsed_module, &Config::default()); + let type_result = &result["type X = ".len()..]; + let type_result = &type_result[..type_result.len() - 2]; + similar_asserts::assert_eq!(type_result, expected); + + let (parsed_module, errors) = parser::parse_program(&result); + if !errors.is_empty() { + panic!("Expected no errors in idempotent check, got: {:?}", errors); + } + let result = crate::format(&result, parsed_module, &Config::default()); + let type_result = &result["type X = ".len()..]; + let type_result = &type_result[..type_result.len() - 2]; + similar_asserts::assert_eq!(type_result, expected); + } + + #[test] + fn format_unit_type() { + let src = " ( ) "; + let expected = "()"; + assert_format_type(src, expected); + } + + #[test] + fn format_bool_type() { + let src = " bool "; + let expected = "bool"; + assert_format_type(src, expected); + } + + #[test] + fn format_integer_type() { + let src = " i32 "; + let expected = "i32"; + assert_format_type(src, expected); + } + + #[test] + fn format_named_type() { + let src = " foo :: bar :: Baz "; + let expected = "foo::bar::Baz"; + assert_format_type(src, expected); + } + + #[test] + fn format_named_type_with_generics() { + let src = " foo :: bar < A, B = Field , C = i32 , D , >"; + let expected = "foo::bar"; + assert_format_type(src, expected); + } + + #[test] + fn format_array_type_with_constant() { + let src = " [ Field ; 1 ] "; + let expected = "[Field; 1]"; + assert_format_type(src, expected); + } + + #[test] + fn format_array_type_with_var() { + let src = " [ Field ; LEN ] "; + let expected = "[Field; LEN]"; + assert_format_type(src, expected); + } + + #[test] + fn format_array_type_with_binary() { + let src = " [ Field ; 1+2 ] "; + let expected = "[Field; 1 + 2]"; + assert_format_type(src, expected); + } + + #[test] + fn format_array_type_with_parenthesized() { + let src = " [ Field ; ( 1 + 2 ) * ( 3 + 4 ) ] "; + let expected = "[Field; (1 + 2) * (3 + 4)]"; + assert_format_type(src, expected); + } + + #[test] + fn format_slice_type() { + let src = " [ Field ] "; + let expected = "[Field]"; + assert_format_type(src, expected); + } + + #[test] + fn format_mutable_reference_type() { + let src = " & mut Field "; + let expected = "&mut Field"; + assert_format_type(src, expected); + } + + #[test] + fn format_parenthesized_type() { + let src = " ( Field )"; + let expected = "(Field)"; + assert_format_type(src, expected); + } + + #[test] + fn format_simple_function_type() { + let src = " fn ( ) -> Field "; + let expected = "fn() -> Field"; + assert_format_type(src, expected); + } + + #[test] + fn format_function_type_with_args_and_unconstrained() { + let src = " unconstrained fn ( Field , i32 , ) -> Field "; + let expected = "unconstrained fn(Field, i32) -> Field"; + assert_format_type(src, expected); + } + + #[test] + fn format_function_type_with_env() { + let src = " fn [ Env ] ( ) -> Field "; + let expected = "fn[Env]() -> Field"; + assert_format_type(src, expected); + } + + #[test] + fn format_tuple_type_one_type() { + let src = " ( Field , )"; + let expected = "(Field,)"; + assert_format_type(src, expected); + } + + #[test] + fn format_tuple_type_two_types() { + let src = " ( Field , i32 , )"; + let expected = "(Field, i32)"; + assert_format_type(src, expected); + } + + #[test] + fn format_trait_as_type() { + let src = " impl Foo < Bar > "; + let expected = "impl Foo"; + assert_format_type(src, expected); + } + + #[test] + fn format_string_type() { + let src = "str < 6 >"; + let expected = "str<6>"; + assert_format_type(src, expected); + } + + #[test] + fn format_fmtstr_type() { + let src = "fmtstr < 6, ( ) >"; + let expected = "fmtstr<6, ()>"; + assert_format_type(src, expected); + } + + #[test] + fn format_quoted_type() { + let src = " Expr "; + let expected = "Expr"; + assert_format_type(src, expected); + } + + #[test] + fn format_as_trait_path_type() { + let src = " < Field as foo :: Bar> :: baz "; + let expected = "::baz"; + assert_format_type(src, expected); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs new file mode 100644 index 00000000000..0c99bc7ee79 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/use_tree.rs @@ -0,0 +1,204 @@ +use noirc_frontend::{ + ast::{ItemVisibility, UseTree, UseTreeKind}, + token::{Keyword, Token}, +}; + +use crate::chunks::{Chunk, ChunkFormatter, ChunkGroup}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_import(&mut self, use_tree: UseTree, visibility: ItemVisibility) { + let group = self.chunk_formatter().format_import(use_tree, visibility); + + self.write_indentation(); + self.format_chunk_group(group); + } +} + +impl<'a, 'b> ChunkFormatter<'a, 'b> { + pub(super) fn format_import( + &mut self, + use_tree: UseTree, + visibility: ItemVisibility, + ) -> ChunkGroup { + let mut group = ChunkGroup::new(); + + group.text(self.chunk(|formatter| { + formatter.format_item_visibility(visibility); + formatter.write_keyword(Keyword::Use); + formatter.write_space(); + })); + + group.group(self.format_use_tree(use_tree)); + group.semicolon(self); + + group + } + + fn format_use_tree(&mut self, use_tree: UseTree) -> ChunkGroup { + let mut group = ChunkGroup::new(); + group.one_chunk_per_line = false; + + if !use_tree.prefix.is_empty() { + group.text(self.chunk(|formatter| { + let has_segments = !use_tree.prefix.segments.is_empty(); + + formatter.format_path(use_tree.prefix); + + // If the path has segments, like in `foo` or `crate::foo`, we need to add a double colon. + // But for example for `crate::` we don't need to add a double colon (there are no segments + // and `crate::` was already written). + if has_segments { + formatter.write_token(Token::DoubleColon); + } + })); + } + + match use_tree.kind { + UseTreeKind::Path(name, alias) => { + group.text(self.chunk(|formatter| { + formatter.write_identifier(name); + if let Some(alias) = alias { + formatter.write_space(); + formatter.write_keyword(Keyword::As); + formatter.write_space(); + formatter.write_identifier(alias); + } + })); + } + UseTreeKind::List(use_trees) => { + let use_trees_len = use_trees.len(); + + let left_brace_chunk = self.chunk(|formatter| { + formatter.write_left_brace(); + }); + + let comments_count_before = self.written_comments_count; + + let mut items_chunk = ChunkGroup::new(); + self.format_items_separated_by_comma( + use_trees, + false, // force trailing comma + false, // surround with spaces + &mut items_chunk, + |formatter, use_tree, chunks| chunks.group(formatter.format_use_tree(use_tree)), + ); + + let wrote_comment = self.written_comments_count > comments_count_before; + + let right_brace_chunk = self.chunk(|formatter| { + formatter.write_right_brace(); + }); + + if use_trees_len == 1 && !wrote_comment { + // We are only interested in keeping the single Group: everything else + // is lines, indentation and trailing comma that we don't need and would + // actually produce incorrect code. + let single_group = + items_chunk.chunks.into_iter().filter_map(Chunk::group).next().unwrap(); + group.chunks.extend(single_group.chunks); + } else { + group.text(left_brace_chunk); + group.chunks.extend(items_chunk.chunks); + group.text(right_brace_chunk); + } + } + } + + group + } +} + +#[cfg(test)] +mod tests { + use crate::{assert_format, assert_format_with_max_width}; + + #[test] + fn format_simple_use() { + let src = " mod moo { pub use foo ; }"; + let expected = "mod moo { + pub use foo; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_simple_use_with_alias() { + let src = " mod moo { use foo :: bar as baz ; }"; + let expected = "mod moo { + use foo::bar as baz; +} +"; + assert_format(src, expected); + } + + #[test] + fn format_simple_use_with_path_kind() { + let src = "use super :: foo ;"; + let expected = "use super::foo;\n"; + assert_format(src, expected); + } + + #[test] + fn format_use_list_two_items() { + let src = " use foo::{ bar, baz };"; + let expected = "use foo::{bar, baz};\n"; + assert_format(src, expected); + } + + #[test] + fn format_use_trees_with_max_width() { + let src = " use foo::{ bar, baz , qux , one::{two, three} };"; + let expected = "use foo::{ + bar, baz, qux, + one::{ + two, three, + }, +}; +"; + assert_format_with_max_width(src, expected, 20); + } + + #[test] + fn format_use_list_one_item() { + let src = " use foo::{ bar, };"; + let expected = "use foo::bar;\n"; + assert_format(src, expected); + } + + #[test] + fn format_long_use_list_one_item() { + let src = "use one::two::{three::{four, five}};"; + let expected = "use one::two::three::{ + four, five, +}; +"; + assert_format_with_max_width(src, expected, 20); + } + + #[test] + fn format_use_list_one_item_with_comments() { + let src = " use foo::{ /* do not remove me */ bar, };"; + let expected = "use foo::{ /* do not remove me */ bar};\n"; + assert_format(src, expected); + } + + #[test] + fn format_use_crate_with_list() { + let src = " use crate :: hash :: { Hash, Hasher }; "; + let expected = "use crate::hash::{Hash, Hasher};\n"; + assert_format(src, expected); + } + + #[test] + fn attaches_semicolon_to_last_group() { + let src = " use crate::hash::{Hash, Hasher}; "; + let expected = "use crate::hash::{ + Hash, Hasher, +}; +"; + assert_format_with_max_width(src, expected, "use crate::hash::{Hash, Hasher}".len()); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/visibility.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/visibility.rs new file mode 100644 index 00000000000..d1068aa4d05 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/visibility.rs @@ -0,0 +1,52 @@ +use super::Formatter; +use noirc_frontend::{ + ast::{ItemVisibility, Visibility}, + token::Keyword, +}; + +impl<'a> Formatter<'a> { + pub(super) fn format_item_visibility(&mut self, visibility: ItemVisibility) { + self.skip_comments_and_whitespace(); + + match visibility { + ItemVisibility::Private => (), + ItemVisibility::PublicCrate => { + self.write_keyword(Keyword::Pub); + self.write_left_paren(); + self.write_keyword(Keyword::Crate); + self.write_right_paren(); + self.write_space(); + } + ItemVisibility::Public => { + self.write_keyword(Keyword::Pub); + self.write_space(); + } + } + } + + pub(super) fn format_visibility(&mut self, visibility: Visibility) { + self.skip_comments_and_whitespace(); + + match visibility { + Visibility::Private => (), + Visibility::Public => { + self.write_keyword(Keyword::Pub); + self.write_space(); + } + Visibility::CallData(..) => { + self.write_keyword(Keyword::CallData); + self.write_left_paren(); + self.skip_comments_and_whitespace(); + self.write_current_token(); + self.bump(); + self.skip_comments_and_whitespace(); + self.write_right_paren(); + self.write_space(); + } + Visibility::ReturnData => { + self.write_keyword(Keyword::ReturnData); + self.write_space(); + } + } + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/formatter/where_clause.rs b/noir/noir-repo/tooling/nargo_fmt/src/formatter/where_clause.rs new file mode 100644 index 00000000000..538d2ba8c01 --- /dev/null +++ b/noir/noir-repo/tooling/nargo_fmt/src/formatter/where_clause.rs @@ -0,0 +1,72 @@ +use noirc_frontend::{ + ast::{TraitBound, UnresolvedTraitConstraint}, + token::{Keyword, Token}, +}; + +use super::Formatter; + +impl<'a> Formatter<'a> { + pub(super) fn format_where_clause( + &mut self, + constraints: Vec, + write_trailing_comma_and_new_line: bool, + ) { + assert!(!constraints.is_empty()); + + self.skip_comments_and_whitespace(); + self.write_line(); + self.write_indentation(); + self.write_keyword(Keyword::Where); + self.increase_indentation(); + + // If we have `where F: Foo + Bar`, that's actually parsed as two constraints: `F: Foo` and `F: Bar`. + // To format it we'll have to skip the second type `F` if we find a `+` token. + let mut write_type = true; + + for constraint in constraints { + if write_type { + self.write_line(); + self.write_indentation(); + self.format_type(constraint.typ); + self.write_token(Token::Colon); + self.write_space(); + } + + self.format_trait_bound(constraint.trait_bound); + self.skip_comments_and_whitespace(); + + if self.is_at(Token::Plus) { + self.write_space(); + self.write_token(Token::Plus); + self.write_space(); + write_type = false; + continue; + } + + write_type = true; + + if self.is_at(Token::Comma) { + if write_trailing_comma_and_new_line { + self.write_token(Token::Comma); + } else { + self.skip_comments_and_whitespace(); + self.bump(); + } + } else if write_trailing_comma_and_new_line { + self.write(","); + } + } + + self.decrease_indentation(); + + if write_trailing_comma_and_new_line { + self.write_line(); + self.write_indentation(); + } + } + + pub(super) fn format_trait_bound(&mut self, trait_bound: TraitBound) { + self.format_path(trait_bound.trait_path); + self.format_generic_type_args(trait_bound.trait_generics); + } +} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/items.rs b/noir/noir-repo/tooling/nargo_fmt/src/items.rs deleted file mode 100644 index e68be7cdc95..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/items.rs +++ /dev/null @@ -1,114 +0,0 @@ -use noirc_errors::Span; - -use crate::{ - utils::{comment_len, find_comment_end}, - visitor::{FmtVisitor, Shape}, -}; - -#[derive(Debug)] -pub(crate) struct Item { - pub(crate) leading: String, - pub(crate) value: String, - pub(crate) trailing: String, - pub(crate) different_line: bool, -} - -impl Item { - pub(crate) fn total_width(&self) -> usize { - comment_len(&self.leading) + self.value.chars().count() + comment_len(&self.trailing) - } - - pub(crate) fn is_multiline(&self) -> bool { - self.leading.contains('\n') || self.trailing.contains('\n') - } -} - -pub(crate) struct Items<'me, T> { - visitor: &'me FmtVisitor<'me>, - shape: Shape, - elements: std::iter::Peekable>, - last_position: u32, - end_position: u32, -} - -impl<'me, T: HasItem> Items<'me, T> { - pub(crate) fn new( - visitor: &'me FmtVisitor<'me>, - shape: Shape, - span: Span, - elements: Vec, - ) -> Self { - Self { - visitor, - shape, - last_position: span.start() + 1, - end_position: span.end() - 1, - elements: elements.into_iter().peekable(), - } - } -} - -impl Iterator for Items<'_, T> { - type Item = Item; - - fn next(&mut self) -> Option { - let element = self.elements.next()?; - let element_span = element.span(); - - let start = self.last_position; - let end = element_span.start(); - - let is_last = self.elements.peek().is_none(); - let next_start = self.elements.peek().map_or(self.end_position, |expr| expr.start()); - - let (leading, different_line) = self.leading(start, end); - let expr = element.format(self.visitor, self.shape); - let trailing = self.trailing(element_span.end(), next_start, is_last); - - Item { leading, value: expr, trailing, different_line }.into() - } -} - -impl<'me, T> Items<'me, T> { - pub(crate) fn leading(&mut self, start: u32, end: u32) -> (String, bool) { - let mut different_line = false; - - let leading = self.visitor.slice(start..end); - // Trim any possible whitespace before and after a comma separator - let leading_trimmed = leading.trim().trim_start_matches(',').trim(); - - let starts_with_block_comment = leading_trimmed.starts_with("/*"); - let ends_with_block_comment = leading_trimmed.ends_with("*/"); - let starts_with_single_line_comment = leading_trimmed.starts_with("//"); - - if ends_with_block_comment { - let comment_end = leading_trimmed.rfind(|c| c == '/').unwrap(); - - if leading[comment_end..].contains('\n') { - different_line = true; - } - } else if starts_with_single_line_comment || starts_with_block_comment { - different_line = true; - }; - - (leading_trimmed.to_string(), different_line) - } - - pub(crate) fn trailing(&mut self, start: u32, end: u32, is_last: bool) -> String { - let slice = self.visitor.slice(start..end); - let comment_end = find_comment_end(slice, is_last); - let trailing = slice[..comment_end].trim_matches(',').trim(); - self.last_position = start + (comment_end as u32); - trailing.to_string() - } -} - -pub(crate) trait HasItem { - fn span(&self) -> Span; - - fn format(self, visitor: &FmtVisitor, shape: Shape) -> String; - - fn start(&self) -> u32 { - self.span().start() - } -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/lib.rs b/noir/noir-repo/tooling/nargo_fmt/src/lib.rs index 0a7903f0ce1..eda77e78c7c 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/lib.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/lib.rs @@ -3,35 +3,87 @@ #![warn(clippy::semicolon_if_nothing_returned)] #![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] -/// A Rust code formatting utility designed to manage and format untouched fragments of source code, -/// including comments, whitespace, and other characters. While the module doesn't directly address comments, -/// it treats them as unchanged fragments, ensuring their original placement and content remain preserved. -/// -/// Key methods include: -/// - `format_missing`: Addresses characters between the last processed position and a given end position, -/// capturing comments and other untouched sequences. -/// - `format_missing_indent`: Functions similarly to `format_missing`, but introduces added indentation. -/// - `format_missing_inner`: The core method for handling missing fragments, appending them to the output buffer. -/// Pure whitespace fragments might be replaced or adjusted based on context. -/// - `push_vertical_spaces`: Standardizes vertical spacing, eliminating potential excessive empty lines -/// or ensuring adequate vertical separation. -/// -/// By recognizing and properly handling these untouched fragments, the utility ensures comments remain intact -/// in both placement and content during the formatting process. +//! The Noir formatter. +//! +//! It works by using two techniques: +//! +//! 1. Surfing a parsed module by using a lexer. +//! 2. Trying to not exceed the maximum line width by formatting to intermediate chunk (see chunks.rs) +//! +//! What is lexer surfing? +//! +//! Suppose we need to format this code: +//! +//! fn foo ( ) { let x : Field = ( 2 , 3 ) ; } +//! +//! We first parse the above code so we end up with a ParsedModule. Next we traverse this module +//! contents and process each item, statement, expression, type, etc., we find. +//! +//! For example, the first thing we'll find is a function. We know it has no visibility and no doc +//! comments so we can expect an `fn` keyword to be there. We write it. Next will come the identifier. +//! For that we "skip" any spaces and comments between `fn` and `foo`, writing only one space instead +//! of possibly multiple spaces, then write "foo". If there were comments between `fn` and `foo`, +//! we write them (the formatter will never lose comments). +//! +//! Next we know there are no generics, so we can expect a `(`, etc. +//! +//! In this way we go token by token, inserting newlines when needed, removing extra spaces, +//! indenting things as we go deep inside structures, etc. +//! +//! But that's not all. The formatter will try to not exceed the configurable maximum width. +//! It will do that but, for simplicity, only for function parameters list, statements and expressions +//! (we assume an `impl Foo ...` line won't exceed the maximum length, and if it does it's not a big deal, +//! or we can always improve things later). For this, read the comments in chunks.rs. +mod chunks; mod config; pub mod errors; -mod items; -mod rewrite; -mod utils; -mod visitor; +mod formatter; +use formatter::Formatter; use noirc_frontend::ParsedModule; -use visitor::FmtVisitor; pub use config::Config; pub fn format(source: &str, parsed_module: ParsedModule, config: &Config) -> String { - let mut fmt = FmtVisitor::new(source, config); - fmt.visit_file(parsed_module); - fmt.finish() + let mut formatter = Formatter::new(source, config); + formatter.format_program(parsed_module); + formatter.buffer.contents() +} + +#[cfg(test)] +pub(crate) fn assert_format(src: &str, expected: &str) { + assert_format_with_config(src, expected, Config::default()); +} + +#[cfg(test)] +pub(crate) fn assert_format_with_max_width(src: &str, expected: &str, max_width: usize) { + let config = Config { max_width, ..Config::default() }; + assert_format_with_config(src, expected, config); +} + +#[cfg(test)] +pub(crate) fn assert_format_with_config(src: &str, expected: &str, config: Config) { + use noirc_frontend::parser; + + let (parsed_module, errors) = parser::parse_program(src); + if !errors.is_empty() { + panic!("Expected no errors, got: {:?}", errors); + } + let result = format(src, parsed_module, &config); + if result != expected { + println!("Expected:\n~~~\n{}\n~~~\nGot:\n~~~\n{}\n~~~", expected, result); + } + + similar_asserts::assert_eq!(result, expected); + + let src = &result; + let (parsed_module, errors) = parser::parse_program(src); + if !errors.is_empty() { + panic!("Expected no errors in idempotent check, got: {:?}", errors); + } + let result = format(src, parsed_module, &config); + if result != expected { + println!("Expected (idempotent):\n~~~\n{}\n~~~\nGot:\n~~~\n{}\n~~~", expected, result); + } + similar_asserts::assert_eq!(result, expected, "idempotent check failed"); } diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite.rs deleted file mode 100644 index 61792c7a7fa..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite.rs +++ /dev/null @@ -1,13 +0,0 @@ -mod array; -mod expr; -mod imports; -mod infix; -mod parenthesized; -mod typ; - -pub(crate) use array::rewrite as array; -pub(crate) use expr::{rewrite as expr, rewrite_sub_expr as sub_expr}; -pub(crate) use imports::UseTree; -pub(crate) use infix::rewrite as infix; -pub(crate) use parenthesized::rewrite as parenthesized; -pub(crate) use typ::rewrite as typ; diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/array.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/array.rs deleted file mode 100644 index 011e775a018..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/array.rs +++ /dev/null @@ -1,92 +0,0 @@ -use noirc_frontend::{ast::Expression, hir::resolution::errors::Span, token::Token}; - -use crate::{ - items::Item, - utils::FindToken, - visitor::{expr::NewlineMode, FmtVisitor}, -}; - -pub(crate) fn rewrite( - mut visitor: FmtVisitor, - array: Vec, - array_span: Span, - is_slice: bool, -) -> String { - let pattern: &[_] = &[' ', '\t']; - - visitor.indent.block_indent(visitor.config); - let nested_indent = visitor.shape(); - - let indent_str = nested_indent.indent.to_string(); - - let mut last_position = array_span.start() + 1; - let end_position = array_span.end() - 1; - - let mut items = array.into_iter().peekable(); - - let mut result = Vec::new(); - while let Some(item) = items.next() { - let item_span = item.span; - - let start: u32 = last_position; - let end = item_span.start(); - - let leading = visitor.slice(start..end).trim_matches(pattern); - let item = super::sub_expr(&visitor, visitor.shape(), item); - let next_start = items.peek().map_or(end_position, |expr| expr.span.start()); - let trailing = visitor.slice(item_span.end()..next_start); - let offset = trailing - .find_token(Token::Comma) - .map(|span| span.end() as usize) - .unwrap_or(trailing.len()); - let trailing = trailing[..offset].trim_end_matches(',').trim_matches(pattern); - last_position = item_span.end() + offset as u32; - - let (leading, _) = visitor.format_comment_in_block(leading); - let (trailing, _) = visitor.format_comment_in_block(trailing); - - result.push(Item { leading, value: item, trailing, different_line: false }); - } - - let slice = visitor.slice(last_position..end_position); - let (comment, _) = visitor.format_comment_in_block(slice); - result.push(Item { - leading: "".into(), - value: "".into(), - trailing: comment, - different_line: false, - }); - - visitor.indent.block_unindent(visitor.config); - - let mut items_str = String::new(); - let mut items = result.into_iter().peekable(); - while let Some(next) = items.next() { - items_str.push_str(&next.leading); - if next.leading.contains('\n') && !next.value.is_empty() { - items_str.push_str(&indent_str); - } - items_str.push_str(&next.value); - items_str.push_str(&next.trailing); - - if let Some(item) = items.peek() { - if !item.value.is_empty() { - items_str.push(','); - } - - if !item.leading.contains('\n') && !next.value.is_empty() { - items_str.push(' '); - } - } - } - - let open_bracket = if is_slice { "&[" } else { "[" }; - crate::visitor::expr::wrap_exprs( - open_bracket, - "]", - items_str.trim().into(), - nested_indent, - visitor.shape(), - NewlineMode::IfContainsNewLineAndWidth, - ) -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/expr.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/expr.rs deleted file mode 100644 index 98b50e92476..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/expr.rs +++ /dev/null @@ -1,258 +0,0 @@ -use noirc_errors::Span; -use noirc_frontend::ast::{ - ArrayLiteral, BlockExpression, Expression, ExpressionKind, Literal, Path, PathKind, UnaryOp, - UnresolvedType, -}; -use noirc_frontend::token::Token; - -use crate::rewrite; -use crate::visitor::{ - expr::{format_brackets, format_parens, NewlineMode}, - ExpressionType, FmtVisitor, Indent, Shape, -}; - -pub(crate) fn rewrite_sub_expr( - visitor: &FmtVisitor, - shape: Shape, - expression: Expression, -) -> String { - rewrite(visitor, expression, ExpressionType::SubExpression, shape) -} - -pub(crate) fn rewrite( - visitor: &FmtVisitor, - Expression { kind, span }: Expression, - expr_type: ExpressionType, - shape: Shape, -) -> String { - match kind { - ExpressionKind::Block(block) => rewrite_block(visitor, block, span), - ExpressionKind::Prefix(prefix) => { - let op = match prefix.operator { - UnaryOp::Minus => "-", - UnaryOp::Not => "!", - UnaryOp::MutableReference => "&mut ", - UnaryOp::Dereference { implicitly_added } => { - if implicitly_added { - "" - } else { - "*" - } - } - }; - - format!("{op}{}", rewrite_sub_expr(visitor, shape, prefix.rhs)) - } - ExpressionKind::Cast(cast) => { - format!("{} as {}", rewrite_sub_expr(visitor, shape, cast.lhs), cast.r#type) - } - kind @ ExpressionKind::Infix(_) => { - super::infix(visitor.fork(), Expression { kind, span }, shape) - } - ExpressionKind::Call(call_expr) => { - let args_span = - visitor.span_before(call_expr.func.span.end()..span.end(), Token::LeftParen); - - let callee = rewrite_sub_expr(visitor, shape, *call_expr.func); - let args = format_parens( - visitor.config.fn_call_width.into(), - visitor.fork(), - shape, - false, - call_expr.arguments, - args_span, - true, - NewlineMode::IfContainsNewLineAndWidth, - ); - - let bang = if call_expr.is_macro_call { "!" } else { "" }; - format!("{callee}{bang}{args}") - } - ExpressionKind::MethodCall(method_call_expr) => { - let args_span = visitor.span_before( - method_call_expr.method_name.span().end()..span.end(), - Token::LeftParen, - ); - - let object = rewrite_sub_expr(visitor, shape, method_call_expr.object); - let method = method_call_expr.method_name.to_string(); - let turbofish = rewrite_turbofish(visitor, shape, method_call_expr.generics); - let args = format_parens( - visitor.config.fn_call_width.into(), - visitor.fork(), - shape, - false, - method_call_expr.arguments, - args_span, - true, - NewlineMode::IfContainsNewLineAndWidth, - ); - - let bang = if method_call_expr.is_macro_call { "!" } else { "" }; - format!("{object}.{method}{turbofish}{bang}{args}") - } - ExpressionKind::MemberAccess(member_access_expr) => { - let lhs_str = rewrite_sub_expr(visitor, shape, member_access_expr.lhs); - format!("{}.{}", lhs_str, member_access_expr.rhs) - } - ExpressionKind::Index(index_expr) => { - let index_span = visitor - .span_before(index_expr.collection.span.end()..span.end(), Token::LeftBracket); - - let collection = rewrite_sub_expr(visitor, shape, index_expr.collection); - let index = format_brackets(visitor.fork(), false, vec![index_expr.index], index_span); - - format!("{collection}{index}") - } - ExpressionKind::Tuple(exprs) => format_parens( - None, - visitor.fork(), - shape, - exprs.len() == 1, - exprs, - span, - true, - NewlineMode::Normal, - ), - ExpressionKind::Literal(literal) => match literal { - Literal::Integer(_, _) - | Literal::Bool(_) - | Literal::Str(_) - | Literal::RawStr(..) - | Literal::FmtStr(_) => visitor.slice(span).to_string(), - Literal::Array(ArrayLiteral::Repeated { repeated_element, length }) => { - let repeated = rewrite_sub_expr(visitor, shape, *repeated_element); - let length = rewrite_sub_expr(visitor, shape, *length); - - format!("[{repeated}; {length}]") - } - Literal::Array(ArrayLiteral::Standard(exprs)) => { - super::array(visitor.fork(), exprs, span, false) - } - Literal::Slice(ArrayLiteral::Repeated { repeated_element, length }) => { - let repeated = rewrite_sub_expr(visitor, shape, *repeated_element); - let length = rewrite_sub_expr(visitor, shape, *length); - - format!("&[{repeated}; {length}]") - } - Literal::Slice(ArrayLiteral::Standard(exprs)) => { - super::array(visitor.fork(), exprs, span, true) - } - Literal::Unit => "()".to_string(), - }, - ExpressionKind::Parenthesized(sub_expr) => { - super::parenthesized(visitor, shape, span, *sub_expr) - } - ExpressionKind::Constructor(constructor) => { - let type_name = visitor.slice(span.start()..constructor.typ.span.end()); - let fields_span = - visitor.span_before(constructor.typ.span.end()..span.end(), Token::LeftBrace); - - visitor.format_struct_lit(type_name, fields_span, *constructor) - } - ExpressionKind::If(if_expr) => { - let allow_single_line = expr_type == ExpressionType::SubExpression; - - if allow_single_line { - let mut visitor = visitor.fork(); - visitor.indent = Indent::default(); - if let Some(line) = visitor.format_if_single_line(*if_expr.clone()) { - return line; - } - } - - visitor.format_if(*if_expr) - } - ExpressionKind::Variable(path) => rewrite_path(visitor, shape, path), - ExpressionKind::Lambda(_) => visitor.slice(span).to_string(), - ExpressionKind::Quote(_) => visitor.slice(span).to_string(), - ExpressionKind::Comptime(block, block_span) => { - format!("comptime {}", rewrite_block(visitor, block, block_span)) - } - ExpressionKind::Unsafe(block, block_span) => { - format!("unsafe {}", rewrite_block(visitor, block, block_span)) - } - ExpressionKind::Error => unreachable!(), - ExpressionKind::Resolved(_) => { - unreachable!("ExpressionKind::Resolved should only emitted by the comptime interpreter") - } - ExpressionKind::Interned(_) => { - unreachable!("ExpressionKind::Interned should only emitted by the comptime interpreter") - } - ExpressionKind::InternedStatement(_) => { - unreachable!( - "ExpressionKind::InternedStatement should only emitted by the comptime interpreter" - ) - } - ExpressionKind::Unquote(expr) => { - if matches!(&expr.kind, ExpressionKind::Variable(..)) { - format!("${expr}") - } else { - format!("$({})", rewrite_sub_expr(visitor, shape, *expr)) - } - } - ExpressionKind::AsTraitPath(path) => { - let trait_path = rewrite_path(visitor, shape, path.trait_path); - - if path.trait_generics.is_empty() { - format!("<{} as {}>::{}", path.typ, trait_path, path.impl_item) - } else { - let generics = path.trait_generics; - format!("<{} as {}::{}>::{}", path.typ, trait_path, generics, path.impl_item) - } - } - ExpressionKind::TypePath(path) => { - if path.turbofish.is_empty() { - format!("{}::{}", path.typ, path.item) - } else { - format!("{}::{}::{}", path.typ, path.item, path.turbofish) - } - } - } -} - -fn rewrite_block(visitor: &FmtVisitor, block: BlockExpression, span: Span) -> String { - let mut visitor = visitor.fork(); - visitor.visit_block(block, span); - visitor.finish() -} - -fn rewrite_path(visitor: &FmtVisitor, shape: Shape, path: Path) -> String { - let mut string = String::new(); - - if path.kind != PathKind::Plain { - string.push_str(&path.kind.to_string()); - string.push_str("::"); - } - - for (index, segment) in path.segments.iter().enumerate() { - if index > 0 { - string.push_str("::"); - } - string.push_str(&segment.ident.to_string()); - string.push_str(&rewrite_turbofish(visitor, shape, segment.generics.clone())); - } - - string -} - -fn rewrite_turbofish( - visitor: &FmtVisitor, - shape: Shape, - generics: Option>, -) -> String { - if let Some(generics) = generics { - let mut turbofish = "".to_owned(); - for (i, generic) in generics.into_iter().enumerate() { - let generic = rewrite::typ(visitor, shape, generic); - turbofish = if i == 0 { - format!("::<{}", generic) - } else { - format!("{turbofish}, {}", generic) - }; - } - format!("{turbofish}>") - } else { - "".to_owned() - } -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/imports.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/imports.rs deleted file mode 100644 index 6c63c551f7d..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/imports.rs +++ /dev/null @@ -1,135 +0,0 @@ -use noirc_frontend::ast::{self, ItemVisibility}; - -use crate::{ - items::Item, - visitor::{ - expr::{format_exprs, Tactic}, - FmtVisitor, Shape, - }, -}; - -#[derive(Debug)] -pub(crate) enum UseSegment { - Ident(String, Option), - List(Vec), - Dep, - Crate, - Super, -} - -impl UseSegment { - fn rewrite(&self, visitor: &FmtVisitor, shape: Shape) -> String { - match self { - UseSegment::Ident(ident, None) => ident.clone(), - UseSegment::Ident(ident, Some(rename)) => format!("{ident} as {rename}"), - UseSegment::List(use_tree_list) => { - let mut nested_shape = shape; - nested_shape.indent.block_indent(visitor.config); - - let items: Vec<_> = use_tree_list - .iter() - .map(|item| Item { - leading: String::new(), - value: item.rewrite(visitor, shape).clone(), - trailing: String::new(), - different_line: false, - }) - .collect(); - - let list_str = - format_exprs(visitor.config, Tactic::Mixed, false, items, nested_shape, true); - - if list_str.contains('\n') { - format!( - "{{\n{}{list_str}\n{}}}", - nested_shape.indent.to_string(), - shape.indent.to_string() - ) - } else { - format!("{{{list_str}}}") - } - } - UseSegment::Dep => "dep".into(), - UseSegment::Crate => "crate".into(), - UseSegment::Super => "super".into(), - } - } -} - -#[derive(Debug)] -pub(crate) struct UseTree { - path: Vec, -} - -impl UseTree { - pub(crate) fn from_ast(use_tree: ast::UseTree) -> Self { - let mut result = UseTree { path: vec![] }; - - match use_tree.prefix.kind { - ast::PathKind::Crate => result.path.push(UseSegment::Crate), - ast::PathKind::Dep => result.path.push(UseSegment::Dep), - ast::PathKind::Super => result.path.push(UseSegment::Super), - ast::PathKind::Plain => {} - }; - - result.path.extend( - use_tree - .prefix - .segments - .into_iter() - .map(|segment| UseSegment::Ident(segment.to_string(), None)), - ); - - match use_tree.kind { - ast::UseTreeKind::Path(name, alias) => { - result.path.push(UseSegment::Ident( - name.to_string(), - alias.map(|rename| rename.to_string()), - )); - } - ast::UseTreeKind::List(list) => { - let segment = UseSegment::List(list.into_iter().map(UseTree::from_ast).collect()); - result.path.push(segment); - } - } - - result - } - - pub(crate) fn rewrite_top_level( - &self, - visitor: &FmtVisitor, - shape: Shape, - visibility: ItemVisibility, - ) -> String { - let rewrite = self.rewrite(visitor, shape); - if visibility == ItemVisibility::Private { - format!("use {};", rewrite) - } else { - format!("{} use {};", visibility, rewrite) - } - } - - fn rewrite(&self, visitor: &FmtVisitor, shape: Shape) -> String { - let mut result = String::new(); - - let mut iter = self.path.iter().peekable(); - while let Some(segment) = iter.next() { - let mut segment_str = segment.rewrite(visitor, shape); - if segment_str.contains('{') - && !segment_str.contains(',') - && !segment_str.contains("::") - { - let empty = ""; - segment_str = segment_str.replace(['{', '}'], empty); - } - result.push_str(&segment_str); - - if iter.peek().is_some() { - result.push_str("::"); - } - } - - result - } -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/infix.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/infix.rs deleted file mode 100644 index e2555f21187..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/infix.rs +++ /dev/null @@ -1,115 +0,0 @@ -use std::iter::zip; - -use noirc_frontend::ast::{Expression, ExpressionKind}; - -use crate::{ - rewrite, - utils::{first_line_width, is_single_line}, - visitor::{FmtVisitor, Shape}, -}; - -pub(crate) fn rewrite(visitor: FmtVisitor, expr: Expression, shape: Shape) -> String { - match flatten(visitor.fork(), &expr) { - Some((exprs, separators)) => rewrite_single_line(shape, &exprs, &separators) - .unwrap_or_else(|| rewrite_multiline(visitor, &exprs, &separators)), - None => { - let ExpressionKind::Infix(infix) = expr.kind else { unreachable!() }; - - format!( - "{} {} {}", - rewrite::sub_expr(&visitor, shape, infix.lhs), - infix.operator.contents.as_string(), - rewrite::sub_expr(&visitor, shape, infix.rhs) - ) - } - } -} - -fn rewrite_single_line(shape: Shape, exprs: &[String], separators: &[String]) -> Option { - let mut result = String::new(); - - for (rewrite, separator) in zip(exprs, separators) { - if !is_single_line(rewrite) || result.len() > shape.width { - return None; - } - - result.push_str(rewrite); - result.push(' '); - result.push_str(separator); - result.push(' '); - } - - let last = exprs.last().unwrap(); - result.push_str(last); - - if first_line_width(&result) > shape.width { - return None; - } - - result.into() -} - -fn rewrite_multiline(visitor: FmtVisitor, exprs: &[String], separators: &[String]) -> String { - let mut visitor = visitor.fork(); - visitor.indent.block_indent(visitor.config); - let indent_str = visitor.indent.to_string_with_newline(); - - let mut result = exprs[0].clone(); - - for (rewrite, separator) in exprs[1..].iter().zip(separators.iter()) { - result.push_str(&indent_str); - result.push_str(separator); - result.push(' '); - result.push_str(rewrite); - } - - result -} - -pub(crate) fn flatten( - mut visitor: FmtVisitor, - mut node: &Expression, -) -> Option<(Vec, Vec)> { - let top_operator = match node.kind { - ExpressionKind::Infix(ref infix) => infix.operator.contents, - _ => return None, - }; - - let mut result = Vec::new(); - - let mut stack: Vec<&Expression> = Vec::new(); - let mut separators = Vec::new(); - - loop { - match &node.kind { - ExpressionKind::Infix(infix) if top_operator == infix.operator.contents => { - stack.push(node); - node = &infix.lhs; - } - _ => { - let rewrite = if result.is_empty() { - rewrite::sub_expr(&visitor, visitor.shape(), node.clone()) - } else { - visitor.indent.block_indent(visitor.config); - rewrite::sub_expr(&visitor, visitor.shape(), node.clone()) - }; - - result.push(rewrite); - - let Some(pop) = stack.pop() else { - break; - }; - - match &pop.kind { - ExpressionKind::Infix(infix) => { - separators.push(infix.operator.contents.to_string()); - node = &infix.rhs; - } - _ => unreachable!(), - } - } - } - } - - (result, separators).into() -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/parenthesized.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/parenthesized.rs deleted file mode 100644 index 93e1538b042..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/parenthesized.rs +++ /dev/null @@ -1,68 +0,0 @@ -use noirc_frontend::ast::{Expression, ExpressionKind}; -use noirc_frontend::hir::resolution::errors::Span; - -use crate::visitor::{FmtVisitor, Shape}; - -pub(crate) fn rewrite( - visitor: &FmtVisitor<'_>, - shape: Shape, - mut span: Span, - mut sub_expr: Expression, -) -> String { - let remove_nested_parens = visitor.config.remove_nested_parens; - - let mut leading; - let mut trailing; - - loop { - let leading_span = span.start() + 1..sub_expr.span.start(); - let trailing_span = sub_expr.span.end()..span.end() - 1; - - leading = visitor.format_comment(leading_span.into()); - trailing = visitor.format_comment(trailing_span.into()); - - if let ExpressionKind::Parenthesized(ref sub_sub_expr) = sub_expr.kind { - if remove_nested_parens && leading.is_empty() && trailing.is_empty() { - span = sub_expr.span; - sub_expr = *sub_sub_expr.clone(); - continue; - } - } - - break; - } - - if !leading.contains("//") && !trailing.contains("//") { - let sub_expr = super::sub_expr(visitor, shape, sub_expr); - format!("({leading}{sub_expr}{trailing})") - } else { - let mut visitor = visitor.fork(); - - let indent = visitor.indent.to_string_with_newline(); - visitor.indent.block_indent(visitor.config); - let nested_indent = visitor.indent.to_string_with_newline(); - - let sub_expr = super::sub_expr(&visitor, shape, sub_expr); - - let mut result = String::new(); - result.push('('); - - if !leading.is_empty() { - result.push_str(&nested_indent); - result.push_str(&leading); - } - - result.push_str(&nested_indent); - result.push_str(&sub_expr); - - if !trailing.is_empty() { - result.push_str(&nested_indent); - result.push_str(&trailing); - } - - result.push_str(&indent); - result.push(')'); - - result - } -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs b/noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs deleted file mode 100644 index 6121f8debf6..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/rewrite/typ.rs +++ /dev/null @@ -1,78 +0,0 @@ -use noirc_frontend::ast::{UnresolvedType, UnresolvedTypeData}; - -use crate::{ - utils::span_is_empty, - visitor::{FmtVisitor, Shape}, -}; - -pub(crate) fn rewrite(visitor: &FmtVisitor, _shape: Shape, typ: UnresolvedType) -> String { - match typ.typ { - UnresolvedTypeData::Array(length, element) => { - let typ = rewrite(visitor, _shape, *element); - let length = visitor.slice(length.span()); - format!("[{typ}; {length}]") - } - UnresolvedTypeData::Slice(element) => { - let typ = rewrite(visitor, _shape, *element); - format!("[{typ}]") - } - UnresolvedTypeData::Parenthesized(typ) => { - let typ = rewrite(visitor, _shape, *typ); - format!("({typ})") - } - UnresolvedTypeData::MutableReference(typ) => { - let typ = rewrite(visitor, _shape, *typ); - format!("&mut {typ}") - } - UnresolvedTypeData::Tuple(mut types) => { - if types.len() == 1 { - let typ = types.pop().unwrap(); - let typ = rewrite(visitor, _shape, typ); - - format!("({typ},)") - } else { - let types: Vec<_> = - types.into_iter().map(|typ| rewrite(visitor, _shape, typ)).collect(); - let types = types.join(", "); - format!("({types})") - } - } - UnresolvedTypeData::Function(args, return_type, env, unconstrained) => { - let unconstrained = if unconstrained { "unconstrained " } else { "" }; - - let env = if span_is_empty(env.span) { - "".into() - } else { - let ty = rewrite(visitor, _shape, *env); - format!("[{ty}]") - }; - - let args = args - .into_iter() - .map(|arg| rewrite(visitor, _shape, arg)) - .collect::>() - .join(", "); - - let return_type = rewrite(visitor, _shape, *return_type); - - format!("{unconstrained}fn{env}({args}) -> {return_type}") - } - UnresolvedTypeData::Resolved(_) => { - unreachable!("Unexpected macro expansion of a type in nargo fmt input") - } - UnresolvedTypeData::AsTraitPath(path) => path.to_string(), - - UnresolvedTypeData::Unspecified => todo!(), - UnresolvedTypeData::FieldElement - | UnresolvedTypeData::Integer(_, _) - | UnresolvedTypeData::Bool - | UnresolvedTypeData::Named(_, _, _) - | UnresolvedTypeData::Unit - | UnresolvedTypeData::Expression(_) - | UnresolvedTypeData::String(_) - | UnresolvedTypeData::FormatString(_, _) - | UnresolvedTypeData::Quoted(_) - | UnresolvedTypeData::TraitAsType(_, _) => visitor.slice(typ.span).into(), - UnresolvedTypeData::Interned(_) | UnresolvedTypeData::Error => unreachable!(), - } -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/utils.rs b/noir/noir-repo/tooling/nargo_fmt/src/utils.rs deleted file mode 100644 index 83634b718e2..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/utils.rs +++ /dev/null @@ -1,233 +0,0 @@ -use std::borrow::Cow; - -use crate::items::HasItem; -use crate::rewrite; -use crate::visitor::{FmtVisitor, Shape}; -use noirc_frontend::ast::{Expression, Ident, Param, UnresolvedGeneric, Visibility}; -use noirc_frontend::hir::resolution::errors::Span; -use noirc_frontend::lexer::Lexer; -use noirc_frontend::token::Token; - -pub(crate) fn changed_comment_content(original: &str, new: &str) -> bool { - comments(original).ne(comments(new)) -} - -pub(crate) fn comments(source: &str) -> impl Iterator + '_ { - Lexer::new(source).skip_comments(false).flatten().filter_map(|spanned| { - if let Token::LineComment(content, _) | Token::BlockComment(content, _) = - spanned.into_token() - { - Some(content) - } else { - None - } - }) -} - -pub(crate) trait FindToken { - fn find_token(&self, token: Token) -> Option; - fn find_token_with(&self, f: impl Fn(&Token) -> bool) -> Option; -} - -impl FindToken for str { - fn find_token(&self, token: Token) -> Option { - Lexer::new(self).flatten().find_map(|it| (it.token() == &token).then(|| it.to_span())) - } - - fn find_token_with(&self, f: impl Fn(&Token) -> bool) -> Option { - Lexer::new(self) - .skip_comments(false) - .flatten() - .find_map(|spanned| f(spanned.token()).then(|| spanned.to_span())) - } -} - -pub(crate) fn find_comment_end(slice: &str, is_last: bool) -> usize { - fn find_comment_end(slice: &str) -> usize { - slice - .find_token_with(|token| { - matches!(token, Token::LineComment(_, _) | Token::BlockComment(_, _)) - }) - .map(|index| index.end() as usize) - .unwrap_or(slice.len()) - } - - if is_last { - return slice.len(); - } - - let mut block_open_index = slice.find("/*"); - if let Some(index) = block_open_index { - match slice.find('/') { - Some(slash) if slash < index => block_open_index = None, - _ if slice[..index].ends_with('/') => block_open_index = None, - _ => (), - } - } - - let newline_index = slice.find('\n'); - if let Some(separator_index) = - slice.find_token(Token::Comma).map(|index| index.start() as usize) - { - match (block_open_index, newline_index) { - (Some(block), None) if block > separator_index => separator_index + 1, - (Some(block), None) => { - let slice = &slice[block..]; - std::cmp::max(find_comment_end(slice) + block, separator_index + 1) - } - (Some(block), Some(newline)) if block < newline => { - let slice = &slice[block..]; - std::cmp::max(find_comment_end(slice) + block, separator_index + 1) - } - (_, Some(newline)) if newline > separator_index => newline + 1, - (None, None) => 0, - _ => slice.len(), - } - } else if let Some(newline_index) = newline_index { - newline_index + 1 - } else { - 0 - } -} - -pub(crate) fn comment_len(comment: &str) -> usize { - match comment { - "" => 0, - _ => { - let len = comment.trim().len(); - if len > 0 { - len + 6 - } else { - len - } - } - } -} - -pub(crate) fn count_newlines(slice: &str) -> usize { - bytecount::count(slice.as_bytes(), b'\n') -} - -impl HasItem for Expression { - fn span(&self) -> Span { - self.span - } - - fn format(self, visitor: &FmtVisitor, shape: Shape) -> String { - rewrite::sub_expr(visitor, shape, self) - } -} - -impl HasItem for (Ident, Expression) { - fn span(&self) -> Span { - let (name, value) = self; - (name.span().start()..value.span.end()).into() - } - - fn format(self, visitor: &FmtVisitor, shape: Shape) -> String { - let (name, expr) = self; - - let name = name.0.contents; - let expr = rewrite::sub_expr(visitor, shape, expr); - - if name == expr { - name - } else { - format!("{name}: {expr}") - } - } -} - -impl HasItem for Param { - fn span(&self) -> Span { - self.span - } - - fn format(self, visitor: &FmtVisitor, shape: Shape) -> String { - let pattern = visitor.slice(self.pattern.span()); - let visibility = match self.visibility { - Visibility::Public => "pub".to_string(), - Visibility::Private => "".to_string(), - Visibility::CallData(x) => format!("call_data({x})"), - Visibility::ReturnData => "return_data".to_string(), - }; - - if self.pattern.is_synthesized() || self.typ.is_synthesized() { - pattern.to_string() - } else { - let ty = rewrite::typ(visitor, shape, self.typ); - let visibility = append_space_if_nonempty(visibility.into()); - format!("{pattern}: {visibility}{ty}") - } - } -} - -impl HasItem for Ident { - fn span(&self) -> Span { - self.span() - } - - fn format(self, visitor: &FmtVisitor, _shape: Shape) -> String { - visitor.slice(self.span()).into() - } -} - -impl HasItem for UnresolvedGeneric { - fn span(&self) -> Span { - self.span() - } - - fn format(self, visitor: &FmtVisitor, _shape: Shape) -> String { - match self { - UnresolvedGeneric::Variable(_) => visitor.slice(self.span()).into(), - UnresolvedGeneric::Numeric { ident, typ } => { - let mut result = "".to_owned(); - result.push_str(&ident.0.contents); - result.push_str(": "); - let typ = rewrite::typ(visitor, _shape, typ); - result.push_str(&typ); - result - } - UnresolvedGeneric::Resolved(..) => { - unreachable!("Found macro result UnresolvedGeneric::Resolved in formatter") - } - } - } -} - -pub(crate) fn first_line_width(exprs: &str) -> usize { - exprs.lines().next().map_or(0, |line: &str| line.chars().count()) -} - -pub(crate) fn last_line_width(s: &str) -> usize { - s.rsplit('\n').next().unwrap_or("").chars().count() -} - -pub(crate) fn is_single_line(s: &str) -> bool { - !s.chars().any(|c| c == '\n') -} - -pub(crate) fn last_line_contains_single_line_comment(s: &str) -> bool { - s.lines().last().map_or(false, |line| line.contains("//")) -} - -pub(crate) fn append_space_if_nonempty(mut string: Cow) -> Cow { - if !string.is_empty() { - let inner = string.to_mut(); - inner.push(' '); - } - - string -} - -pub(crate) fn last_line_used_width(s: &str, offset: usize) -> usize { - if s.contains('\n') { - last_line_width(s) - } else { - offset + s.chars().count() - } -} - -pub(crate) fn span_is_empty(span: Span) -> bool { - span.start() == span.end() -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/visitor.rs b/noir/noir-repo/tooling/nargo_fmt/src/visitor.rs deleted file mode 100644 index 50f1ca69fcd..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/visitor.rs +++ /dev/null @@ -1,303 +0,0 @@ -pub(crate) mod expr; -mod item; -mod stmt; - -use noirc_frontend::{hir::resolution::errors::Span, lexer::Lexer, token::Token}; - -use crate::{ - config::Config, - utils::{self, FindToken}, -}; - -pub(crate) struct FmtVisitor<'me> { - ignore_next_node: bool, - pub(crate) config: &'me Config, - buffer: String, - pub(crate) source: &'me str, - pub(crate) indent: Indent, - last_position: u32, -} - -impl<'me> FmtVisitor<'me> { - pub(crate) fn new(source: &'me str, config: &'me Config) -> Self { - Self { - ignore_next_node: false, - buffer: String::new(), - config, - source, - last_position: 0, - indent: Indent { block_indent: 0 }, - } - } - - pub(crate) fn budget(&self, used_width: usize) -> usize { - self.config.max_width.saturating_sub(used_width) - } - - pub(crate) fn slice(&self, span: impl Into) -> &'me str { - let span = span.into(); - str_slice(self.source, span.start() as usize, span.end() as usize) - } - - pub(crate) fn span_after(&self, span: impl Into, token: Token) -> Span { - let span = span.into(); - - let slice = self.slice(span); - let offset = slice.find_token(token).unwrap().end(); - - (span.start() + offset..span.end()).into() - } - - pub(crate) fn span_before(&self, span: impl Into, token: Token) -> Span { - let span = span.into(); - - let slice = self.slice(span); - let offset = slice.find_token(token).unwrap().start(); - - (span.start() + offset..span.end()).into() - } - - pub(crate) fn shape(&self) -> Shape { - Shape { - width: self.config.max_width.saturating_sub(self.indent.width()), - indent: self.indent, - } - } - - pub(crate) fn fork(&self) -> Self { - Self { - buffer: String::new(), - ignore_next_node: self.ignore_next_node, - config: self.config, - source: self.source, - last_position: self.last_position, - indent: self.indent, - } - } - - pub(crate) fn finish(self) -> String { - self.buffer - } - - fn at_start(&self) -> bool { - self.buffer.is_empty() - } - - fn push_str(&mut self, s: &str) { - let comments = Lexer::new(s).skip_comments(false).flatten().flat_map(|token| { - if let Token::LineComment(content, _) | Token::BlockComment(content, _) = - token.into_token() - { - let content = content.trim(); - content.strip_prefix("noir-fmt:").map(ToOwned::to_owned) - } else { - None - } - }); - - for comment in comments { - match comment.as_str() { - "ignore" => self.ignore_next_node = true, - this => unreachable!("unknown settings {this}"), - } - } - - self.buffer.push_str(s); - } - - #[track_caller] - fn push_rewrite(&mut self, rewrite: String, span: Span) { - let original = self.slice(span); - let changed_comment_content = utils::changed_comment_content(original, &rewrite); - - if changed_comment_content && self.config.error_on_lost_comment { - panic!("not formatted because a comment would be lost: {rewrite:?}"); - } - - self.format_missing_indent(span.start(), true); - - let rewrite = if changed_comment_content || std::mem::take(&mut self.ignore_next_node) { - original.to_string() - } else { - rewrite - }; - - self.push_str(&rewrite); - - if rewrite.starts_with('{') && rewrite.ends_with('}') { - self.ignore_next_node = false; - } - } - - #[track_caller] - fn format_missing_indent(&mut self, end: u32, should_indent: bool) { - self.format_missing_inner(end, |this, last_slice, slice| { - this.push_str(last_slice.trim_end()); - - if (last_slice == slice && !this.at_start()) || this.buffer.ends_with("*/") { - this.push_str("\n"); - } - - if should_indent { - let indent = this.indent.to_string(); - this.push_str(&indent); - } - }); - } - - #[track_caller] - fn format_missing_inner( - &mut self, - end: u32, - process_last_slice: impl Fn(&mut Self, &str, &str), - ) { - let start = self.last_position; - - if start == end { - if !self.at_start() { - process_last_slice(self, "", ""); - } - return; - } - - let slice = self.slice(start..end); - self.last_position = end; - - if slice.trim().is_empty() && !self.at_start() { - self.push_vertical_spaces(slice); - process_last_slice(self, "", slice); - } else { - let (result, last_end) = self.format_comment_in_block(slice); - if result.trim().is_empty() { - process_last_slice(self, slice, slice); - } else { - let last_snippet = &slice[last_end as usize..]; - self.push_str(&result); - process_last_slice(self, last_snippet, &result); - } - } - } - - pub(crate) fn format_comment_in_block(&mut self, slice: &str) -> (String, u32) { - let mut result = String::new(); - let comments = Lexer::new(slice).skip_comments(false).skip_whitespaces(false).flatten(); - - let indent = self.indent.to_string(); - for comment in comments { - let span = comment.to_span(); - - match comment.token() { - Token::LineComment(_, _) | Token::BlockComment(_, _) => { - let comment = str_slice(slice, span.start() as usize, span.end() as usize); - if result.ends_with('\n') { - result.push_str(&indent); - } else if !self.at_start() { - result.push(' '); - } - result.push_str(comment); - } - Token::Whitespace(whitespaces) => { - let mut visitor = self.fork(); - if whitespaces.contains('\n') { - visitor.push_vertical_spaces(whitespaces.trim_matches(' ')); - result.push_str(&visitor.finish()); - } - } - _ => {} - } - } - - (result, slice.len() as u32) - } - - fn push_vertical_spaces(&mut self, slice: &str) { - let newline_upper_bound = 2; - let newline_lower_bound = 1; - - let mut newline_count = utils::count_newlines(slice); - let offset = self.buffer.chars().rev().take_while(|c| *c == '\n').count(); - - if newline_count + offset > newline_upper_bound { - if offset >= newline_upper_bound { - newline_count = 0; - } else { - newline_count = newline_upper_bound - offset; - } - } else if newline_count + offset < newline_lower_bound { - if offset >= newline_lower_bound { - newline_count = 0; - } else { - newline_count = newline_lower_bound - offset; - } - } - - let blank_lines = "\n".repeat(newline_count); - self.push_str(&blank_lines); - } - - pub(crate) fn format_comment(&self, span: Span) -> String { - let slice = self.slice(span).trim(); - let pos = slice.find('/'); - - if !slice.is_empty() && pos.is_some() { - slice.to_string() - } else { - String::new() - } - } -} - -pub(crate) fn str_slice(s: &str, start: usize, end: usize) -> &str { - &s[start..ceil_char_boundary(s, end)] -} - -pub(crate) fn ceil_char_boundary(s: &str, byte_index: usize) -> usize { - for i in byte_index..s.len() { - if s.is_char_boundary(i) { - return i; - } - } - s.len() -} - -#[derive(Clone, Copy, Debug, Default)] -pub(crate) struct Indent { - block_indent: usize, -} - -impl Indent { - pub(crate) fn width(&self) -> usize { - self.block_indent - } - - #[track_caller] - pub(crate) fn block_indent(&mut self, config: &Config) { - self.block_indent += config.tab_spaces; - } - - #[track_caller] - pub(crate) fn block_unindent(&mut self, config: &Config) { - self.block_indent -= config.tab_spaces; - } - - pub(crate) fn to_string_with_newline(self) -> String { - "\n".to_string() + &self.to_string() - } - - #[allow(clippy::inherent_to_string)] - pub(crate) fn to_string(self) -> String { - " ".repeat(self.block_indent) - } -} - -#[derive(Clone, Copy, Debug, Default)] -pub(crate) struct Shape { - pub(crate) width: usize, - pub(crate) indent: Indent, -} - -#[derive(PartialEq, Eq, Debug)] -pub(crate) enum ExpressionType { - Statement, - SubExpression, -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/visitor/expr.rs b/noir/noir-repo/tooling/nargo_fmt/src/visitor/expr.rs deleted file mode 100644 index 18b962a7f85..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/visitor/expr.rs +++ /dev/null @@ -1,484 +0,0 @@ -use noirc_frontend::ast::Expression; -use noirc_frontend::ast::{ - BlockExpression, ConstructorExpression, ExpressionKind, IfExpression, Statement, StatementKind, -}; -use noirc_frontend::{hir::resolution::errors::Span, lexer::Lexer, token::Token}; - -use super::{ExpressionType, FmtVisitor, Shape}; -use crate::{ - items::{HasItem, Item, Items}, - rewrite, - utils::{first_line_width, FindToken}, - Config, -}; - -impl FmtVisitor<'_> { - pub(crate) fn visit_expr(&mut self, expr: Expression, expr_type: ExpressionType) { - let span = expr.span; - let rewrite = rewrite::expr(self, expr, expr_type, self.shape()); - self.push_rewrite(rewrite, span); - self.last_position = span.end(); - } - - pub(crate) fn format_if(&self, if_expr: IfExpression) -> String { - let condition_str = rewrite::sub_expr(self, self.shape(), if_expr.condition); - let consequence_str = rewrite::sub_expr(self, self.shape(), if_expr.consequence); - - let mut result = format!("if {condition_str} {consequence_str}"); - - if let Some(alternative) = if_expr.alternative { - let alternative = if let Some(ExpressionKind::If(if_expr)) = - extract_simple_expr(alternative.clone()).map(|expr| expr.kind) - { - self.format_if(*if_expr) - } else { - rewrite::expr(self, alternative, ExpressionType::Statement, self.shape()) - }; - - result.push_str(" else "); - result.push_str(&alternative); - }; - - result - } - - pub(crate) fn format_if_single_line(&self, if_expr: IfExpression) -> Option { - let condition_str = rewrite::sub_expr(self, self.shape(), if_expr.condition); - let consequence_str = - rewrite::sub_expr(self, self.shape(), extract_simple_expr(if_expr.consequence)?); - - let if_str = if let Some(alternative) = if_expr.alternative { - let alternative_str = if let Some(ExpressionKind::If(_)) = - extract_simple_expr(alternative.clone()).map(|expr| expr.kind) - { - return None; - } else { - rewrite::expr( - self, - extract_simple_expr(alternative)?, - ExpressionType::Statement, - self.shape(), - ) - }; - - format!("if {} {{ {} }} else {{ {} }}", condition_str, consequence_str, alternative_str) - } else { - format!("if {{{}}} {{{}}}", condition_str, consequence_str) - }; - - (if_str.len() <= self.config.single_line_if_else_max_width).then_some(if_str) - } - - pub(crate) fn format_struct_lit( - &self, - type_name: &str, - fields_span: Span, - constructor: ConstructorExpression, - ) -> String { - let fields = { - let mut visitor = self.fork(); - let is_unit_struct = constructor.fields.is_empty(); - - visitor.indent.block_indent(visitor.config); - - let nested_indent = visitor.shape(); - let exprs: Vec<_> = - Items::new(&visitor, nested_indent, fields_span, constructor.fields).collect(); - let exprs = format_exprs( - visitor.config, - Tactic::HorizontalVertical, - false, - exprs, - nested_indent, - true, - ); - - visitor.indent.block_unindent(visitor.config); - - if exprs.contains('\n') { - format!( - "{}{exprs}{}", - nested_indent.indent.to_string_with_newline(), - visitor.shape().indent.to_string_with_newline() - ) - } else if is_unit_struct { - exprs - } else { - format!(" {exprs} ") - } - }; - - format!("{type_name} {{{fields}}}") - } - - pub(crate) fn visit_block(&mut self, block: BlockExpression, block_span: Span) { - if block.is_empty() { - self.visit_empty_block(block_span); - return; - } - - self.last_position = block_span.start() + 1; // `{` - self.push_str("{"); - - self.trim_spaces_after_opening_brace(&block.statements); - - self.indent.block_indent(self.config); - - self.visit_stmts(block.statements); - - let span = (self.last_position..block_span.end() - 1).into(); - self.close_block(span); - self.last_position = block_span.end(); - } - - fn trim_spaces_after_opening_brace(&mut self, block: &[Statement]) { - if let Some(first_stmt) = block.first() { - let slice = self.slice(self.last_position..first_stmt.span.start()); - let len = - slice.chars().take_while(|ch| ch.is_whitespace()).collect::().rfind('\n'); - self.last_position += len.unwrap_or(0) as u32; - } - } - - pub(crate) fn visit_empty_block(&mut self, block_span: Span) { - let slice = self.slice(block_span); - let comment_str = slice[1..slice.len() - 1].trim(); - - if comment_str.is_empty() { - self.push_str("{}"); - } else { - self.push_str("{"); - self.indent.block_indent(self.config); - self.close_block(block_span); - }; - - self.last_position = block_span.end(); - } - - pub(crate) fn close_block(&mut self, span: Span) { - let slice = self.slice(span); - - for spanned in Lexer::new(slice).skip_comments(false).flatten() { - match spanned.token() { - Token::LineComment(_, _) | Token::BlockComment(_, _) => { - let token_span = spanned.to_span(); - - let offset = token_span.start(); - let sub_slice = &slice[token_span.start() as usize..token_span.end() as usize]; - - let span_in_between = span.start()..span.start() + offset; - let slice_in_between = self.slice(span_in_between); - let comment_on_same_line = !slice_in_between.contains('\n'); - - if comment_on_same_line { - self.push_str(" "); - self.push_str(sub_slice); - } else { - self.push_str(&self.indent.to_string_with_newline()); - self.push_str(sub_slice); - } - } - _ => {} - } - } - - self.indent.block_unindent(self.config); - self.push_str(&self.indent.to_string_with_newline()); - self.push_str("}"); - } -} - -// TODO: fixme -#[allow(clippy::too_many_arguments)] -pub(crate) fn format_seq( - shape: Shape, - prefix: &str, - suffix: &str, - visitor: FmtVisitor, - trailing_comma: bool, - exprs: Vec, - span: Span, - tactic: Tactic, - mode: NewlineMode, - reduce: bool, -) -> String { - let mut nested_indent = shape; - - nested_indent.indent.block_indent(visitor.config); - - let exprs: Vec<_> = Items::new(&visitor, nested_indent, span, exprs).collect(); - let exprs = format_exprs(visitor.config, tactic, trailing_comma, exprs, nested_indent, reduce); - - wrap_exprs(prefix, suffix, exprs, nested_indent, shape, mode) -} - -pub(crate) fn format_brackets( - visitor: FmtVisitor, - trailing_comma: bool, - exprs: Vec, - span: Span, -) -> String { - let array_width = visitor.config.array_width; - format_seq( - visitor.shape(), - "[", - "]", - visitor, - trailing_comma, - exprs, - span, - Tactic::LimitedHorizontalVertical(array_width), - NewlineMode::Normal, - false, - ) -} - -// TODO: fixme -#[allow(clippy::too_many_arguments)] -pub(crate) fn format_parens( - max_width: Option, - visitor: FmtVisitor, - shape: Shape, - trailing_comma: bool, - exprs: Vec, - span: Span, - reduce: bool, - mode: NewlineMode, -) -> String { - let tactic = max_width.map(Tactic::LimitedHorizontalVertical).unwrap_or(Tactic::Horizontal); - format_seq(shape, "(", ")", visitor, trailing_comma, exprs, span, tactic, mode, reduce) -} - -pub(crate) fn format_exprs( - config: &Config, - tactic: Tactic, - trailing_comma: bool, - exprs: Vec, - shape: Shape, - reduce: bool, -) -> String { - let mut result = String::new(); - let indent_str = shape.indent.to_string(); - - let tactic = tactic.definitive(&exprs, config.short_array_element_width_threshold, reduce); - let mut exprs = exprs.into_iter().enumerate().peekable(); - let mut line_len = 0; - let mut prev_expr_trailing_comment = false; - - while let Some((index, expr)) = exprs.next() { - let is_first = index == 0; - let separate = exprs.peek().is_some() || trailing_comma; - let separate_len = usize::from(separate); - - match tactic { - DefinitiveTactic::Vertical - if !is_first && !expr.value.is_empty() && !result.is_empty() => - { - result.push('\n'); - result.push_str(&indent_str); - } - DefinitiveTactic::Horizontal if !is_first => { - result.push(' '); - } - DefinitiveTactic::Mixed => { - let total_width = expr.total_width() + separate_len; - - if line_len > 0 && line_len + 1 + total_width > shape.width - || prev_expr_trailing_comment - { - result.push('\n'); - result.push_str(&indent_str); - line_len = 0; - } else if line_len > 0 { - result.push(' '); - line_len += 1; - } - - line_len += total_width; - } - _ => {} - } - - result.push_str(&expr.leading); - - if expr.different_line { - result.push('\n'); - result.push_str(&indent_str); - line_len = expr.value.chars().count(); - } else if !expr.leading.is_empty() { - result.push(' '); - } - - result.push_str(&expr.value); - - if tactic == DefinitiveTactic::Horizontal { - result.push_str(&expr.trailing); - } - - if separate && expr.trailing.find_token(Token::Comma).is_none() { - result.push(','); - } - - if tactic != DefinitiveTactic::Horizontal { - prev_expr_trailing_comment = !expr.trailing.is_empty(); - - if !expr.different_line && !expr.trailing.is_empty() { - result.push(' '); - } - - result.push_str(&expr.trailing); - } - } - - result -} - -#[derive(PartialEq, Eq)] -pub(crate) enum NewlineMode { - IfContainsNewLine, - IfContainsNewLineAndWidth, - Normal, -} - -pub(crate) fn wrap_exprs( - prefix: &str, - suffix: &str, - exprs: String, - nested_shape: Shape, - shape: Shape, - newline_mode: NewlineMode, -) -> String { - let mut force_one_line = if newline_mode == NewlineMode::IfContainsNewLine { - true - } else { - first_line_width(&exprs) <= shape.width - }; - - if matches!( - newline_mode, - NewlineMode::IfContainsNewLine | NewlineMode::IfContainsNewLineAndWidth - ) && force_one_line - { - force_one_line = !exprs.contains('\n'); - } - - if force_one_line { - let allow_trailing_newline = exprs - .lines() - .last() - .unwrap_or_default() - .find_token_with(|token| matches!(token, Token::LineComment(_, _))) - .is_some(); - - let trailing_newline = if allow_trailing_newline { - shape.indent.to_string_with_newline() - } else { - String::new() - }; - - format!("{prefix}{exprs}{trailing_newline}{suffix}") - } else { - let nested_indent_str = nested_shape.indent.to_string_with_newline(); - let indent_str = shape.indent.to_string_with_newline(); - - format!("{prefix}{nested_indent_str}{exprs}{indent_str}{suffix}") - } -} - -#[derive(PartialEq, Eq, Clone, Copy)] -pub(crate) enum Tactic { - Horizontal, - HorizontalVertical, - LimitedHorizontalVertical(usize), - Mixed, -} - -impl Tactic { - fn definitive( - self, - exprs: &[Item], - short_width_threshold: usize, - reduce: bool, - ) -> DefinitiveTactic { - let tactic = || { - let has_single_line_comment = exprs.iter().any(|item| { - has_single_line_comment(&item.leading) || has_single_line_comment(&item.trailing) - }); - - let limit = match self { - _ if has_single_line_comment => return DefinitiveTactic::Vertical, - - Tactic::Horizontal => return DefinitiveTactic::Horizontal, - Tactic::LimitedHorizontalVertical(limit) => limit, - Tactic::HorizontalVertical | Tactic::Mixed => 100, - }; - - let (sep_count, total_width): (usize, usize) = exprs - .iter() - .map(|expr| expr.total_width()) - .fold((0, 0), |(sep_count, total_width), width| { - (sep_count + 1, total_width + width) - }); - - let total_sep_len = sep_count.saturating_sub(1); - let real_total = total_width + total_sep_len; - - if real_total <= limit && !exprs.iter().any(|expr| expr.is_multiline()) { - DefinitiveTactic::Horizontal - } else if self == Tactic::Mixed { - DefinitiveTactic::Mixed - } else { - DefinitiveTactic::Vertical - } - }; - - let definitive_tactic = tactic(); - if reduce { - definitive_tactic.reduce(exprs, short_width_threshold) - } else { - definitive_tactic - } - } -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -enum DefinitiveTactic { - Vertical, - Horizontal, - Mixed, -} - -impl DefinitiveTactic { - fn reduce(self, exprs: &[Item], short_array_element_width_threshold: usize) -> Self { - match self { - DefinitiveTactic::Vertical - if no_long_exprs(exprs, short_array_element_width_threshold) => - { - DefinitiveTactic::Mixed - } - DefinitiveTactic::Vertical | DefinitiveTactic::Horizontal | DefinitiveTactic::Mixed => { - self - } - } - } -} - -fn has_single_line_comment(slice: &str) -> bool { - slice.trim_start().starts_with("//") -} - -fn no_long_exprs(exprs: &[Item], max_width: usize) -> bool { - exprs.iter().all(|expr| expr.value.len() <= max_width) -} - -fn extract_simple_expr(expr: Expression) -> Option { - if let ExpressionKind::Block(mut block) = expr.kind { - if block.len() == 1 { - if let StatementKind::Expression(expr) = block.pop().unwrap() { - return expr.into(); - } - } - } - - None -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs b/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs deleted file mode 100644 index 4724c8d957d..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs +++ /dev/null @@ -1,439 +0,0 @@ -use crate::{ - rewrite::{self, UseTree}, - utils::{ - append_space_if_nonempty, last_line_contains_single_line_comment, last_line_used_width, - FindToken, - }, - visitor::expr::{format_seq, NewlineMode}, -}; -use noirc_frontend::{ - ast::{ItemVisibility, NoirFunction, TraitImplItemKind, UnresolvedTypeData, Visibility}, - lexer::Lexer, - token::{SecondaryAttribute, TokenKind}, -}; -use noirc_frontend::{ - hir::resolution::errors::Span, - parser::{Item, ItemKind}, - token::{Keyword, Token}, - ParsedModule, -}; - -use super::{ - expr::Tactic::{HorizontalVertical, LimitedHorizontalVertical}, - Shape, -}; - -impl super::FmtVisitor<'_> { - fn format_fn_before_block(&self, func: NoirFunction, start: u32) -> (String, bool) { - let name_span = func.name_ident().span(); - let func_span = func.span(); - - let fn_header = self.slice(start..name_span.end()); - let mut result = self.format_fn_header(fn_header, &func); - - let params_open = - self.span_before(name_span.end()..func_span.start(), Token::LeftParen).start(); - - let last_span = if func.parameters().is_empty() { - params_open..func_span.start() - } else { - func.parameters().last().unwrap().span.end()..func_span.start() - }; - - let params_end = self.span_after(last_span, Token::RightParen).start(); - - let params_span = params_open..params_end; - let return_type_span = func.return_type().span; - let return_type = self.format_return_type(return_type_span, &func, func_span, params_end); - let parameters = func.def.parameters; - - if !func.def.generics.is_empty() { - let full_span = name_span.end()..params_open; - let start = self.span_before(full_span.clone(), Token::Less).start(); - let end = self.span_after(full_span, Token::Greater).start(); - - let generics = func.def.generics; - let span = (start..end).into(); - let generics = format_seq( - self.shape(), - "<", - ">", - self.fork(), - false, - generics, - span, - HorizontalVertical, - NewlineMode::IfContainsNewLine, - false, - ); - - result.push_str(&generics); - } - - let parameters = if parameters.is_empty() { - self.slice(params_span).into() - } else { - let fn_start = result - .find_token_with(|token| { - matches!(token, Token::Keyword(Keyword::Fn | Keyword::Unconstrained)) - }) - .unwrap() - .start(); - - let slice = self.slice(fn_start..result.len() as u32); - let indent = self.indent; - let used_width = last_line_used_width(slice, indent.width()); - let overhead = if return_type.is_empty() { 2 } else { 3 }; // 2 = `()`, 3 = `() ` - let one_line_budget = self.budget(used_width + return_type.len() + overhead); - let shape = Shape { width: one_line_budget, indent }; - - let tactic = LimitedHorizontalVertical(one_line_budget); - - format_seq( - shape, - "(", - ")", - self.fork(), - false, - parameters, - params_span.into(), - tactic, - NewlineMode::IfContainsNewLine, - false, - ) - }; - - result.push_str(¶meters); - result.push_str(&return_type); - - let maybe_comment = self.slice(params_end..func_span.start()); - - (result.trim_end().to_string(), last_line_contains_single_line_comment(maybe_comment)) - } - - // This formats the function outer doc comments, attributes, modifiers, and `fn name`. - fn format_fn_header(&self, src: &str, func: &NoirFunction) -> String { - let mut result = String::new(); - let mut lexer = Lexer::new(src).skip_comments(false).peekable(); - - // First there might be outer doc comments - while let Some(Ok(token)) = lexer.peek() { - if token.kind() == TokenKind::OuterDocComment { - result.push_str(&token.to_string()); - result.push('\n'); - result.push_str(&self.indent.to_string()); - lexer.next(); - - self.append_comments_if_any(&mut lexer, &mut result); - } else { - break; - } - } - - // Then, optionally, attributes - while let Some(Ok(token)) = lexer.peek() { - if token.kind() == TokenKind::Attribute { - result.push_str(&token.to_string()); - result.push('\n'); - result.push_str(&self.indent.to_string()); - lexer.next(); - - self.append_comments_if_any(&mut lexer, &mut result); - } else { - break; - } - } - - self.append_comments_if_any(&mut lexer, &mut result); - - // Then, optionally, the `unconstrained` keyword - // (eventually we'll stop accepting this, but we keep it for backwards compatibility) - if let Some(Ok(token)) = lexer.peek() { - if let Token::Keyword(Keyword::Unconstrained) = token.token() { - lexer.next(); - } - } - - self.append_comments_if_any(&mut lexer, &mut result); - - // Then the visibility - let mut has_visibility = false; - if let Some(Ok(token)) = lexer.peek() { - if let Token::Keyword(Keyword::Pub) = token.token() { - has_visibility = true; - lexer.next(); - if let Some(Ok(token)) = lexer.peek() { - if let Token::LeftParen = token.token() { - lexer.next(); // Skip '(' - lexer.next(); // Skip 'crate' - lexer.next(); // Skip ')' - } - } - } - } - - if has_visibility { - result.push_str(&func.def.visibility.to_string()); - result.push(' '); - } - - self.append_comments_if_any(&mut lexer, &mut result); - - // Then, optionally, and again, the `unconstrained` keyword - if let Some(Ok(token)) = lexer.peek() { - if let Token::Keyword(Keyword::Unconstrained) = token.token() { - lexer.next(); - } - } - - if func.def.is_unconstrained { - result.push_str("unconstrained "); - } - - self.append_comments_if_any(&mut lexer, &mut result); - - // Then, optionally, the `comptime` keyword - if let Some(Ok(token)) = lexer.peek() { - if let Token::Keyword(Keyword::Comptime) = token.token() { - lexer.next(); - } - } - - if func.def.is_comptime { - result.push_str("comptime "); - } - - self.append_comments_if_any(&mut lexer, &mut result); - - // Then the `fn` keyword - lexer.next(); // Skip fn - result.push_str("fn "); - - self.append_comments_if_any(&mut lexer, &mut result); - - // Then the function name - result.push_str(&func.def.name.0.contents); - - result - } - - fn append_comments_if_any( - &self, - lexer: &mut std::iter::Peekable>, - result: &mut String, - ) { - while let Some(Ok(token)) = lexer.peek() { - match token.token() { - Token::LineComment(..) => { - result.push_str(&token.to_string()); - result.push('\n'); - result.push_str(&self.indent.to_string()); - lexer.next(); - } - Token::BlockComment(..) => { - result.push_str(&token.to_string()); - lexer.next(); - } - _ => break, - } - } - } - - fn format_return_type( - &self, - span: Span, - func: &NoirFunction, - func_span: Span, - params_end: u32, - ) -> String { - let mut result = String::new(); - - if func.return_type().typ == UnresolvedTypeData::Unit { - result.push_str(self.slice(params_end..func_span.start())); - } else { - result.push_str(" -> "); - - let visibility = match func.def.return_visibility { - Visibility::Public => "pub", - Visibility::ReturnData => "return_data", - Visibility::Private => "", - Visibility::CallData(_) => { - unreachable!("call_data cannot be used for return value") - } - }; - result.push_str(&append_space_if_nonempty(visibility.into())); - - let typ = rewrite::typ(self, self.shape(), func.return_type()); - result.push_str(&typ); - - let slice = self.slice(span.end()..func_span.start()); - if !slice.trim().is_empty() { - result.push_str(slice); - } - } - - result - } - - pub(crate) fn visit_file(&mut self, module: ParsedModule) { - self.visit_module(module); - self.format_missing_indent(self.source.len() as u32, false); - } - - fn visit_module(&mut self, module: ParsedModule) { - for Item { kind, span, doc_comments } in module.items { - match kind { - ItemKind::Function(func) => { - self.visit_function(span, func); - } - ItemKind::Submodules(module) => { - self.format_missing_indent(span.start(), true); - - if std::mem::take(&mut self.ignore_next_node) { - self.push_str(self.slice(span)); - self.last_position = span.end(); - continue; - } - - for doc_comment in doc_comments { - self.push_str(&format!("///{doc_comment}\n")); - self.push_str(&self.indent.to_string()); - } - - for attribute in module.outer_attributes { - let is_tag = matches!(attribute, SecondaryAttribute::Tag(_)); - let tag = if is_tag { "'" } else { "" }; - self.push_str(&format!("#[{tag}{}]\n", attribute.as_ref())); - self.push_str(&self.indent.to_string()); - } - - let name = module.name; - let after_brace = self.span_after(span, Token::LeftBrace).start(); - self.last_position = after_brace; - - let visibility = module.visibility; - if visibility != ItemVisibility::Private { - self.push_str(&format!("{visibility} ")); - } - - let keyword = if module.is_contract { "contract" } else { "mod" }; - self.push_str(&format!("{keyword} {name} ")); - - if module.contents.items.is_empty() { - self.visit_empty_block((after_brace - 1..span.end()).into()); - continue; - } else { - self.push_str("{"); - self.indent.block_indent(self.config); - self.visit_module(module.contents); - } - - self.close_block((self.last_position..span.end() - 1).into()); - self.last_position = span.end(); - } - ItemKind::Impl(impl_) => { - self.format_missing_indent(span.start(), true); - - if std::mem::take(&mut self.ignore_next_node) { - self.push_str(self.slice(span)); - self.last_position = span.end(); - continue; - } - - let before_brace = self.span_before(span, Token::LeftBrace).start(); - let slice = self.slice(self.last_position..before_brace).trim(); - let after_brace = self.span_after(span, Token::LeftBrace).start(); - self.last_position = after_brace; - - self.push_str(&format!("{slice} ")); - - if impl_.methods.is_empty() { - self.visit_empty_block((after_brace - 1..span.end()).into()); - continue; - } else { - self.push_str("{"); - self.indent.block_indent(self.config); - - for (method, span) in impl_.methods { - self.visit_function(span, method.item); - } - - self.close_block((self.last_position..span.end() - 1).into()); - self.last_position = span.end(); - } - } - ItemKind::TraitImpl(noir_trait_impl) => { - self.format_missing_indent(span.start(), true); - - if std::mem::take(&mut self.ignore_next_node) { - self.push_str(self.slice(span)); - self.last_position = span.end(); - continue; - } - - let before_brace = self.span_before(span, Token::LeftBrace).start(); - let slice = self.slice(self.last_position..before_brace).trim(); - let after_brace = self.span_after(span, Token::LeftBrace).start(); - self.last_position = after_brace; - - self.push_str(&format!("{slice} ")); - - if noir_trait_impl.items.is_empty() { - self.visit_empty_block((after_brace - 1..span.end()).into()); - continue; - } else { - self.push_str("{"); - self.indent.block_indent(self.config); - - for documented_item in noir_trait_impl.items { - let span = documented_item.item.span; - match documented_item.item.kind { - TraitImplItemKind::Function(method) => { - self.visit_function(span, method); - } - TraitImplItemKind::Constant(..) - | TraitImplItemKind::Type { .. } => { - self.push_rewrite(self.slice(span).to_string(), span); - self.last_position = span.end(); - } - } - } - - self.close_block((self.last_position..span.end() - 1).into()); - self.last_position = span.end(); - } - } - ItemKind::Import(use_tree, visibility) => { - let use_tree = UseTree::from_ast(use_tree); - let use_tree = use_tree.rewrite_top_level(self, self.shape(), visibility); - self.push_rewrite(use_tree, span); - self.last_position = span.end(); - } - - ItemKind::Struct(_) - | ItemKind::Trait(_) - | ItemKind::TypeAlias(_) - | ItemKind::Global(..) - | ItemKind::ModuleDecl(_) - | ItemKind::InnerAttribute(_) => { - self.push_rewrite(self.slice(span).to_string(), span); - self.last_position = span.end(); - } - } - } - } - - fn visit_function(&mut self, span: Span, func: NoirFunction) { - self.format_missing_indent(span.start(), true); - if std::mem::take(&mut self.ignore_next_node) { - self.push_str(self.slice(span)); - self.last_position = span.end(); - return; - } - let (fn_before_block, force_brace_newline) = - self.format_fn_before_block(func.clone(), span.start()); - self.push_str(&fn_before_block); - self.push_str(if force_brace_newline { "\n" } else { " " }); - self.visit_block(func.def.body, func.def.span); - } -} diff --git a/noir/noir-repo/tooling/nargo_fmt/src/visitor/stmt.rs b/noir/noir-repo/tooling/nargo_fmt/src/visitor/stmt.rs deleted file mode 100644 index 7696c4c5fd4..00000000000 --- a/noir/noir-repo/tooling/nargo_fmt/src/visitor/stmt.rs +++ /dev/null @@ -1,98 +0,0 @@ -use std::iter::zip; - -use noirc_errors::Span; - -use noirc_frontend::ast::{ - ConstrainKind, ConstrainStatement, ForBounds, ForRange, Statement, StatementKind, -}; - -use crate::{rewrite, visitor::expr::wrap_exprs}; - -use super::{expr::NewlineMode, ExpressionType}; - -impl super::FmtVisitor<'_> { - pub(crate) fn visit_stmts(&mut self, stmts: Vec) { - let len = stmts.len(); - - for (Statement { kind, span }, index) in zip(stmts, 1..) { - let is_last = index == len; - self.visit_stmt(kind, span, is_last); - self.last_position = span.end(); - } - } - - fn visit_stmt(&mut self, kind: StatementKind, span: Span, is_last: bool) { - match kind { - StatementKind::Expression(expr) => self.visit_expr( - expr, - if is_last { ExpressionType::SubExpression } else { ExpressionType::Statement }, - ), - StatementKind::Semi(expr) => { - self.visit_expr(expr, ExpressionType::Statement); - self.push_str(";"); - } - StatementKind::Let(let_stmt) => { - let let_str = self.slice(span.start()..let_stmt.expression.span.start()).trim_end(); - - let expr_str = rewrite::sub_expr(self, self.shape(), let_stmt.expression); - - self.push_rewrite(format!("{let_str} {expr_str};"), span); - } - StatementKind::Constrain(ConstrainStatement { kind, arguments, span: _ }) => { - let mut nested_shape = self.shape(); - let shape = nested_shape; - - nested_shape.indent.block_indent(self.config); - - let callee = match kind { - ConstrainKind::Assert | ConstrainKind::Constrain => "assert", - ConstrainKind::AssertEq => "assert_eq", - }; - let args = arguments - .into_iter() - .map(|arg| rewrite::sub_expr(self, nested_shape, arg)) - .collect::>() - .join(", "); - - let args = wrap_exprs( - "(", - ")", - args, - nested_shape, - shape, - NewlineMode::IfContainsNewLineAndWidth, - ); - let constrain = format!("{callee}{args};"); - - self.push_rewrite(constrain, span); - } - StatementKind::For(for_stmt) => { - let identifier = self.slice(for_stmt.identifier.span()); - let range = match for_stmt.range { - ForRange::Range(ForBounds { start, end, inclusive }) => format!( - "{}{}{}", - rewrite::sub_expr(self, self.shape(), start), - if inclusive { "..=" } else { ".." }, - rewrite::sub_expr(self, self.shape(), end) - ), - - ForRange::Array(array) => rewrite::sub_expr(self, self.shape(), array), - }; - let block = rewrite::sub_expr(self, self.shape(), for_stmt.block); - - let result = format!("for {identifier} in {range} {block}"); - self.push_rewrite(result, span); - } - StatementKind::Assign(_) => { - self.push_rewrite(self.slice(span).to_string(), span); - } - StatementKind::Error => unreachable!(), - StatementKind::Break => self.push_rewrite("break;".into(), span), - StatementKind::Continue => self.push_rewrite("continue;".into(), span), - StatementKind::Comptime(statement) => self.visit_stmt(statement.kind, span, is_last), - StatementKind::Interned(_) => unreachable!( - "StatementKind::Resolved should only emitted by the comptime interpreter" - ), - } - } -} diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/array.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/array.nr index 3341afb31a5..b8e7d051368 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/array.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/array.nr @@ -1,37 +1,51 @@ fn big_array() { [ - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000, + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, + 10000000000000000, + 100000000000000000, + 1000000000000000000, 10000000000000000000, 100000000000000000000, 1000000000000000000000, 10000000000000000000000, 100000000000000000000000, - 1000000000000000000000000 + 1000000000000000000000000, ]; - [ - 1, - 10 - ]; + [1, 10]; [ // hello! - 1, - 10 + 1, 10, ]; [ // hello! 1, // asd - 10 + 10, ]; [ // hello! 1, // asd - 10 + 10, // asdasd ]; diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/call.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/call.nr index de78d7c4edb..8a1a529dfb7 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/call.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/call.nr @@ -3,12 +3,12 @@ fn foo() { outer_function( some_function(), // Original inner function call - another_function() // Original inner function call + another_function(), // Original inner function call ); outer_function( some_function(), // Original inner function call - another_function() // Original inner function call + another_function(), // Original inner function call ); my_function( @@ -16,17 +16,17 @@ fn foo() { some_value, /* Multiline Comment */ - another_func(20, 30) + another_func(20, 30), ); my_function( some_function(10, "arg1", another_function()), - another_func(20, some_function(), 30) + another_func(20, some_function(), 30), ); outer_function( some_function(), - another_function(some_function(), some_value) + another_function(some_function(), some_value), ); assert_eq(x, y); @@ -39,12 +39,8 @@ fn foo() { assert(x == y); - assert( - p4_affine.eq( - Gaffine::new( - 6890855772600357754907169075114257697580319025794532037257385534741338397365, - 4338620300185947561074059802482547481416142213883829469920100239455078257889 - ) - ) - ); + assert(p4_affine.eq(Gaffine::new( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889, + ))); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr index cb7505f845c..28e4ccd8ffe 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/contract.nr @@ -5,13 +5,16 @@ contract Benchmarking { use aztec::protocol_types::abis::function_selector::FunctionSelector; - use value_note::{utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}}; + use value_note::{ + utils::{increment, decrement}, value_note::{VALUE_NOTE_LEN, ValueNote, ValueNoteMethods}, + }; use aztec::{ context::Context, note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader}, log::emit_unencrypted_log, state_vars::{Map, PublicMutable, PrivateSet}, - types::type_serialization::field_serialization::{FieldSerializationMethods, FIELD_SERIALIZED_LEN}, - types::address::AztecAddress + types::type_serialization::field_serialization::{ + FieldSerializationMethods, FIELD_SERIALIZED_LEN, + }, types::address::AztecAddress, }; struct Storage { @@ -25,13 +28,15 @@ contract Benchmarking { notes: Map::new( context, 1, - |context, slot| { PrivateSet::new(context, slot, ValueNoteMethods) } + |context, slot| { PrivateSet::new(context, slot, ValueNoteMethods) }, ), balances: Map::new( context, 2, - |context, slot| { PublicMutable::new(context, slot, FieldSerializationMethods) } - ) + |context, slot| { + PublicMutable::new(context, slot, FieldSerializationMethods) + }, + ), } } } @@ -63,10 +68,8 @@ contract Benchmarking { storage.balances.at(owner).write(current + value); let _callStackItem1 = context.call_public_function( context.this_address(), - comptime { - FunctionSelector::from_signature("broadcast(Field)") - }, - [owner] + comptime { FunctionSelector::from_signature("broadcast(Field)") }, + [owner], ); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/empty.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/empty.nr index e69de29bb2d..8b137891791 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/empty.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/empty.nr @@ -0,0 +1 @@ + diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/expr.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/expr.nr index babaf5b356e..9bee940f900 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/expr.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/expr.nr @@ -2,8 +2,7 @@ fn qux() { {} - { /* a block with a comment */ - } + { /* a block with a comment */ } {} { // A block with a comment. @@ -96,11 +95,12 @@ fn parenthesized() { } fn parenthesized() { - value + (/*test*/x as Field/*test*/) + value + ( /*test*/ x as Field /*test*/) } fn parenthesized() { - value + ( + value + + ( // line x as Field ) @@ -117,21 +117,23 @@ fn if_expr() { } fn return_if_expr() { - if true { 42 } else { 40 + 2 } + if true { + 42 + } else { + 40 + 2 + } } fn return_if_expr() { + if true { 42 }; + if true { 42 - }; - - if true { 42 } else { 40 + 2 } + } else { + 40 + 2 + } } fn if_if() { - (if cond { - some(); - } else { - none(); - }).bar().baz(); + (if cond { some(); } else { none(); }).bar().baz(); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr index 19f022751c4..afdb8883e15 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr @@ -2,7 +2,11 @@ fn main(x: pub u8, y: u8) {} fn main(x: pub u8, y: u8) -> pub Field {} -fn main(x: A, y: B) -> pub Field where A: Eq, B: Eq {} +fn main(x: A, y: B) -> pub Field +where + A: Eq, + B: Eq, +{} fn main() // hello @@ -14,10 +18,13 @@ fn main( fn main( // hello - unit: () + unit: (), ) {} -fn main() where T: Eq {} +fn main() +where + T: Eq, +{} fn main( tape: [Field; TAPE_LEN], @@ -25,7 +32,7 @@ fn main( initial_memory: [Field; MEM_COUNT], initial_program_counter: Field, initial_call_stack: [Field; MAX_CALL_STACK], - initial_call_stack_pointer: u64 + initial_call_stack_pointer: u64, ) -> pub ExecutionResult {} fn apply_binary_field_op( @@ -33,7 +40,7 @@ fn apply_binary_field_op( rhs: RegisterIndex, result: RegisterIndex, op: u8, - registers: &mut Registers + registers: &mut Registers, ) -> bool {} fn main() -> pub [Field; 2] {} @@ -57,7 +64,7 @@ fn main( message_field: Field, pub_key_x: Field, pub_key_y: Field, - signature: [u8; 64] + signature: [u8; 64], ) {} pub fn from_baz(x: [Field; crate::foo::MAGIC_NUMBER]) {} diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/if.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/if.nr index 39ad7d18cdd..fa0d10a819b 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/if.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/if.nr @@ -1,13 +1,17 @@ //@error_on_lost_comment=false fn main() { - let (x,y) = if is_square(gx1) { + let (x, y) = if is_square(gx1) { (x1, sqrt(gx1)) } else { (x2, sqrt(gx2)) }; let n = if x != y { - if x != 20 { slice.push_back(y) } else { slice } + if x != 20 { + slice.push_back(y) + } else { + slice + } } else { slice }; @@ -39,8 +43,7 @@ fn main() { if true // else-if-chain if comment { (); - } - else if false // else-if-chain else-if comment + } else if false // else-if-chain else-if comment { (); (); diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/ignore.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/ignore.nr index 1c84e178f34..6e957539405 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/ignore.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/ignore.nr @@ -24,3 +24,4 @@ fn mk_array() { ]; let array = [1]; } + diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl.nr index 84394f6fa1d..d3f986ca943 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl.nr @@ -14,8 +14,6 @@ impl MyType { fn method(self: Self) {} fn method(mut self: Self) {} - - fn method(&mut self: Self) {} } impl MyType { @@ -26,7 +24,10 @@ impl MyType { fn method(self) {} } -impl MyStruct where T: MyEq { +impl MyStruct +where + T: MyEq, +{ fn my_eq(self, other: Self) -> bool { (self.a == other.a) & self.b.my_eq(other.b) } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl_trait_fn_parameter.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl_trait_fn_parameter.nr index 5ace5c60dcf..f931a06c96c 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl_trait_fn_parameter.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/impl_trait_fn_parameter.nr @@ -1,3 +1,6 @@ fn func_name(x: impl Eq) {} -fn func_name(x: impl Eq, y: T) where T: SomeTrait + Eq {} +fn func_name(x: impl Eq, y: T) +where + T: SomeTrait + Eq, +{} diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/index.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/index.nr index 54f2ed2cf39..74356a9013f 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/index.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/index.nr @@ -4,6 +4,8 @@ fn foo() { arr[2]; arr[/*test*/ 2]; arr[2/*test*/]; - arr[// test - 2]; + arr[ + // test + 2 + ]; } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/infix.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/infix.nr index 228dfdf68c4..7a43f4a70a1 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/infix.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/infix.nr @@ -4,17 +4,17 @@ fn foo() { !40 + 2; 40 + 2 == 42; - 40/*test*/ + 2 == 42; - 40 + 2/*test*/ == 42; + 40 /*test*/ + 2 == 42; + 40 + 2 /*test*/ == 42; } fn big() { assert( bjj_affine.contains(bjj_affine.gen) - & bjj_affine.contains(p1_affine) - & bjj_affine.contains(p2_affine) - & bjj_affine.contains(p3_affine) - & bjj_affine.contains(p4_affine) - & bjj_affine.contains(p5_affine) + & bjj_affine.contains(p1_affine) + & bjj_affine.contains(p2_affine) + & bjj_affine.contains(p3_affine) + & bjj_affine.contains(p4_affine) + & bjj_affine.contains(p5_affine), ); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/let.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/let.nr index 0edc0eaf922..b5806d5f3d3 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/let.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/let.nr @@ -2,31 +2,36 @@ fn let_() { let fn_call = my_function( some_function(10, "arg1", another_function()), - another_func(20, some_function(), 30) + another_func(20, some_function(), 30), ); let array = [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18]]]; let padded_sha256_hash: [u8; 259] = [ // Padded hash - 209, 50, 135, 178, 4, 155, 190, 229, 228, 111, 61, 174, 8, 49, 48, 116, 90, 226, 77, 7, 111, 27, 19, 113, 154, 48, 138, 136, 138, 15, 230, 132, 32, 4, 0, 5, 1, 2, 4, 3, 101, 1, 72, 134, 96, 9, 6, 13, 48, 49, - 48, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, + 209, 50, 135, 178, 4, 155, 190, 229, 228, 111, 61, 174, 8, 49, 48, 116, 90, 226, 77, 7, 111, + 27, 19, 113, 154, 48, 138, 136, 138, 15, 230, 132, 32, 4, 0, 5, 1, 2, 4, 3, 101, 1, 72, 134, + 96, 9, 6, 13, 48, 49, 48, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, // Rest is padded with 0s until max bytes - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let a = BigUint56 { limbs: [ - 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ] + 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + ], }; let person = Person { first_name: "John", last_name: "Doe", - home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345" } + home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345" }, }; let person = Person { @@ -39,21 +44,25 @@ fn let_() { master: Person { first_name: "John", last_name: "Doe", - home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345" } - } - } + home_address: Address { + street: "123 Main St", + city: "Exampleville", + zip_code: "12345", + }, + }, + }, }; let expr = MyExpr { // A boolean literal (true, false). - kind: ExprKind::Bool(true) + kind: ExprKind::Bool(true), }; let expr = MyExpr { /*A boolean literal (true, false).*/ kind: ExprKind::Bool(true) }; let mut V = crate2::MyStruct { Q: x }; let mut V = crate2::MyStruct {}; - let mut V = crate2::MyStruct {/*test*/}; + let mut V = crate2::MyStruct { /*test*/ }; let mut V = crate2::MyStruct { // sad }; diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr index 1d153b02078..9f8fb53d5cd 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr @@ -4,7 +4,7 @@ mod a { mod b { struct Data { - a: Field + a: Field, } } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/parens.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/parens.nr index e6c4f91879c..5ff0acf7330 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/parens.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/parens.nr @@ -23,23 +23,27 @@ fn main(x: u64, y: pub u64) { ) ); - (/*a*/( - // test - 1 - )/*b*/); + ( + /*a*/ + ( + // test + 1 + ) + /*b*/ + ); ( // test 1 ); - (/*a*/1); + ( /*a*/ 1); - (1/*b*/); + (1 /*b*/); - (/*c*/1/*d*/); + ( /*c*/ 1 /*d*/); - (/*test*/1/*test 2*/); + ( /*test*/ 1 /*test 2*/); (()); (()); diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/struct.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/struct.nr index f3651de607d..d7a0cfc6d7c 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/struct.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/struct.nr @@ -26,7 +26,7 @@ impl Pair { struct Nested { a: Field, - b: Field + b: Field, } struct MyStruct { my_bool: bool, diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr index c3b32904f15..d4b8b239815 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/tuple.nr @@ -1,32 +1,52 @@ fn main() { (1,); - (// hello - 1,); - (/*hello*/ 1,); + ( + // hello + 1, + ); + ( /*hello*/ 1,); (1/*hello*/,); (1,); - (/*test*/ 1,); - (/*a*/ 1/*b*/,); - (/*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/); - (/*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/); + ( /*test*/ 1,); + ( /*a*/ 1/*b*/,); + ( /*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/); + ( /*a*/ 1/*b*/, /*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/); - (1/*1*/, 2/* 2*/); + (1 /*1*/, 2 /* 2*/); - (1/*test*/,); + (1 /*test*/,); - (// - 1,); + ( + // + 1, + ); - (// 1 - 1, // 2, - 2); + ( + // 1 + 1, + // 2, + 2, + ); - (/*1*/ 1, /*2*/ 2); + ( /*1*/ 1, /*2*/ 2); - // FIXME: - (((//2 - 1,),),); - (/*a*/ - 1/*b*/, -/*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/); + ( + ( + ( + //2 + 1, + ), + ), + ); + ( + /*a*/ + 1 + /*b*/, + /*c*/ + 2/*d*/, + /*c*/ + 2/*d*/, + /*e*/ + 3,/*f*/ + ); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_call.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_call.nr index bcf0df9a969..aac36db7985 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_call.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_call.nr @@ -3,6 +3,6 @@ fn foo() { outer_function::( some_function(), // Original inner function call - another_function() // Original inner function call + another_function(), // Original inner function call ); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_method_call.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_method_call.nr index 52fa3db2ac9..cd09d7fea56 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_method_call.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/turbofish_method_call.nr @@ -1,12 +1,8 @@ fn foo() { my_object.some_method::(10, var_value, inner_method::(20, 30)); - assert( - p4_affine.eq::( - Gaffine::new::( - 6890855772600357754907169075114257697580319025794532037257385534741338397365, - 4338620300185947561074059802482547481416142213883829469920100239455078257889 - ) - ) - ); + assert(p4_affine.eq::(Gaffine::new::( + 6890855772600357754907169075114257697580319025794532037257385534741338397365, + 4338620300185947561074059802482547481416142213883829469920100239455078257889, + ))); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/vec.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/vec.nr index 466c9844e74..15c198efafb 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/vec.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/vec.nr @@ -1,5 +1,5 @@ -struct Vec { - slice: [T] +struct Vec { + slice: [T], } // A mutable vector type implemented as a wrapper around immutable slices. @@ -39,7 +39,7 @@ impl Vec { last_elem } - /// Insert an element at a specified index, shifting all elements + /// Insert an element at a specified index, shifting all elements /// after it to the right pub fn insert(&mut self, index: Field, elem: T) { self.slice = self.slice.insert(index, elem); diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/input/ignore.nr b/noir/noir-repo/tooling/nargo_fmt/tests/input/ignore.nr index e095d2e9f1f..7d5a187146b 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/input/ignore.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/input/ignore.nr @@ -25,3 +25,4 @@ fn mk_array() { let array = [1, ]; } + diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/input/impl.nr b/noir/noir-repo/tooling/nargo_fmt/tests/input/impl.nr index 53c9759ca1b..dae62033a65 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/input/impl.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/input/impl.nr @@ -14,8 +14,6 @@ impl MyType { fn method(self: Self) {} fn method(mut self: Self) {} - - fn method(&mut self: Self) {} } impl MyType { diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/input/tuple.nr b/noir/noir-repo/tooling/nargo_fmt/tests/input/tuple.nr index da3b6ed597b..5be07be6ff4 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/input/tuple.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/input/tuple.nr @@ -32,7 +32,6 @@ fn main() { (/*1*/1, /*2*/2); -// FIXME: ((( //2 1,),),); diff --git a/noir/noir-repo/tooling/noir_codegen/package.json b/noir/noir-repo/tooling/noir_codegen/package.json index fc38dc4ec01..d6bd8ac18c9 100644 --- a/noir/noir-repo/tooling/noir_codegen/package.json +++ b/noir/noir-repo/tooling/noir_codegen/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.35.0", + "version": "0.36.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/noir/noir-repo/tooling/noir_js/package.json b/noir/noir-repo/tooling/noir_js/package.json index 705c3b3c3ee..fb970ecf1fe 100644 --- a/noir/noir-repo/tooling/noir_js/package.json +++ b/noir/noir-repo/tooling/noir_js/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.35.0", + "version": "0.36.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/noir/noir-repo/tooling/noir_js_types/package.json b/noir/noir-repo/tooling/noir_js_types/package.json index 61cff4bc53d..7c4d9910289 100644 --- a/noir/noir-repo/tooling/noir_js_types/package.json +++ b/noir/noir-repo/tooling/noir_js_types/package.json @@ -4,7 +4,7 @@ "The Noir Team " ], "packageManager": "yarn@3.5.1", - "version": "0.35.0", + "version": "0.36.0", "license": "(MIT OR Apache-2.0)", "homepage": "https://noir-lang.org/", "repository": { diff --git a/noir/noir-repo/tooling/noirc_abi_wasm/package.json b/noir/noir-repo/tooling/noirc_abi_wasm/package.json index df2bb613751..89a1abc4232 100644 --- a/noir/noir-repo/tooling/noirc_abi_wasm/package.json +++ b/noir/noir-repo/tooling/noirc_abi_wasm/package.json @@ -3,7 +3,7 @@ "contributors": [ "The Noir Team " ], - "version": "0.35.0", + "version": "0.36.0", "license": "(MIT OR Apache-2.0)", "homepage": "https://noir-lang.org/", "repository": { diff --git a/noir/noir-repo/yarn.lock b/noir/noir-repo/yarn.lock index 9df981f1af1..03cea21026e 100644 --- a/noir/noir-repo/yarn.lock +++ b/noir/noir-repo/yarn.lock @@ -245,6 +245,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/code-frame@npm:7.24.7" + dependencies: + "@babel/highlight": ^7.24.7 + picocolors: ^1.0.0 + checksum: 830e62cd38775fdf84d612544251ce773d544a8e63df667728cc9e0126eeef14c6ebda79be0f0bc307e8318316b7f58c27ce86702e0a1f5c321d842eb38ffda4 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.3, @babel/compat-data@npm:^7.23.5": version: 7.23.5 resolution: "@babel/compat-data@npm:7.23.5" @@ -252,6 +262,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.25.2, @babel/compat-data@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/compat-data@npm:7.25.4" + checksum: b12a91d27c3731a4b0bdc9312a50b1911f41f7f728aaf0d4b32486e2257fd2cb2d3ea1a295e98449600c48f2c7883a3196ca77cda1cef7d97a10c2e83d037974 + languageName: node + linkType: hard + "@babel/core@npm:7.12.9": version: 7.12.9 resolution: "@babel/core@npm:7.12.9" @@ -299,6 +316,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.21.3": + version: 7.25.2 + resolution: "@babel/core@npm:7.25.2" + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.0 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-module-transforms": ^7.25.2 + "@babel/helpers": ^7.25.0 + "@babel/parser": ^7.25.0 + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.2 + "@babel/types": ^7.25.2 + convert-source-map: ^2.0.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.3 + semver: ^6.3.1 + checksum: 9a1ef604a7eb62195f70f9370cec45472a08114e3934e3eaaedee8fd754edf0730e62347c7b4b5e67d743ce57b5bb8cf3b92459482ca94d06e06246ef021390a + languageName: node + linkType: hard + "@babel/generator@npm:^7.12.5, @babel/generator@npm:^7.18.7, @babel/generator@npm:^7.23.3, @babel/generator@npm:^7.23.5": version: 7.23.5 resolution: "@babel/generator@npm:7.23.5" @@ -311,6 +351,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.6": + version: 7.25.6 + resolution: "@babel/generator@npm:7.25.6" + dependencies: + "@babel/types": ^7.25.6 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^2.5.1 + checksum: b55975cd664f5602304d868bb34f4ee3bed6f5c7ce8132cd92ff27a46a53a119def28a182d91992e86f75db904f63094a81247703c4dc96e4db0c03fd04bcd68 + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" @@ -320,6 +372,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-annotate-as-pure@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" + dependencies: + "@babel/types": ^7.24.7 + checksum: 6178566099a6a0657db7a7fa601a54fb4731ca0b8614fbdccfd8e523c210c13963649bc8fdfd53ce7dd14d05e3dda2fb22dea5b30113c488b9eb1a906d60212e + languageName: node + linkType: hard + "@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.15": version: 7.22.15 resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15" @@ -329,6 +390,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 71a6158a9fdebffb82fdc400d5555ba8f2e370cea81a0d578155877bdc4db7d5252b75c43b2fdf3f72b3f68348891f99bd35ae315542daad1b7ace8322b1abcb + languageName: node + linkType: hard + "@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.6": version: 7.22.15 resolution: "@babel/helper-compilation-targets@npm:7.22.15" @@ -342,6 +413,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.24.7, @babel/helper-compilation-targets@npm:^7.24.8, @babel/helper-compilation-targets@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-compilation-targets@npm:7.25.2" + dependencies: + "@babel/compat-data": ^7.25.2 + "@babel/helper-validator-option": ^7.24.8 + browserslist: ^4.23.1 + lru-cache: ^5.1.1 + semver: ^6.3.1 + checksum: aed33c5496cb9db4b5e2d44e26bf8bc474074cc7f7bb5ebe1d4a20fdeb362cb3ba9e1596ca18c7484bcd6e5c3a155ab975e420d520c0ae60df81f9de04d0fd16 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.22.15, @babel/helper-create-class-features-plugin@npm:^7.23.5": version: 7.23.5 resolution: "@babel/helper-create-class-features-plugin@npm:7.23.5" @@ -361,6 +445,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.24.7, @babel/helper-create-class-features-plugin@npm:^7.25.0, @babel/helper-create-class-features-plugin@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.4" + dependencies: + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-member-expression-to-functions": ^7.24.8 + "@babel/helper-optimise-call-expression": ^7.24.7 + "@babel/helper-replace-supers": ^7.25.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/traverse": ^7.25.4 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 4544ebda4516eb25efdebd47ca024bd7bdb1eb6e7cc3ad89688c8ef8e889734c2f4411ed78981899c641394f013f246f2af63d92a0e9270f6c453309b4cb89ba + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.15, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": version: 7.22.15 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" @@ -374,6 +475,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-regexp-features-plugin@npm:^7.24.7, @babel/helper-create-regexp-features-plugin@npm:^7.25.0, @babel/helper-create-regexp-features-plugin@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.2" + dependencies: + "@babel/helper-annotate-as-pure": ^7.24.7 + regexpu-core: ^5.3.1 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: df55fdc6a1f3090dd37d91347df52d9322d52affa239543808dc142f8fe35e6787e67d8612337668198fac85826fafa9e6772e6c28b7d249ec94e6fafae5da6e + languageName: node + linkType: hard + "@babel/helper-define-polyfill-provider@npm:^0.4.3": version: 0.4.3 resolution: "@babel/helper-define-polyfill-provider@npm:0.4.3" @@ -389,6 +503,21 @@ __metadata: languageName: node linkType: hard +"@babel/helper-define-polyfill-provider@npm:^0.6.2": + version: 0.6.2 + resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" + dependencies: + "@babel/helper-compilation-targets": ^7.22.6 + "@babel/helper-plugin-utils": ^7.22.5 + debug: ^4.1.1 + lodash.debounce: ^4.0.8 + resolve: ^1.14.2 + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 2bba965ea9a4887ddf9c11d51d740ab473bd7597b787d042c325f6a45912dfe908c2d6bb1d837bf82f7e9fa51e6ad5150563c58131d2bb85515e63d971414a9c + languageName: node + linkType: hard + "@babel/helper-environment-visitor@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-environment-visitor@npm:7.22.20" @@ -424,6 +553,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" + dependencies: + "@babel/traverse": ^7.24.8 + "@babel/types": ^7.24.8 + checksum: bf923d05d81b06857f4ca4fe9c528c9c447a58db5ea39595bb559eae2fce01a8266173db0fd6a2ec129d7bbbb9bb22f4e90008252f7c66b422c76630a878a4bc + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.22.15": version: 7.22.15 resolution: "@babel/helper-module-imports@npm:7.22.15" @@ -433,6 +572,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-module-imports@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 8ac15d96d262b8940bc469052a048e06430bba1296369be695fabdf6799f201dd0b00151762b56012a218464e706bc033f27c07f6cec20c6f8f5fd6543c67054 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.23.3": version: 7.23.3 resolution: "@babel/helper-module-transforms@npm:7.23.3" @@ -448,6 +597,20 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.0, @babel/helper-module-transforms@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-module-transforms@npm:7.25.2" + dependencies: + "@babel/helper-module-imports": ^7.24.7 + "@babel/helper-simple-access": ^7.24.7 + "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.2 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 282d4e3308df6746289e46e9c39a0870819630af5f84d632559171e4fae6045684d771a65f62df3d569e88ccf81dc2def78b8338a449ae3a94bb421aa14fc367 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" @@ -457,6 +620,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" + dependencies: + "@babel/types": ^7.24.7 + checksum: 280654eaf90e92bf383d7eed49019573fb35a98c9e992668f701ad099957246721044be2068cf6840cb2299e0ad393705a1981c88c23a1048096a8d59e5f79a3 + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:7.10.4": version: 7.10.4 resolution: "@babel/helper-plugin-utils@npm:7.10.4" @@ -471,6 +643,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-plugin-utils@npm:7.24.8" + checksum: 73b1a83ba8bcee21dc94de2eb7323207391715e4369fd55844bb15cf13e3df6f3d13a40786d990e6370bf0f571d94fc31f70dec96c1d1002058258c35ca3767a + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" @@ -484,6 +663,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-remap-async-to-generator@npm:^7.24.7, @babel/helper-remap-async-to-generator@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-remap-async-to-generator@npm:7.25.0" + dependencies: + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-wrap-function": ^7.25.0 + "@babel/traverse": ^7.25.0 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 47f3065e43fe9d6128ddb4291ffb9cf031935379265fd13de972b5f241943121f7583efb69cd2e1ecf39e3d0f76f047547d56c3fcc2c853b326fad5465da0bd7 + languageName: node + linkType: hard + "@babel/helper-replace-supers@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-replace-supers@npm:7.22.20" @@ -497,6 +689,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.24.7, @babel/helper-replace-supers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-replace-supers@npm:7.25.0" + dependencies: + "@babel/helper-member-expression-to-functions": ^7.24.8 + "@babel/helper-optimise-call-expression": ^7.24.7 + "@babel/traverse": ^7.25.0 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: f669fc2487c22d40b808f94b9c3ee41129484d5ef0ba689bdd70f216ff91e10b6b021d2f8cd37e7bdd700235a2a6ae6622526344f064528190383bf661ac65f8 + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-simple-access@npm:7.22.5" @@ -506,6 +711,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-simple-access@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-simple-access@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: ddbf55f9dea1900213f2a1a8500fabfd21c5a20f44dcfa957e4b0d8638c730f88751c77f678644f754f1a1dc73f4eb8b766c300deb45a9daad000e4247957819 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" @@ -515,6 +730,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 11b28fe534ce2b1a67c4d8e51a7b5711a2a0a0cae802f74614eee54cca58c744d9a62f6f60103c41759e81c537d270bfd665bf368a6bea214c6052f2094f8407 + languageName: node + linkType: hard + "@babel/helper-split-export-declaration@npm:^7.22.6": version: 7.22.6 resolution: "@babel/helper-split-export-declaration@npm:7.22.6" @@ -531,6 +756,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 39b03c5119216883878655b149148dc4d2e284791e969b19467a9411fccaa33f7a713add98f4db5ed519535f70ad273cdadfd2eb54d47ebbdeac5083351328ce + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-validator-identifier@npm:7.22.20" @@ -538,6 +770,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-validator-identifier@npm:7.24.7" + checksum: 6799ab117cefc0ecd35cd0b40ead320c621a298ecac88686a14cffceaac89d80cdb3c178f969861bf5fa5e4f766648f9161ea0752ecfe080d8e89e3147270257 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.23.5": version: 7.23.5 resolution: "@babel/helper-validator-option@npm:7.23.5" @@ -545,6 +784,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.24.7, @babel/helper-validator-option@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: a52442dfa74be6719c0608fee3225bd0493c4057459f3014681ea1a4643cd38b68ff477fe867c4b356da7330d085f247f0724d300582fa4ab9a02efaf34d107c + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-wrap-function@npm:7.22.20" @@ -556,6 +802,17 @@ __metadata: languageName: node linkType: hard +"@babel/helper-wrap-function@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-wrap-function@npm:7.25.0" + dependencies: + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 0095b4741704066d1687f9bbd5370bb88c733919e4275e49615f70c180208148ff5f24ab58d186ce92f8f5d28eab034ec6617e9264590cc4744c75302857629c + languageName: node + linkType: hard + "@babel/helpers@npm:^7.12.5, @babel/helpers@npm:^7.23.5": version: 7.23.5 resolution: "@babel/helpers@npm:7.23.5" @@ -567,6 +824,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.25.0": + version: 7.25.6 + resolution: "@babel/helpers@npm:7.25.6" + dependencies: + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.6 + checksum: 5a548999db82049a5f7ac6de57576b4ed0d386ce07d058151698836ed411eae6230db12535487caeebb68a2ffc964491e8aead62364a5132ab0ae20e8b68e19f + languageName: node + linkType: hard + "@babel/highlight@npm:^7.23.4": version: 7.23.4 resolution: "@babel/highlight@npm:7.23.4" @@ -578,7 +845,19 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.12.7, @babel/parser@npm:^7.18.8, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.23.5": +"@babel/highlight@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/highlight@npm:7.24.7" + dependencies: + "@babel/helper-validator-identifier": ^7.24.7 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: 5cd3a89f143671c4ac129960024ba678b669e6fc673ce078030f5175002d1d3d52bc10b22c5b916a6faf644b5028e9a4bd2bb264d053d9b05b6a98690f1d46f1 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.12.7, @babel/parser@npm:^7.18.8, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.5": version: 7.23.5 resolution: "@babel/parser@npm:7.23.5" bin: @@ -587,6 +866,40 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.6": + version: 7.25.6 + resolution: "@babel/parser@npm:7.25.6" + dependencies: + "@babel/types": ^7.25.6 + bin: + parser: ./bin/babel-parser.js + checksum: 85b237ded09ee43cc984493c35f3b1ff8a83e8dbbb8026b8132e692db6567acc5a1659ec928e4baa25499ddd840d7dae9dee3062be7108fe23ec5f94a8066b1e + languageName: node + linkType: hard + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.3": + version: 7.25.3 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.3" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.3 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: d3dba60f360defe70eb43e35a1b17ea9dd4a99e734249e15be3d5c288019644f96f88d7ff51990118fda0845b4ad50f6d869e0382232b1d8b054d113d4eea7e2 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: fd56d1e6435f2c008ca9050ea906ff7eedcbec43f532f2bf2e7e905d8bf75bf5e4295ea9593f060394e2c8e45737266ccbf718050bad2dd7be4e7613c60d1b5b + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.23.3" @@ -598,6 +911,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 13ed301b108d85867d64226bbc4032b07dd1a23aab68e9e32452c4fe3930f2198bb65bdae9c262c4104bd5e45647bc1830d25d43d356ee9a137edd8d5fab8350 + languageName: node + linkType: hard + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.23.3" @@ -611,6 +935,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/plugin-transform-optional-chaining": ^7.24.7 + peerDependencies: + "@babel/core": ^7.13.0 + checksum: 07b92878ac58a98ea1fdf6a8b4ec3413ba4fa66924e28b694d63ec5b84463123fbf4d7153b56cf3cedfef4a3482c082fe3243c04f8fb2c041b32b0e29b4a9e21 + languageName: node + linkType: hard + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.23.3" @@ -623,6 +960,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.0 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: c8d08b8d6cc71451ad2a50cf7db72ab5b41c1e5e2e4d56cf6837a25a61270abd682c6b8881ab025f11a552d2024b3780519bb051459ebb71c27aed13d9917663 + languageName: node + linkType: hard + "@babel/plugin-proposal-object-rest-spread@npm:7.12.1": version: 7.12.1 resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.12.1" @@ -711,6 +1060,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-import-assertions@npm:^7.24.7": + version: 7.25.6 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.25.6" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: b3b251ace9f184c2d6369cde686ff01581050cb0796f2ff00ff4021f31cf86270b347df09579f2c0996e999e37e1dddafacec42ed1ef6aae21a265aff947e792 + languageName: node + linkType: hard + "@babel/plugin-syntax-import-attributes@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-syntax-import-attributes@npm:7.23.3" @@ -722,6 +1082,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-import-attributes@npm:^7.24.7": + version: 7.25.6 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.25.6" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3b0928e73e42346e8a65760a3ff853c87ad693cdf11bb335a23e895e0b5b1f0601118521b3aff2a6946488a580a63afb6a5b5686153a7678b4dff0e4e4604dd7 + languageName: node + linkType: hard + "@babel/plugin-syntax-import-meta@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" @@ -766,6 +1137,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 7a5ca629d8ca1e1ee78705a78e58c12920d07ed8006d7e7232b31296a384ff5e41d7b649bde5561196041037bbb9f9715be1d1c20975df87ca204f34ad15b965 + languageName: node + linkType: hard + "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -865,6 +1247,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^7.24.7": + version: 7.25.4 + resolution: "@babel/plugin-syntax-typescript@npm:7.25.4" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 9b89b8930cd5983f64251d75c9fcdc17a8dc73837d6de12220ff972888ecff4054a6467cf0c423cad242aa96c0f0564a39a0823073728cc02239b80d13f02230 + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -888,6 +1281,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-arrow-functions@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 707c209b5331c7dc79bd326128c6a6640dbd62a78da1653c844db20c4f36bf7b68454f1bc4d2d051b3fde9136fa291f276ec03a071bb00ee653069ff82f91010 + languageName: node + linkType: hard + "@babel/plugin-transform-async-generator-functions@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.4" @@ -902,6 +1306,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-generator-functions@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.4" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-remap-async-to-generator": ^7.25.0 + "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/traverse": ^7.25.4 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 4235444735a1946f8766fe56564a8134c2c36c73e6cf83b3f2ed5624ebc84ff5979506a6a5b39acdb23aa09d442a6af471710ed408ccce533a2c4d2990b9df6a + languageName: node + linkType: hard + "@babel/plugin-transform-async-to-generator@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-async-to-generator@npm:7.23.3" @@ -915,6 +1333,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-async-to-generator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.7" + dependencies: + "@babel/helper-module-imports": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-remap-async-to-generator": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 13704fb3b83effc868db2b71bfb2c77b895c56cb891954fc362e95e200afd523313b0e7cf04ce02f45b05e76017c5b5fa8070c92613727a35131bb542c253a36 + languageName: node + linkType: hard + "@babel/plugin-transform-block-scoped-functions@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.23.3" @@ -926,6 +1357,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-block-scoped-functions@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 249cdcbff4e778b177245f9652b014ea4f3cd245d83297f10a7bf6d97790074089aa62bcde8c08eb299c5e68f2faed346b587d3ebac44d625ba9a83a4ee27028 + languageName: node + linkType: hard + "@babel/plugin-transform-block-scoping@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-block-scoping@npm:7.23.4" @@ -937,6 +1379,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-block-scoping@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-block-scoping@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: b1a8f932f69ad2a47ae3e02b4cedd2a876bfc2ac9cf72a503fd706cdc87272646fe9eed81e068c0fc639647033de29f7fa0c21cddd1da0026f83dbaac97316a8 + languageName: node + linkType: hard + "@babel/plugin-transform-class-properties@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-class-properties@npm:7.23.3" @@ -949,6 +1402,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-properties@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-class-properties@npm:7.25.4" + dependencies: + "@babel/helper-create-class-features-plugin": ^7.25.4 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: b73f7d968639c6c2dfc13f4c5a8fe45cefd260f0faa7890ae12e65d41211072544ff5e128c8b61a86887b29ffd3df8422dbdfbf61648488e71d4bb599c41f4a5 + languageName: node + linkType: hard + "@babel/plugin-transform-class-static-block@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-class-static-block@npm:7.23.4" @@ -962,6 +1427,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-static-block@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-class-static-block@npm:7.24.7" + dependencies: + "@babel/helper-create-class-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-class-static-block": ^7.14.5 + peerDependencies: + "@babel/core": ^7.12.0 + checksum: 324049263504f18416f1c3e24033baebfafd05480fdd885c8ebe6f2b415b0fc8e0b98d719360f9e30743cc78ac387fabc0b3c6606d2b54135756ffb92963b382 + languageName: node + linkType: hard + "@babel/plugin-transform-classes@npm:^7.23.5": version: 7.23.5 resolution: "@babel/plugin-transform-classes@npm:7.23.5" @@ -981,6 +1459,22 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-classes@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-classes@npm:7.25.4" + dependencies: + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-replace-supers": ^7.25.0 + "@babel/traverse": ^7.25.4 + globals: ^11.1.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 0bf20e46eeb691bd60cee5d1b01950fc37accec88018ecace25099f7c8d8509c1ac54d11b8caf9f2157c6945969520642a3bc421159c1a14e80224dc9a7611de + languageName: node + linkType: hard + "@babel/plugin-transform-computed-properties@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-computed-properties@npm:7.23.3" @@ -993,6 +1487,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-computed-properties@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-computed-properties@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/template": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 0cf8c1b1e4ea57dec8d4612460d84fd4cdbf71a7499bb61ee34632cf89018a59eee818ffca88a8d99ee7057c20a4257044d7d463fda6daef9bf1db9fa81563cb + languageName: node + linkType: hard + "@babel/plugin-transform-destructuring@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-destructuring@npm:7.23.3" @@ -1004,6 +1510,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-destructuring@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-destructuring@npm:7.24.8" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 0b4bd3d608979a1e5bd97d9d42acd5ad405c7fffa61efac4c7afd8e86ea6c2d91ab2d94b6a98d63919571363fe76e0b03c4ff161f0f60241b895842596e4a999 + languageName: node + linkType: hard + "@babel/plugin-transform-dotall-regex@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-dotall-regex@npm:7.23.3" @@ -1016,6 +1533,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-dotall-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.7" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 67b10fc6abb1f61f0e765288eb4c6d63d1d0f9fc0660e69f6f2170c56fa16bc74e49857afc644beda112b41771cd90cf52df0940d11e97e52617c77c7dcff171 + languageName: node + linkType: hard + "@babel/plugin-transform-duplicate-keys@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.23.3" @@ -1027,6 +1556,29 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-duplicate-keys@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: d1da2ff85ecb56a63f4ccfd9dc9ae69400d85f0dadf44ecddd9e71c6e5c7a9178e74e3a9637555f415a2bb14551e563f09f98534ab54f53d25e8439fdde6ba2d + languageName: node + linkType: hard + +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 608d6b0e77341189508880fd1a9f605a38d0803dd6f678ea3920ab181b17b377f6d5221ae8cf0104c7a044d30d4ddb0366bd064447695671d78457a656bb264f + languageName: node + linkType: hard + "@babel/plugin-transform-dynamic-import@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-dynamic-import@npm:7.23.4" @@ -1039,6 +1591,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-dynamic-import@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-dynamic-import": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 776509ff62ab40c12be814a342fc56a5cc09b91fb63032b2633414b635875fd7da03734657be0f6db2891fe6e3033b75d5ddb6f2baabd1a02e4443754a785002 + languageName: node + linkType: hard + "@babel/plugin-transform-exponentiation-operator@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.23.3" @@ -1051,6 +1615,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-exponentiation-operator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.7" + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 23c84a23eb56589fdd35a3540f9a1190615be069110a2270865223c03aee3ba4e0fc68fe14850800cf36f0712b26e4964d3026235261f58f0405a29fe8dac9b1 + languageName: node + linkType: hard + "@babel/plugin-transform-export-namespace-from@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.23.4" @@ -1063,6 +1639,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-export-namespace-from@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-export-namespace-from": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3bd3a10038f10ae0dea1ee42137f3edcf7036b5e9e570a0d1cbd0865f03658990c6c2d84fa2475f87a754e7dc5b46766c16f7ce5c9b32c3040150b6a21233a80 + languageName: node + linkType: hard + "@babel/plugin-transform-for-of@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-for-of@npm:7.23.3" @@ -1074,6 +1662,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-for-of@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-for-of@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: a53b42dc93ab4b7d1ebd3c695b52be22b3d592f6a3dbdb3dc2fea2c8e0a7e1508fe919864c455cde552aec44ce7518625fccbb70c7063373ca228d884f4f49ea + languageName: node + linkType: hard + "@babel/plugin-transform-function-name@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-function-name@npm:7.23.3" @@ -1087,6 +1687,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-function-name@npm:^7.25.1": + version: 7.25.1 + resolution: "@babel/plugin-transform-function-name@npm:7.25.1" + dependencies: + "@babel/helper-compilation-targets": ^7.24.8 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 743f3ea03bbc5a90944849d5a880b6bd9243dddbde581a46952da76e53a0b74c1e2424133fe8129d7a152c1f8c872bcd27e0b6728d7caadabd1afa7bb892e1e0 + languageName: node + linkType: hard + "@babel/plugin-transform-json-strings@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-json-strings@npm:7.23.4" @@ -1099,6 +1712,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-json-strings@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-json-strings@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-json-strings": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 88874d0b7a1ddea66c097fc0abb68801ffae194468aa44b828dde9a0e20ac5d8647943793de86092eabaa2911c96f67a6b373793d4bb9c932ef81b2711c06c2e + languageName: node + linkType: hard + "@babel/plugin-transform-literals@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-literals@npm:7.23.3" @@ -1110,6 +1735,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-literals@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/plugin-transform-literals@npm:7.25.2" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 70c9bb40e377a306bd8f500899fb72127e527517914466e95dc6bb53fa7a0f51479db244a54a771b5780fc1eab488fedd706669bf11097b81a23c81ab7423eb1 + languageName: node + linkType: hard + "@babel/plugin-transform-logical-assignment-operators@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.23.4" @@ -1122,6 +1758,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3367ce0be243704dc6fce23e86a592c4380f01998ee5dd9f94c54b1ef7b971ac6f8a002901eb51599ac6cbdc0d067af8d1a720224fca1c40fde8bb8aab804aac + languageName: node + linkType: hard + "@babel/plugin-transform-member-expression-literals@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.23.3" @@ -1133,6 +1781,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-member-expression-literals@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 2720c57aa3bf70576146ba7d6ea03227f4611852122d76d237924f7b008dafc952e6ae61a19e5024f26c665f44384bbd378466f01b6bd1305b3564a3b7fb1a5d + languageName: node + linkType: hard + "@babel/plugin-transform-modules-amd@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-modules-amd@npm:7.23.3" @@ -1145,6 +1804,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-amd@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-modules-amd@npm:7.24.7" + dependencies: + "@babel/helper-module-transforms": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: f1dd0fb2f46c0f8f21076b8c7ccd5b33a85ce6dcb31518ea4c648d9a5bb2474cd4bd87c9b1b752e68591e24b022e334ba0d07631fef2b6b4d8a4b85cf3d581f5 + languageName: node + linkType: hard + "@babel/plugin-transform-modules-commonjs@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.23.3" @@ -1158,6 +1829,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-commonjs@npm:^7.24.7, @babel/plugin-transform-modules-commonjs@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" + dependencies: + "@babel/helper-module-transforms": ^7.24.8 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-simple-access": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: a4cf95b1639c33382064b44558f73ee5fac023f2a94d16e549d2bb55ceebd5cbc10fcddd505d08cd5bc97f5a64af9fd155512358b7dcf7b1a0082e8945cf21c5 + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.23.3" @@ -1168,7 +1852,21 @@ __metadata: "@babel/helper-validator-identifier": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0d2fdd993c785aecac9e0850cd5ed7f7d448f0fbb42992a950cc0590167144df25d82af5aac9a5c99ef913d2286782afa44e577af30c10901c5ee8984910fa1f + checksum: 0d2fdd993c785aecac9e0850cd5ed7f7d448f0fbb42992a950cc0590167144df25d82af5aac9a5c99ef913d2286782afa44e577af30c10901c5ee8984910fa1f + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-systemjs@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.0" + dependencies: + "@babel/helper-module-transforms": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: fe673bec08564e491847324bb80a1e6edfb229f5c37e58a094d51e95306e7b098e1d130fc43e992d22debd93b9beac74441ffc3f6ea5d78f6b2535896efa0728 languageName: node linkType: hard @@ -1184,6 +1882,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-umd@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-modules-umd@npm:7.24.7" + dependencies: + "@babel/helper-module-transforms": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 9ff1c464892efe042952ba778468bda6131b196a2729615bdcc3f24cdc94014f016a4616ee5643c5845bade6ba698f386833e61056d7201314b13a7fd69fac88 + languageName: node + linkType: hard + "@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" @@ -1196,6 +1906,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.24.7" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: f1c6c7b5d60a86b6d7e4dd098798e1d393d55e993a0b57a73b53640c7a94985b601a96bdacee063f809a9a700bcea3a2ff18e98fa561554484ac56b761d774bd + languageName: node + linkType: hard + "@babel/plugin-transform-new-target@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-new-target@npm:7.23.3" @@ -1207,6 +1929,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-new-target@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-new-target@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3cb94cd1076b270f768f91fdcf9dd2f6d487f8dbfff3df7ca8d07b915900b86d02769a35ba1407d16fe49499012c8f055e1741299e2c880798b953d942a8fa1b + languageName: node + linkType: hard + "@babel/plugin-transform-nullish-coalescing-operator@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.23.4" @@ -1219,6 +1952,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 4a9221356401d87762afbc37a9e8e764afc2daf09c421117537820f8cfbed6876888372ad3a7bcfae2d45c95f026651f050ab4020b777be31d3ffb00908dbdd3 + languageName: node + linkType: hard + "@babel/plugin-transform-numeric-separator@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-numeric-separator@npm:7.23.4" @@ -1231,6 +1976,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-numeric-separator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 561b5f1d08b2c3f92ce849f092751558b5e6cfeb7eb55c79e7375c34dd9c3066dce5e630bb439affef6adcf202b6cbcaaa23870070276fa5bb429c8f5b8c7514 + languageName: node + linkType: hard + "@babel/plugin-transform-object-rest-spread@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.23.4" @@ -1246,6 +2003,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-object-rest-spread@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.7" + dependencies: + "@babel/helper-compilation-targets": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-transform-parameters": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 169d257b9800c13e1feb4c37fb05dae84f702e58b342bb76e19e82e6692b7b5337c9923ee89e3916a97c0dd04a3375bdeca14f5e126f110bbacbeb46d1886ca2 + languageName: node + linkType: hard + "@babel/plugin-transform-object-super@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-object-super@npm:7.23.3" @@ -1258,6 +2029,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-object-super@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-object-super@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-replace-supers": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: f71e607a830ee50a22fa1a2686524d3339440cf9dea63032f6efbd865cfe4e35000e1e3f3492459e5c986f7c0c07dc36938bf3ce61fc9ba5f8ab732d0b64ab37 + languageName: node + linkType: hard + "@babel/plugin-transform-optional-catch-binding@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.23.4" @@ -1270,6 +2053,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-optional-catch-binding@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 7229f3a5a4facaab40f4fdfc7faabc157dc38a67d66bed7936599f4bc509e0bff636f847ac2aa45294881fce9cf8a0a460b85d2a465b7b977de9739fce9b18f6 + languageName: node + linkType: hard + "@babel/plugin-transform-optional-chaining@npm:^7.23.3, @babel/plugin-transform-optional-chaining@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-optional-chaining@npm:7.23.4" @@ -1283,6 +2078,19 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-optional-chaining@npm:^7.24.7, @babel/plugin-transform-optional-chaining@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.8" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 45e55e3a2fffb89002d3f89aef59c141610f23b60eee41e047380bffc40290b59f64fc649aa7ec5281f73d41b2065410d788acc6afaad2a9f44cad6e8af04442 + languageName: node + linkType: hard + "@babel/plugin-transform-parameters@npm:^7.12.1, @babel/plugin-transform-parameters@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-parameters@npm:7.23.3" @@ -1294,6 +2102,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-parameters@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-parameters@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: ab534b03ac2eff94bc79342b8f39a4584666f5305a6c63c1964afda0b1b004e6b861e49d1683548030defe248e3590d3ff6338ee0552cb90c064f7e1479968c3 + languageName: node + linkType: hard + "@babel/plugin-transform-private-methods@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-private-methods@npm:7.23.3" @@ -1306,6 +2125,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-private-methods@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-private-methods@npm:7.25.4" + dependencies: + "@babel/helper-create-class-features-plugin": ^7.25.4 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: cb1dabfc03e2977990263d65bc8f43a9037dffbb5d9a5f825c00d05447ff68015099408c1531d9dd88f18a41a90f5062dc48f3a1d52b415d2d2ee4827dedff09 + languageName: node + linkType: hard + "@babel/plugin-transform-private-property-in-object@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-private-property-in-object@npm:7.23.4" @@ -1320,6 +2151,20 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-private-property-in-object@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.7" + dependencies: + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-create-class-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 8cee9473095305cc787bb653fd681719b49363281feabf677db8a552e8e41c94441408055d7e5fd5c7d41b315e634fa70b145ad0c7c54456216049df4ed57350 + languageName: node + linkType: hard + "@babel/plugin-transform-property-literals@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-property-literals@npm:7.23.3" @@ -1331,6 +2176,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-property-literals@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-property-literals@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 9aeefc3aab6c6bf9d1fae1cf3a2d38c7d886fd3c6c81b7c608c477f5758aee2e7abf52f32724310fe861da61af934ee2508b78a5b5f234b9740c9134e1c14437 + languageName: node + linkType: hard + "@babel/plugin-transform-react-constant-elements@npm:^7.18.12": version: 7.23.3 resolution: "@babel/plugin-transform-react-constant-elements@npm:7.23.3" @@ -1342,6 +2198,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-react-constant-elements@npm:^7.21.3": + version: 7.25.1 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.25.1" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 6126abf8bc3980c1e27fd217f8b2f226b20cce9be300eaf9d30548556dd1e906b7daa4580d9ae1dae35eb5ed5c98e7222e0cb91efb0a232d05aae5875dcfe55c + languageName: node + linkType: hard + "@babel/plugin-transform-react-display-name@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-react-display-name@npm:7.23.3" @@ -1403,6 +2270,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-regenerator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-regenerator@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + regenerator-transform: ^0.15.2 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 20c6c3fb6fc9f407829087316653388d311e8c1816b007609bb09aeef254092a7157adace8b3aaa8f34be752503717cb85c88a5fe482180a9b11bcbd676063be + languageName: node + linkType: hard + "@babel/plugin-transform-reserved-words@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-reserved-words@npm:7.23.3" @@ -1414,6 +2293,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-reserved-words@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-reserved-words@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3d5876954d5914d7270819479504f30c4bf5452a65c677f44e2dab2db50b3c9d4b47793c45dfad7abf4f377035dd79e4b3f554ae350df9f422201d370ce9f8dd + languageName: node + linkType: hard + "@babel/plugin-transform-runtime@npm:^7.18.6, @babel/plugin-transform-runtime@npm:^7.22.9": version: 7.23.4 resolution: "@babel/plugin-transform-runtime@npm:7.23.4" @@ -1441,6 +2331,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-shorthand-properties@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 7b524245814607188212b8eb86d8c850e5974203328455a30881b4a92c364b93353fae14bc2af5b614ef16300b75b8c1d3b8f3a08355985b4794a7feb240adc3 + languageName: node + linkType: hard + "@babel/plugin-transform-spread@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-spread@npm:7.23.3" @@ -1453,6 +2354,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-spread@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-spread@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 4c4254c8b9cceb1a8f975fa9b92257ddb08380a35c0a3721b8f4b9e13a3d82e403af2e0fba577b9f2452dd8f06bc3dea71cc53b1e2c6af595af5db52a13429d6 + languageName: node + linkType: hard + "@babel/plugin-transform-sticky-regex@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-sticky-regex@npm:7.23.3" @@ -1464,6 +2377,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-sticky-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 118fc7a7ebf7c20411b670c8a030535fdfe4a88bc5643bb625a584dbc4c8a468da46430a20e6bf78914246962b0f18f1b9d6a62561a7762c4f34a038a5a77179 + languageName: node + linkType: hard + "@babel/plugin-transform-template-literals@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-template-literals@npm:7.23.3" @@ -1475,6 +2399,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-template-literals@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-template-literals@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: ad44e5826f5a98c1575832dbdbd033adfe683cdff195e178528ead62507564bf02f479b282976cfd3caebad8b06d5fd7349c1cdb880dec3c56daea4f1f179619 + languageName: node + linkType: hard + "@babel/plugin-transform-typeof-symbol@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-typeof-symbol@npm:7.23.3" @@ -1486,6 +2421,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typeof-symbol@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.8" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 8663a8e7347cedf181001d99c88cf794b6598c3d82f324098510fe8fb8bd22113995526a77aa35a3cc5d70ffd0617a59dd0d10311a9bf0e1a3a7d3e59b900c00 + languageName: node + linkType: hard + "@babel/plugin-transform-typescript@npm:^7.23.3": version: 7.23.5 resolution: "@babel/plugin-transform-typescript@npm:7.23.5" @@ -1500,6 +2446,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.24.7": + version: 7.25.2 + resolution: "@babel/plugin-transform-typescript@npm:7.25.2" + dependencies: + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-create-class-features-plugin": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/plugin-syntax-typescript": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: b0267128d93560a4350919f7230a3b497e20fb8611d9f04bb3560d6b38877305ccad4c40903160263361c6930a84dbcb5b21b8ea923531bda51f67bffdc2dd0b + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.23.3" @@ -1511,6 +2472,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-escapes@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 4af0a193e1ddea6ff82b2b15cc2501b872728050bd625740b813c8062fec917d32d530ff6b41de56c15e7296becdf3336a58db81f5ca8e7c445c1306c52f3e01 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-property-regex@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.23.3" @@ -1523,6 +2495,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-property-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.7" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: aae13350c50973f5802ca7906d022a6a0cc0e3aebac9122d0450bbd51e78252d4c2032ad69385e2759fcbdd3aac5d571bd7e26258907f51f8e1a51b53be626c2 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-regex@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-unicode-regex@npm:7.23.3" @@ -1535,6 +2519,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.7" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 1cb4e70678906e431da0a05ac3f8350025fee290304ad7482d9cfaa1ca67b2e898654de537c9268efbdad5b80d3ebadf42b4a88ea84609bd8a4cce7b11b48afd + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-sets-regex@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.23.3" @@ -1547,6 +2543,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.4" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.25.2 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 6d1a7e9fdde4ffc9a81c0e3f261b96a9a0dfe65da282ec96fe63b36c597a7389feac638f1df2a8a4f8c9128337bba8e984f934e9f19077930f33abf1926759ea + languageName: node + linkType: hard + "@babel/preset-env@npm:^7.18.6, @babel/preset-env@npm:^7.19.4, @babel/preset-env@npm:^7.22.9": version: 7.23.5 resolution: "@babel/preset-env@npm:7.23.5" @@ -1637,6 +2645,99 @@ __metadata: languageName: node linkType: hard +"@babel/preset-env@npm:^7.20.2": + version: 7.25.4 + resolution: "@babel/preset-env@npm:7.25.4" + dependencies: + "@babel/compat-data": ^7.25.4 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-validator-option": ^7.24.8 + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.25.3 + "@babel/plugin-bugfix-safari-class-field-initializer-scope": ^7.25.0 + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.25.0 + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.24.7 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.25.0 + "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 + "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/plugin-syntax-class-properties": ^7.12.13 + "@babel/plugin-syntax-class-static-block": ^7.14.5 + "@babel/plugin-syntax-dynamic-import": ^7.8.3 + "@babel/plugin-syntax-export-namespace-from": ^7.8.3 + "@babel/plugin-syntax-import-assertions": ^7.24.7 + "@babel/plugin-syntax-import-attributes": ^7.24.7 + "@babel/plugin-syntax-import-meta": ^7.10.4 + "@babel/plugin-syntax-json-strings": ^7.8.3 + "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 + "@babel/plugin-syntax-top-level-await": ^7.14.5 + "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 + "@babel/plugin-transform-arrow-functions": ^7.24.7 + "@babel/plugin-transform-async-generator-functions": ^7.25.4 + "@babel/plugin-transform-async-to-generator": ^7.24.7 + "@babel/plugin-transform-block-scoped-functions": ^7.24.7 + "@babel/plugin-transform-block-scoping": ^7.25.0 + "@babel/plugin-transform-class-properties": ^7.25.4 + "@babel/plugin-transform-class-static-block": ^7.24.7 + "@babel/plugin-transform-classes": ^7.25.4 + "@babel/plugin-transform-computed-properties": ^7.24.7 + "@babel/plugin-transform-destructuring": ^7.24.8 + "@babel/plugin-transform-dotall-regex": ^7.24.7 + "@babel/plugin-transform-duplicate-keys": ^7.24.7 + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ^7.25.0 + "@babel/plugin-transform-dynamic-import": ^7.24.7 + "@babel/plugin-transform-exponentiation-operator": ^7.24.7 + "@babel/plugin-transform-export-namespace-from": ^7.24.7 + "@babel/plugin-transform-for-of": ^7.24.7 + "@babel/plugin-transform-function-name": ^7.25.1 + "@babel/plugin-transform-json-strings": ^7.24.7 + "@babel/plugin-transform-literals": ^7.25.2 + "@babel/plugin-transform-logical-assignment-operators": ^7.24.7 + "@babel/plugin-transform-member-expression-literals": ^7.24.7 + "@babel/plugin-transform-modules-amd": ^7.24.7 + "@babel/plugin-transform-modules-commonjs": ^7.24.8 + "@babel/plugin-transform-modules-systemjs": ^7.25.0 + "@babel/plugin-transform-modules-umd": ^7.24.7 + "@babel/plugin-transform-named-capturing-groups-regex": ^7.24.7 + "@babel/plugin-transform-new-target": ^7.24.7 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.24.7 + "@babel/plugin-transform-numeric-separator": ^7.24.7 + "@babel/plugin-transform-object-rest-spread": ^7.24.7 + "@babel/plugin-transform-object-super": ^7.24.7 + "@babel/plugin-transform-optional-catch-binding": ^7.24.7 + "@babel/plugin-transform-optional-chaining": ^7.24.8 + "@babel/plugin-transform-parameters": ^7.24.7 + "@babel/plugin-transform-private-methods": ^7.25.4 + "@babel/plugin-transform-private-property-in-object": ^7.24.7 + "@babel/plugin-transform-property-literals": ^7.24.7 + "@babel/plugin-transform-regenerator": ^7.24.7 + "@babel/plugin-transform-reserved-words": ^7.24.7 + "@babel/plugin-transform-shorthand-properties": ^7.24.7 + "@babel/plugin-transform-spread": ^7.24.7 + "@babel/plugin-transform-sticky-regex": ^7.24.7 + "@babel/plugin-transform-template-literals": ^7.24.7 + "@babel/plugin-transform-typeof-symbol": ^7.24.8 + "@babel/plugin-transform-unicode-escapes": ^7.24.7 + "@babel/plugin-transform-unicode-property-regex": ^7.24.7 + "@babel/plugin-transform-unicode-regex": ^7.24.7 + "@babel/plugin-transform-unicode-sets-regex": ^7.25.4 + "@babel/preset-modules": 0.1.6-no-external-plugins + babel-plugin-polyfill-corejs2: ^0.4.10 + babel-plugin-polyfill-corejs3: ^0.10.6 + babel-plugin-polyfill-regenerator: ^0.6.1 + core-js-compat: ^3.37.1 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 752be43f0b78a2eefe5007076aed3d21b505e1c09d134b61e7de8838f1bbb1e7af81023d39adb14b6eae23727fb5a9fd23f8115a44df043319be22319be17913 + languageName: node + linkType: hard + "@babel/preset-modules@npm:0.1.6-no-external-plugins": version: 0.1.6-no-external-plugins resolution: "@babel/preset-modules@npm:0.1.6-no-external-plugins" @@ -1681,6 +2782,21 @@ __metadata: languageName: node linkType: hard +"@babel/preset-typescript@npm:^7.21.0": + version: 7.24.7 + resolution: "@babel/preset-typescript@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-validator-option": ^7.24.7 + "@babel/plugin-syntax-jsx": ^7.24.7 + "@babel/plugin-transform-modules-commonjs": ^7.24.7 + "@babel/plugin-transform-typescript": ^7.24.7 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 12929b24757f3bd6548103475f86478eda4c872bc7cefd920b29591eee8f4a4f350561d888e133d632d0c9402b8615fdcec9138e5127a6567dcb22f804ff207f + languageName: node + linkType: hard + "@babel/regjsgen@npm:^0.8.0": version: 0.8.0 resolution: "@babel/regjsgen@npm:0.8.0" @@ -1718,6 +2834,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" + dependencies: + "@babel/code-frame": ^7.24.7 + "@babel/parser": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 3f2db568718756d0daf2a16927b78f00c425046b654cd30b450006f2e84bdccaf0cbe6dc04994aa1f5f6a4398da2f11f3640a4d3ee31722e43539c4c919c817b + languageName: node + linkType: hard + "@babel/traverse@npm:^7.12.9, @babel/traverse@npm:^7.18.8, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.23.5": version: 7.23.5 resolution: "@babel/traverse@npm:7.23.5" @@ -1736,6 +2863,21 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.25.4": + version: 7.25.6 + resolution: "@babel/traverse@npm:7.25.6" + dependencies: + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.6 + "@babel/parser": ^7.25.6 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.6 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: 11ee47269aa4356f2d6633a05b9af73405b5ed72c09378daf644289b686ef852035a6ac9aa410f601991993c6bbf72006795b5478283b78eb1ca77874ada7737 + languageName: node + linkType: hard + "@babel/types@npm:^7.12.7, @babel/types@npm:^7.20.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.23.5, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.23.5 resolution: "@babel/types@npm:7.23.5" @@ -1747,6 +2889,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.21.3, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.6": + version: 7.25.6 + resolution: "@babel/types@npm:7.25.6" + dependencies: + "@babel/helper-string-parser": ^7.24.8 + "@babel/helper-validator-identifier": ^7.24.7 + to-fast-properties: ^2.0.0 + checksum: 9b2f84ff3f874ad05b0b9bf06862c56f478b65781801f82296b4cc01bee39e79c20a7c0a06959fed0ee582c8267e1cb21638318655c5e070b0287242a844d1c9 + languageName: node + linkType: hard + "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -2343,9 +3496,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:3.0.1, @docusaurus/core@npm:^3.0.1": - version: 3.0.1 - resolution: "@docusaurus/core@npm:3.0.1" +"@docusaurus/core@npm:3.5.2, @docusaurus/core@npm:^3.5.2": + version: 3.5.2 + resolution: "@docusaurus/core@npm:3.5.2" dependencies: "@babel/core": ^7.23.3 "@babel/generator": ^7.23.3 @@ -2357,15 +3510,12 @@ __metadata: "@babel/runtime": ^7.22.6 "@babel/runtime-corejs3": ^7.22.6 "@babel/traverse": ^7.22.8 - "@docusaurus/cssnano-preset": 3.0.1 - "@docusaurus/logger": 3.0.1 - "@docusaurus/mdx-loader": 3.0.1 - "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-common": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 - "@slorber/static-site-generator-webpack-plugin": ^4.0.7 - "@svgr/webpack": ^6.5.1 + "@docusaurus/cssnano-preset": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 autoprefixer: ^10.4.14 babel-loader: ^9.1.3 babel-plugin-dynamic-import-node: ^2.3.3 @@ -2379,12 +3529,13 @@ __metadata: copy-webpack-plugin: ^11.0.0 core-js: ^3.31.1 css-loader: ^6.8.1 - css-minimizer-webpack-plugin: ^4.2.2 - cssnano: ^5.1.15 + css-minimizer-webpack-plugin: ^5.0.1 + cssnano: ^6.1.2 del: ^6.1.1 detect-port: ^1.5.1 escape-html: ^1.0.3 eta: ^2.2.0 + eval: ^0.1.8 file-loader: ^6.2.0 fs-extra: ^11.1.1 html-minifier-terser: ^7.2.0 @@ -2393,12 +3544,13 @@ __metadata: leven: ^3.1.0 lodash: ^4.17.21 mini-css-extract-plugin: ^2.7.6 + p-map: ^4.0.0 postcss: ^8.4.26 postcss-loader: ^7.3.3 prompts: ^2.4.2 react-dev-utils: ^12.0.1 react-helmet-async: ^1.3.0 - react-loadable: "npm:@docusaurus/react-loadable@5.5.2" + react-loadable: "npm:@docusaurus/react-loadable@6.0.0" react-loadable-ssr-addon-v5-slorber: ^1.0.1 react-router: ^5.3.4 react-router-config: ^5.1.1 @@ -2417,11 +3569,12 @@ __metadata: webpack-merge: ^5.9.0 webpackbar: ^5.0.2 peerDependencies: + "@mdx-js/react": ^3.0.0 react: ^18.0.0 react-dom: ^18.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: 56767f7e629edce4d23c19403abf4039daeea25db20c695fb7c3a1ce04a90f182f14ea1f70286afb221b8c1593823ebb0d28cbc2ca5d9d38d707a0338d544f64 + checksum: 6c6282a75931f0f8f8f8768232b4436ff8679ae12b619f7bd01e0d83aa346e24ab0d9cecac034f9dc95c55059997efdd963d052d3e429583bfb8d3b54ab750d3 languageName: node linkType: hard @@ -2437,15 +3590,15 @@ __metadata: languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/cssnano-preset@npm:3.0.1" +"@docusaurus/cssnano-preset@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/cssnano-preset@npm:3.5.2" dependencies: - cssnano-preset-advanced: ^5.3.10 - postcss: ^8.4.26 - postcss-sort-media-queries: ^4.4.1 + cssnano-preset-advanced: ^6.1.2 + postcss: ^8.4.38 + postcss-sort-media-queries: ^5.2.0 tslib: ^2.6.0 - checksum: 3a04606d362c84398a5af9a98de4995958e2705086af83388479feaa157cbe3164281006e64036f9337e96b0cec62bd1362fc0f910075e6eeec930f0a519801d + checksum: 4bb1fae3741e14cbbdb64c1b0707435970838bf219831234a70cf382e6811ffac1cadf733d5e1fe7c278e7b2a9e533bfa802a5212b22ec46edd703208cf49f92 languageName: node linkType: hard @@ -2459,13 +3612,13 @@ __metadata: languageName: node linkType: hard -"@docusaurus/logger@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/logger@npm:3.0.1" +"@docusaurus/logger@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/logger@npm:3.5.2" dependencies: chalk: ^4.1.2 tslib: ^2.6.0 - checksum: 4d4ffcd08f9c76c105d2d2b95974f5c33941e5346c5de1b19ee3f55a4f5011bb7db3875349e25da02750cea5fb357ba00be271ea24368c75b8e29189d04e9f7c + checksum: 7cbdcf54acd6e7787ca5a10b9c884be4b9e8fdae837862c66550a0bf3d02737f72c3188b2bddd61da6d8530eb2eb2b646ea599a79416e33c4998f1a87d2f6a8c languageName: node linkType: hard @@ -2497,15 +3650,13 @@ __metadata: languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/mdx-loader@npm:3.0.1" +"@docusaurus/mdx-loader@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/mdx-loader@npm:3.5.2" dependencies: - "@babel/parser": ^7.22.7 - "@babel/traverse": ^7.22.8 - "@docusaurus/logger": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 + "@docusaurus/logger": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@mdx-js/mdx": ^3.0.0 "@slorber/remark-comment": ^1.0.0 escape-html: ^1.0.3 @@ -2530,7 +3681,7 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 8ba9774cd2cc7216f645d54a6f6f6cba34e39e371f0de09e56f60a27dde95a8e42ab92cf0a6f384dce01960c68a1e720868c56b6aa8929d23bafe9f523941151 + checksum: 36186c2f3487631757b24ba3a21575d2253ca1e6ada82d556bf323da7ae7637c0880eb388bf375e207bc5f26dcd8b58cc76d763e6c2caf6ed80f88748444ce8d languageName: node linkType: hard @@ -2553,37 +3704,37 @@ __metadata: languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:3.0.1, @docusaurus/module-type-aliases@npm:^3.0.1": - version: 3.0.1 - resolution: "@docusaurus/module-type-aliases@npm:3.0.1" +"@docusaurus/module-type-aliases@npm:3.5.2, @docusaurus/module-type-aliases@npm:^3.5.2": + version: 3.5.2 + resolution: "@docusaurus/module-type-aliases@npm:3.5.2" dependencies: - "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/types": 3.0.1 + "@docusaurus/types": 3.5.2 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" "@types/react-router-dom": "*" react-helmet-async: "*" - react-loadable: "npm:@docusaurus/react-loadable@5.5.2" + react-loadable: "npm:@docusaurus/react-loadable@6.0.0" peerDependencies: react: "*" react-dom: "*" - checksum: 08895f8b100df772bb9c9a8fcf9cd3ee83f0deafeb76fb9b14efd5cdd3313abb4a02032868bd458cb3a5f345942fd9f4c44833ce5042279b2241d462a1bf4cc2 + checksum: 0161db859d459bb25ac162f0c509fb1316dfb403a9e89f325a9bc7d9f35ae1825b9703a435777903ba93de827d4413b189bbd0c03018ac13d66b50633302ea80 languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-content-blog@npm:3.0.1" - dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/logger": 3.0.1 - "@docusaurus/mdx-loader": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-common": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 - cheerio: ^1.0.0-rc.12 +"@docusaurus/plugin-content-blog@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-blog@npm:3.5.2" + dependencies: + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 + cheerio: 1.0.0-rc.12 feed: ^4.2.2 fs-extra: ^11.1.1 lodash: ^4.17.21 @@ -2594,23 +3745,26 @@ __metadata: utility-types: ^3.10.0 webpack: ^5.88.1 peerDependencies: + "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 react-dom: ^18.0.0 - checksum: 20985fac48d2f77d560483d06d8fc21ea8c3a009be8d040da76bd4363279ad7fe8f98353bc6a50504403be3315508344faa62123ac3691912d27710fe3c6ec90 + checksum: c5997b9d86ccf939998f9d56e65491ecf9e677d8425e95a79b3b428041d4dfc4ecb03a18ef595777c3ad5bd65f4a2dd30d99cb6f1b411161bf7cd32027ecc6d5 languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-content-docs@npm:3.0.1" - dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/logger": 3.0.1 - "@docusaurus/mdx-loader": 3.0.1 - "@docusaurus/module-type-aliases": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 +"@docusaurus/plugin-content-docs@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-docs@npm:3.5.2" + dependencies: + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/module-type-aliases": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@types/react-router-config": ^5.0.7 combine-promises: ^1.1.0 fs-extra: ^11.1.1 @@ -2622,7 +3776,7 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ee3a12a49df2db112798e8d080365c9cc2afc4959f28772abe03eb9c806b919a9837669354b04a1ff99bf473cab1aa3b8b6ad740947a440a6b9cae09823ef6b2 + checksum: fb7ba7f8a6741b14bbe8db0bf1b12ff7a24d12c40d8276f32b9b393881d74bfed3bed4f1e5b0756cac0e43c4bd8106094d5cf6a3c527400e9713283fc3832dab languageName: node linkType: hard @@ -2653,129 +3807,129 @@ __metadata: languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-content-pages@npm:3.0.1" +"@docusaurus/plugin-content-pages@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-pages@npm:3.5.2" dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/mdx-loader": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 fs-extra: ^11.1.1 tslib: ^2.6.0 webpack: ^5.88.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 0a3bd568e4b9df11b5926c5be10f2ced08b241f1a6b8a08f556c57ce707ebb788b19937ec1d884474c4e275dc71affb91dd55a2965ad02a03545e3eae4976141 + checksum: 8b3f1040e8ec006c9431508e73ef3f61cd5759bece3770189f7d52609f91bd156c9b18d0608f9cb14c456a1d1823be6633c573d5eee7cf9bd142b0f978c7a745 languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-debug@npm:3.0.1" +"@docusaurus/plugin-debug@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-debug@npm:3.5.2" dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils": 3.0.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 fs-extra: ^11.1.1 react-json-view-lite: ^1.2.0 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 419f2bb61aceca70ffbba03e5e885303cea72055a41328d09d78fa2e40e7d5feb0ee4d66f056d54ac01f8d2361e890a072da6570da16f290c84746ced1582823 + checksum: a839e6c3a595ea202fdd7fbce638ab8df26ba73a8c7ead8c04d1bbb509ebe34e9633e7fe9eb54a7a733e93a03d74a60df4d9f6597b9621ff464280d4dd71db34 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-google-analytics@npm:3.0.1" +"@docusaurus/plugin-google-analytics@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-analytics@npm:3.5.2" dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 850930ed0860411142fe058562040f0b3a776be755670790273f48bfa37c7ee904d9107ec23d2ce210904610b72769ce0996a558c89414ac3687bd38bb50edf4 + checksum: 0b8c4d21333d40c2509d6ef807caaf69f085010c5deac514ab34f53b5486fd76766c90213dc98976a6c4d66fdfa14bf6b05594e51e8a53ec60c2a3fa08fd9a83 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-google-gtag@npm:3.0.1" +"@docusaurus/plugin-google-gtag@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-gtag@npm:3.5.2" dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@types/gtag.js": ^0.0.12 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 579a19a6dad3940801a170efc7e5c763c7f90b68d5ecdb2707b61311af321122e84cd0bb5ceb45669e76df712ea1747d6d30fa5a0574b69a7f337dd66b346a04 + checksum: 5d53c2483c8c7e3a8e842bd091a774d4041f0e165d216b3c02f031a224a77258c9456e8b2acd0500b4a0eff474a83c1b82803628db9d4b132514409936c68ac4 languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-google-tag-manager@npm:3.0.1" +"@docusaurus/plugin-google-tag-manager@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-tag-manager@npm:3.5.2" dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 1e3faf9496f75d43a81a5ff2921e783c87ef13d852cf678b54275fa0f79d70efdc127df6ae9c90ddce58b81384f39ec62de75d7e64e34ae96ea938cf234268c0 + checksum: 9a6fc2ca54ea677c6edfd78f4f392d7d9ae86afd085fcda96d5ac41efa441352c25a2519595d9d15fb9b838e2ae39837f0daf02e2406c5cd56199ae237bd7b7a languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/plugin-sitemap@npm:3.0.1" - dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/logger": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-common": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 +"@docusaurus/plugin-sitemap@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-sitemap@npm:3.5.2" + dependencies: + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 fs-extra: ^11.1.1 sitemap: ^7.1.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 464359fa44143f3e686d02cd70f86741cdd4a74f29f212b83767617fc1dacbfddfa4321c16e0c253849ff41a75078fabbfdf8637d7a141fb1a0354360db2b2bb + checksum: 26b6bceb7ab87fe7f6f666742d1e81de32cdacc5aaa3d45d91002c7d64e3258f3d0aac87c6b0d442eaf34ede2af4b7521b50737f2e8e2718daff6fce10230213 languageName: node linkType: hard -"@docusaurus/preset-classic@npm:^3.0.1": - version: 3.0.1 - resolution: "@docusaurus/preset-classic@npm:3.0.1" - dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/plugin-content-blog": 3.0.1 - "@docusaurus/plugin-content-docs": 3.0.1 - "@docusaurus/plugin-content-pages": 3.0.1 - "@docusaurus/plugin-debug": 3.0.1 - "@docusaurus/plugin-google-analytics": 3.0.1 - "@docusaurus/plugin-google-gtag": 3.0.1 - "@docusaurus/plugin-google-tag-manager": 3.0.1 - "@docusaurus/plugin-sitemap": 3.0.1 - "@docusaurus/theme-classic": 3.0.1 - "@docusaurus/theme-common": 3.0.1 - "@docusaurus/theme-search-algolia": 3.0.1 - "@docusaurus/types": 3.0.1 +"@docusaurus/preset-classic@npm:^3.5.2": + version: 3.5.2 + resolution: "@docusaurus/preset-classic@npm:3.5.2" + dependencies: + "@docusaurus/core": 3.5.2 + "@docusaurus/plugin-content-blog": 3.5.2 + "@docusaurus/plugin-content-docs": 3.5.2 + "@docusaurus/plugin-content-pages": 3.5.2 + "@docusaurus/plugin-debug": 3.5.2 + "@docusaurus/plugin-google-analytics": 3.5.2 + "@docusaurus/plugin-google-gtag": 3.5.2 + "@docusaurus/plugin-google-tag-manager": 3.5.2 + "@docusaurus/plugin-sitemap": 3.5.2 + "@docusaurus/theme-classic": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/theme-search-algolia": 3.5.2 + "@docusaurus/types": 3.5.2 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 03e75324c92a70aea9980f29a993e79967e5ca85d2db1b18bcb00e6c3d8711fec1a1728f92247d4d35a119ae5c3fb5b5d728ea33591f36e8bd43fa6acb1c791c + checksum: ec578e62b3b13b1874b14235a448a913c2d2358ea9b9d9c60bb250be468ab62387c88ec44e1ee82ad5b3d7243306e31919888a80eae62e5e8eab0ae12194bf69 languageName: node linkType: hard @@ -2791,26 +3945,26 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-classic@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/theme-classic@npm:3.0.1" - dependencies: - "@docusaurus/core": 3.0.1 - "@docusaurus/mdx-loader": 3.0.1 - "@docusaurus/module-type-aliases": 3.0.1 - "@docusaurus/plugin-content-blog": 3.0.1 - "@docusaurus/plugin-content-docs": 3.0.1 - "@docusaurus/plugin-content-pages": 3.0.1 - "@docusaurus/theme-common": 3.0.1 - "@docusaurus/theme-translations": 3.0.1 - "@docusaurus/types": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-common": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 +"@docusaurus/theme-classic@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-classic@npm:3.5.2" + dependencies: + "@docusaurus/core": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/module-type-aliases": 3.5.2 + "@docusaurus/plugin-content-blog": 3.5.2 + "@docusaurus/plugin-content-docs": 3.5.2 + "@docusaurus/plugin-content-pages": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/theme-translations": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@mdx-js/react": ^3.0.0 clsx: ^2.0.0 copy-text-to-clipboard: ^3.2.0 - infima: 0.2.0-alpha.43 + infima: 0.2.0-alpha.44 lodash: ^4.17.21 nprogress: ^0.2.0 postcss: ^8.4.26 @@ -2823,21 +3977,18 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 86cef28b5f93d01f15cb134283b8d1006466d661cc39c09c585e56a6a98b09816f8e7cef24b164e8a378b6deb4ed8984fdc329d09fdcbe83fa51529091ccfad8 + checksum: 6c415b01ad24bb43eb166e2b780a84356ff14a627627f6a541c2803832d56c4f9409a5636048693d2d24804f59c2cc7bda925d9ef999a8276fe125477d2b2e1e languageName: node linkType: hard -"@docusaurus/theme-common@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/theme-common@npm:3.0.1" - dependencies: - "@docusaurus/mdx-loader": 3.0.1 - "@docusaurus/module-type-aliases": 3.0.1 - "@docusaurus/plugin-content-blog": 3.0.1 - "@docusaurus/plugin-content-docs": 3.0.1 - "@docusaurus/plugin-content-pages": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-common": 3.0.1 +"@docusaurus/theme-common@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-common@npm:3.5.2" + dependencies: + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/module-type-aliases": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -2847,24 +3998,25 @@ __metadata: tslib: ^2.6.0 utility-types: ^3.10.0 peerDependencies: + "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 react-dom: ^18.0.0 - checksum: 99fb138fd2fb499d53ee81ae717768b5cb6556ddd337b6d1a399815cb428eed2c04d2823e2040fd4db27bc79681f6333ac1ea78d760ff7fc4475d16d1790552a + checksum: c78ec7f6035abc920a2a0bc1ad78920178a5452538a3a70794eca8d4b976725f6ccc464ee3092afd31ca59b4e061ad4c21cdce7f5e10b06567075814b2fc2002 languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/theme-search-algolia@npm:3.0.1" +"@docusaurus/theme-search-algolia@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-search-algolia@npm:3.5.2" dependencies: "@docsearch/react": ^3.5.2 - "@docusaurus/core": 3.0.1 - "@docusaurus/logger": 3.0.1 - "@docusaurus/plugin-content-docs": 3.0.1 - "@docusaurus/theme-common": 3.0.1 - "@docusaurus/theme-translations": 3.0.1 - "@docusaurus/utils": 3.0.1 - "@docusaurus/utils-validation": 3.0.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/plugin-content-docs": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/theme-translations": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 algoliasearch: ^4.18.0 algoliasearch-helper: ^3.13.3 clsx: ^2.0.0 @@ -2876,17 +4028,17 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 24a38dbd7085ea78c412e50c94dda7e0ecb80046dd18c1fdb515d81b21be5cdbc706705a5155600510b0814698abb234885a576d90e0db9cf3c5983d0bf51462 + checksum: e945e3001996477597bfad074eaef074cf4c5365ed3076c3109130a2252b266e4e2fac46904a0626eedeff23b9ac11e7b985cc71f5485ede52d3ddf379b7959b languageName: node linkType: hard -"@docusaurus/theme-translations@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/theme-translations@npm:3.0.1" +"@docusaurus/theme-translations@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-translations@npm:3.5.2" dependencies: fs-extra: ^11.1.1 tslib: ^2.6.0 - checksum: a1df314ddaeb7f453867c5ee5424b36d31c6d6541f86b3927881b77333e997b87e720c0285f3be507283cb851537ff154ce0ddbd5e771c184c8aa10af721d7c2 + checksum: dc523c74a13fb8552c03e547c6de1c21881d899cc74bf088a2bed716e0ef1a4ceba2726c43656d87fff60413ca191f5ea946b182e4ae4129c14da832b5194d82 languageName: node linkType: hard @@ -2900,10 +4052,10 @@ __metadata: languageName: node linkType: hard -"@docusaurus/tsconfig@npm:^3.0.1": - version: 3.0.1 - resolution: "@docusaurus/tsconfig@npm:3.0.1" - checksum: a191e527740ea09cc4783ab45f106989f692d100e83768a4398fc08d3d41f0645afdce83aa89a1b251d5899544105af09e795af4d0db54247403a180f3c43098 +"@docusaurus/tsconfig@npm:^3.5.2": + version: 3.5.2 + resolution: "@docusaurus/tsconfig@npm:3.5.2" + checksum: 808a17eaf422ae9a948c6558dd1e92d4700b067ead3a63a84049c6845bf94f84e311cd0e4d517047fe9ea057efe393bb22c2d5c92d727d06c9f895e971f2c3ea languageName: node linkType: hard @@ -2926,10 +4078,11 @@ __metadata: languageName: node linkType: hard -"@docusaurus/types@npm:3.0.1, @docusaurus/types@npm:^3.0.1": - version: 3.0.1 - resolution: "@docusaurus/types@npm:3.0.1" +"@docusaurus/types@npm:3.5.2, @docusaurus/types@npm:^3.5.2": + version: 3.5.2 + resolution: "@docusaurus/types@npm:3.5.2" dependencies: + "@mdx-js/mdx": ^3.0.0 "@types/history": ^4.7.11 "@types/react": "*" commander: ^5.1.0 @@ -2941,7 +4094,7 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 1874e66435e986262ad06639b812d49aa5c81a29815b27d31370d055335cebdad77ee0276504497b1765c489e5c5faf9795df97e52649af931d1cf381c4afa77 + checksum: e39451b7b08673ad5e1551ee6e4286f90f2554cf9ba245abfa56670550f48afca9c57b01c10ffa21dacb734c0fcd067150eeb2b1c1ebb1692f1f538b1eed0029 languageName: node linkType: hard @@ -2959,9 +4112,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/utils-common@npm:3.0.1" +"@docusaurus/utils-common@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils-common@npm:3.5.2" dependencies: tslib: ^2.6.0 peerDependencies: @@ -2969,7 +4122,7 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 7d4eb39258539d594cf1432d07be0325de5a02c2a00418e022b0cd2d4374788a7cc5dd3febad6f34744e5a1e76646ae909ffbdf2024284f31c579d1f1ff055d8 + checksum: 9d550c89663d4271456ae0832c82a1691207ccc95e21df3a05a4bd6bbd2624bb9e3ab7327d939c04b2023378987bcf99321b2c37be1af214852832f65d6db14a languageName: node linkType: hard @@ -2986,16 +4139,19 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils-validation@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/utils-validation@npm:3.0.1" +"@docusaurus/utils-validation@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils-validation@npm:3.5.2" dependencies: - "@docusaurus/logger": 3.0.1 - "@docusaurus/utils": 3.0.1 + "@docusaurus/logger": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + fs-extra: ^11.2.0 joi: ^17.9.2 js-yaml: ^4.1.0 + lodash: ^4.17.21 tslib: ^2.6.0 - checksum: c52edd61906ee004cea95ca33f81ec10a40276cad29f1aef505220cea4b922c1734b765d9c55b0889822351876ea545a73f7f3a4fbbb574f625fe455f8387033 + checksum: 5966e6d0e8f26292c629899f13b545501b53b345b0e2291bb47aaa80d7c9c5cf155e15a4ecd073a4095ee7c83c6db3612e0a34f81a8187fd20410b1aeb92d731 languageName: node linkType: hard @@ -3028,12 +4184,13 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils@npm:3.0.1": - version: 3.0.1 - resolution: "@docusaurus/utils@npm:3.0.1" +"@docusaurus/utils@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils@npm:3.5.2" dependencies: - "@docusaurus/logger": 3.0.1 - "@svgr/webpack": ^6.5.1 + "@docusaurus/logger": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@svgr/webpack": ^8.1.0 escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 fs-extra: ^11.1.1 @@ -3044,17 +4201,19 @@ __metadata: js-yaml: ^4.1.0 lodash: ^4.17.21 micromatch: ^4.0.5 + prompts: ^2.4.2 resolve-pathname: ^3.0.0 shelljs: ^0.8.5 tslib: ^2.6.0 url-loader: ^4.1.1 + utility-types: ^3.10.0 webpack: ^5.88.1 peerDependencies: "@docusaurus/types": "*" peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 5a8c5d8dd9cf1ad9ed1cecff3be3cbe041ebf8f51e2744af8aa006df67367f24d0888181566ed9ab2837b931a4fb135d943eadfde99708468f90f18795d413b5 + checksum: 0e0f4fc65ed076d4e4b551ecb61447b7c2468060d1655afff314515844ae34dc0546f467f53bff535f3144afc109e974da27fadb7c678a5d19966bed9e7a27c4 languageName: node linkType: hard @@ -3771,6 +4930,17 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 + languageName: node + linkType: hard + "@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.1 resolution: "@jridgewell/resolve-uri@npm:3.1.1" @@ -3785,6 +4955,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + languageName: node + linkType: hard + "@jridgewell/source-map@npm:^0.3.3": version: 0.3.5 resolution: "@jridgewell/source-map@npm:0.3.5" @@ -3822,6 +4999,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.20": version: 0.3.22 resolution: "@jridgewell/trace-mapping@npm:0.3.22" @@ -5007,6 +6194,15 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3fc8e35d16f5abe0af5efe5851f27581225ac405d6a1ca44cda0df064cddfcc29a428c48c2e4bef6cebf627c9ac2f652a096030edb02cf5a120ce28d3c234710 + languageName: node + linkType: hard + "@svgr/babel-plugin-add-jsx-attribute@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:6.5.1" @@ -5016,7 +6212,7 @@ __metadata: languageName: node linkType: hard -"@svgr/babel-plugin-remove-jsx-attribute@npm:*": +"@svgr/babel-plugin-remove-jsx-attribute@npm:*, @svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0": version: 8.0.0 resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0" peerDependencies: @@ -5025,7 +6221,7 @@ __metadata: languageName: node linkType: hard -"@svgr/babel-plugin-remove-jsx-empty-expression@npm:*": +"@svgr/babel-plugin-remove-jsx-empty-expression@npm:*, @svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0": version: 8.0.0 resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0" peerDependencies: @@ -5034,6 +6230,15 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 1edda65ef4f4dd8f021143c8ec276a08f6baa6f733b8e8ee2e7775597bf6b97afb47fdeefd579d6ae6c959fe2e634f55cd61d99377631212228c8cfb351b8921 + languageName: node + linkType: hard + "@svgr/babel-plugin-replace-jsx-attribute-value@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:6.5.1" @@ -5043,6 +6248,15 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 876cec891488992e6a9aebb8155e2bea4ec461b4718c51de36e988e00e271c6d9d01ef6be17b9effd44b2b3d7db0b41c161a5904a46ae6f38b26b387ad7f3709 + languageName: node + linkType: hard + "@svgr/babel-plugin-svg-dynamic-title@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:6.5.1" @@ -5052,6 +6266,15 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: be0e2d391164428327d9ec469a52cea7d93189c6b0e2c290999e048f597d777852f701c64dca44cd45b31ed14a7f859520326e2e4ad7c3a4545d0aa235bc7e9a + languageName: node + linkType: hard + "@svgr/babel-plugin-svg-em-dimensions@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:6.5.1" @@ -5061,6 +6284,15 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 85b434a57572f53bd2b9f0606f253e1fcf57b4a8c554ec3f2d43ed17f50d8cae200cb3aaf1ec9d626e1456e8b135dce530ae047eb0bed6d4bf98a752d6640459 + languageName: node + linkType: hard + "@svgr/babel-plugin-transform-react-native-svg@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:6.5.1" @@ -5070,6 +6302,15 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-plugin-transform-svg-component@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-transform-svg-component@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 04e2023d75693eeb0890341c40e449881184663056c249be7e5c80168e4aabb0fadd255e8d5d2dbf54b8c2a6e700efba994377135bfa4060dc4a2e860116ef8c + languageName: node + linkType: hard + "@svgr/babel-plugin-transform-svg-component@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-plugin-transform-svg-component@npm:6.5.1" @@ -5079,6 +6320,24 @@ __metadata: languageName: node linkType: hard +"@svgr/babel-preset@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/babel-preset@npm:8.1.0" + dependencies: + "@svgr/babel-plugin-add-jsx-attribute": 8.0.0 + "@svgr/babel-plugin-remove-jsx-attribute": 8.0.0 + "@svgr/babel-plugin-remove-jsx-empty-expression": 8.0.0 + "@svgr/babel-plugin-replace-jsx-attribute-value": 8.0.0 + "@svgr/babel-plugin-svg-dynamic-title": 8.0.0 + "@svgr/babel-plugin-svg-em-dimensions": 8.0.0 + "@svgr/babel-plugin-transform-react-native-svg": 8.1.0 + "@svgr/babel-plugin-transform-svg-component": 8.0.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3a67930f080b8891e1e8e2595716b879c944d253112bae763dce59807ba23454d162216c8d66a0a0e3d4f38a649ecd6c387e545d1e1261dd69a68e9a3392ee08 + languageName: node + linkType: hard + "@svgr/babel-preset@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/babel-preset@npm:6.5.1" @@ -5097,6 +6356,19 @@ __metadata: languageName: node linkType: hard +"@svgr/core@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/core@npm:8.1.0" + dependencies: + "@babel/core": ^7.21.3 + "@svgr/babel-preset": 8.1.0 + camelcase: ^6.2.0 + cosmiconfig: ^8.1.3 + snake-case: ^3.0.4 + checksum: da4a12865c7dc59829d58df8bd232d6c85b7115fda40da0d2f844a1a51886e2e945560596ecfc0345d37837ac457de86a931e8b8d8550e729e0c688c02250d8a + languageName: node + linkType: hard + "@svgr/core@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/core@npm:6.5.1" @@ -5110,6 +6382,16 @@ __metadata: languageName: node linkType: hard +"@svgr/hast-util-to-babel-ast@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/hast-util-to-babel-ast@npm:8.0.0" + dependencies: + "@babel/types": ^7.21.3 + entities: ^4.4.0 + checksum: 88401281a38bbc7527e65ff5437970414391a86158ef4b4046c89764c156d2d39ecd7cce77be8a51994c9fb3249170cb1eb8b9128b62faaa81743ef6ed3534ab + languageName: node + linkType: hard + "@svgr/hast-util-to-babel-ast@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/hast-util-to-babel-ast@npm:6.5.1" @@ -5120,6 +6402,20 @@ __metadata: languageName: node linkType: hard +"@svgr/plugin-jsx@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/plugin-jsx@npm:8.1.0" + dependencies: + "@babel/core": ^7.21.3 + "@svgr/babel-preset": 8.1.0 + "@svgr/hast-util-to-babel-ast": 8.0.0 + svg-parser: ^2.0.4 + peerDependencies: + "@svgr/core": "*" + checksum: 0418a9780753d3544912ee2dad5d2cf8d12e1ba74df8053651b3886aeda54d5f0f7d2dece0af5e0d838332c4f139a57f0dabaa3ca1afa4d1a765efce6a7656f2 + languageName: node + linkType: hard + "@svgr/plugin-jsx@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/plugin-jsx@npm:6.5.1" @@ -5134,6 +6430,19 @@ __metadata: languageName: node linkType: hard +"@svgr/plugin-svgo@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/plugin-svgo@npm:8.1.0" + dependencies: + cosmiconfig: ^8.1.3 + deepmerge: ^4.3.1 + svgo: ^3.0.2 + peerDependencies: + "@svgr/core": "*" + checksum: 59d9d214cebaacca9ca71a561f463d8b7e5a68ca9443e4792a42d903acd52259b1790c0680bc6afecc3f00a255a6cbd7ea278a9f625bac443620ea58a590c2d0 + languageName: node + linkType: hard + "@svgr/plugin-svgo@npm:^6.5.1": version: 6.5.1 resolution: "@svgr/plugin-svgo@npm:6.5.1" @@ -5147,7 +6456,7 @@ __metadata: languageName: node linkType: hard -"@svgr/webpack@npm:^6.2.1, @svgr/webpack@npm:^6.5.1": +"@svgr/webpack@npm:^6.2.1": version: 6.5.1 resolution: "@svgr/webpack@npm:6.5.1" dependencies: @@ -5163,6 +6472,22 @@ __metadata: languageName: node linkType: hard +"@svgr/webpack@npm:^8.1.0": + version: 8.1.0 + resolution: "@svgr/webpack@npm:8.1.0" + dependencies: + "@babel/core": ^7.21.3 + "@babel/plugin-transform-react-constant-elements": ^7.21.3 + "@babel/preset-env": ^7.20.2 + "@babel/preset-react": ^7.18.6 + "@babel/preset-typescript": ^7.21.0 + "@svgr/core": 8.1.0 + "@svgr/plugin-jsx": 8.1.0 + "@svgr/plugin-svgo": 8.1.0 + checksum: c6eec5b0cf2fb2ecd3a7a362d272eda35330b17c76802a3481f499b5d07ff8f87b31d2571043bff399b051a1767b1e2e499dbf186104d1c06d76f9f1535fac01 + languageName: node + linkType: hard + "@szmarczak/http-timer@npm:^1.1.2": version: 1.1.2 resolution: "@szmarczak/http-timer@npm:1.1.2" @@ -7138,6 +8463,24 @@ __metadata: languageName: node linkType: hard +"autoprefixer@npm:^10.4.19": + version: 10.4.20 + resolution: "autoprefixer@npm:10.4.20" + dependencies: + browserslist: ^4.23.3 + caniuse-lite: ^1.0.30001646 + fraction.js: ^4.3.7 + normalize-range: ^0.1.2 + picocolors: ^1.0.1 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.1.0 + bin: + autoprefixer: bin/autoprefixer + checksum: 187cec2ec356631932b212f76dc64f4419c117fdb2fb9eeeb40867d38ba5ca5ba734e6ceefc9e3af4eec8258e60accdf5cbf2b7708798598fde35cdc3de562d6 + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.5": version: 1.0.5 resolution: "available-typed-arrays@npm:1.0.5" @@ -7230,6 +8573,19 @@ __metadata: languageName: node linkType: hard +"babel-plugin-polyfill-corejs2@npm:^0.4.10": + version: 0.4.11 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.11" + dependencies: + "@babel/compat-data": ^7.22.6 + "@babel/helper-define-polyfill-provider": ^0.6.2 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: f098353ce7c7dde1a1d2710858e01b471e85689110c9e37813e009072347eb8c55d5f84d20d3bf1cab31755f20078ba90f8855fdc4686a9daa826a95ff280bd7 + languageName: node + linkType: hard + "babel-plugin-polyfill-corejs2@npm:^0.4.6": version: 0.4.6 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.6" @@ -7243,6 +8599,18 @@ __metadata: languageName: node linkType: hard +"babel-plugin-polyfill-corejs3@npm:^0.10.6": + version: 0.10.6 + resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6" + dependencies: + "@babel/helper-define-polyfill-provider": ^0.6.2 + core-js-compat: ^3.38.0 + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: f762f29f7acca576897c63149c850f0a72babd3fb9ea436a2e36f0c339161c4b912a77828541d8188ce8a91e50965c6687120cf36071eabb1b7aa92f279e2164 + languageName: node + linkType: hard + "babel-plugin-polyfill-corejs3@npm:^0.8.5": version: 0.8.6 resolution: "babel-plugin-polyfill-corejs3@npm:0.8.6" @@ -7266,6 +8634,17 @@ __metadata: languageName: node linkType: hard +"babel-plugin-polyfill-regenerator@npm:^0.6.1": + version: 0.6.2 + resolution: "babel-plugin-polyfill-regenerator@npm:0.6.2" + dependencies: + "@babel/helper-define-polyfill-provider": ^0.6.2 + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 150233571072b6b3dfe946242da39cba8587b7f908d1c006f7545fc88b0e3c3018d445739beb61e7a75835f0c2751dbe884a94ff9b245ec42369d9267e0e1b3f + languageName: node + linkType: hard + "bail@npm:^1.0.0": version: 1.0.5 resolution: "bail@npm:1.0.5" @@ -7590,6 +8969,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.23.0, browserslist@npm:^4.23.1, browserslist@npm:^4.23.3": + version: 4.24.0 + resolution: "browserslist@npm:4.24.0" + dependencies: + caniuse-lite: ^1.0.30001663 + electron-to-chromium: ^1.5.28 + node-releases: ^2.0.18 + update-browserslist-db: ^1.1.0 + bin: + browserslist: cli.js + checksum: de200d3eb8d6ed819dad99719099a28fb6ebeb88016a5ac42fbdc11607e910c236a84ca1b0bbf232477d4b88ab64e8ab6aa67557cdd40a73ca9c2834f92ccce0 + languageName: node + linkType: hard + "bs58@npm:^4.0.0": version: 4.0.1 resolution: "bs58@npm:4.0.1" @@ -7816,6 +9209,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001646, caniuse-lite@npm:^1.0.30001663": + version: 1.0.30001664 + resolution: "caniuse-lite@npm:1.0.30001664" + checksum: cee25b4ea8a84779b7c9a60c1f9e304f6d99b79ef622b25fbc7873b4e55e8722a1091dd6c8b77bd7723e9f26a84b4a820a50a864989dd477e7ee51dc30461dca + languageName: node + linkType: hard + "ccount@npm:^1.0.0": version: 1.1.0 resolution: "ccount@npm:1.1.0" @@ -7988,7 +9388,7 @@ __metadata: languageName: node linkType: hard -"cheerio@npm:^1.0.0-rc.12, cheerio@npm:^1.0.0-rc.3": +"cheerio@npm:1.0.0-rc.12, cheerio@npm:^1.0.0-rc.3": version: 1.0.0-rc.12 resolution: "cheerio@npm:1.0.0-rc.12" dependencies: @@ -8313,7 +9713,7 @@ __metadata: languageName: node linkType: hard -"colord@npm:^2.9.1": +"colord@npm:^2.9.1, colord@npm:^2.9.3": version: 2.9.3 resolution: "colord@npm:2.9.3" checksum: 95d909bfbcfd8d5605cbb5af56f2d1ce2b323990258fd7c0d2eb0e6d3bb177254d7fb8213758db56bb4ede708964f78c6b992b326615f81a18a6aaf11d64c650 @@ -8686,6 +10086,15 @@ __metadata: languageName: node linkType: hard +"core-js-compat@npm:^3.37.1, core-js-compat@npm:^3.38.0": + version: 3.38.1 + resolution: "core-js-compat@npm:3.38.1" + dependencies: + browserslist: ^4.23.3 + checksum: a0a5673bcd59f588f0cd0b59cdacd4712b82909738a87406d334dd412eb3d273ae72b275bdd8e8fef63fca9ef12b42ed651be139c7c44c8a1acb423c8906992e + languageName: node + linkType: hard + "core-js-pure@npm:^3.30.2": version: 3.34.0 resolution: "core-js-pure@npm:3.34.0" @@ -8733,7 +10142,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^8.2.0": +"cosmiconfig@npm:^8.1.3, cosmiconfig@npm:^8.2.0": version: 8.3.6 resolution: "cosmiconfig@npm:8.3.6" dependencies: @@ -8964,6 +10373,15 @@ __metadata: languageName: node linkType: hard +"css-declaration-sorter@npm:^7.2.0": + version: 7.2.0 + resolution: "css-declaration-sorter@npm:7.2.0" + peerDependencies: + postcss: ^8.0.9 + checksum: 69b2f63a1c7c593123fabcbb353618ed01eb75f6404da9321328fbb30d603d89c47195129fadf1dc316e1406a0881400b324c2bded9438c47196e1c96ec726dd + languageName: node + linkType: hard + "css-loader@npm:^6.7.1, css-loader@npm:^6.8.1": version: 6.8.1 resolution: "css-loader@npm:6.8.1" @@ -8982,7 +10400,7 @@ __metadata: languageName: node linkType: hard -"css-minimizer-webpack-plugin@npm:^4.0.0, css-minimizer-webpack-plugin@npm:^4.2.2": +"css-minimizer-webpack-plugin@npm:^4.0.0": version: 4.2.2 resolution: "css-minimizer-webpack-plugin@npm:4.2.2" dependencies: @@ -9011,6 +10429,35 @@ __metadata: languageName: node linkType: hard +"css-minimizer-webpack-plugin@npm:^5.0.1": + version: 5.0.1 + resolution: "css-minimizer-webpack-plugin@npm:5.0.1" + dependencies: + "@jridgewell/trace-mapping": ^0.3.18 + cssnano: ^6.0.1 + jest-worker: ^29.4.3 + postcss: ^8.4.24 + schema-utils: ^4.0.1 + serialize-javascript: ^6.0.1 + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + "@parcel/css": + optional: true + "@swc/css": + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true + checksum: 10055802c61d1ae72584eac03b6bd221ecbefde11d337be44a5459d8de075b38f91b80949f95cd0c3a10295615ee013f82130bfac5fe9b5b3e8e75531f232680 + languageName: node + linkType: hard + "css-select@npm:^4.1.3": version: 4.3.0 resolution: "css-select@npm:4.3.0" @@ -9047,6 +10494,26 @@ __metadata: languageName: node linkType: hard +"css-tree@npm:^2.3.1": + version: 2.3.1 + resolution: "css-tree@npm:2.3.1" + dependencies: + mdn-data: 2.0.30 + source-map-js: ^1.0.1 + checksum: 493cc24b5c22b05ee5314b8a0d72d8a5869491c1458017ae5ed75aeb6c3596637dbe1b11dac2548974624adec9f7a1f3a6cf40593dc1f9185eb0e8279543fbc0 + languageName: node + linkType: hard + +"css-tree@npm:~2.2.0": + version: 2.2.1 + resolution: "css-tree@npm:2.2.1" + dependencies: + mdn-data: 2.0.28 + source-map-js: ^1.0.1 + checksum: b94aa8cc2f09e6f66c91548411fcf74badcbad3e150345074715012d16333ce573596ff5dfca03c2a87edf1924716db765120f94247e919d72753628ba3aba27 + languageName: node + linkType: hard + "css-what@npm:^6.0.1, css-what@npm:^6.1.0": version: 6.1.0 resolution: "css-what@npm:6.1.0" @@ -9063,7 +10530,7 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-advanced@npm:^5.3.10, cssnano-preset-advanced@npm:^5.3.8": +"cssnano-preset-advanced@npm:^5.3.8": version: 5.3.10 resolution: "cssnano-preset-advanced@npm:5.3.10" dependencies: @@ -9079,6 +10546,23 @@ __metadata: languageName: node linkType: hard +"cssnano-preset-advanced@npm:^6.1.2": + version: 6.1.2 + resolution: "cssnano-preset-advanced@npm:6.1.2" + dependencies: + autoprefixer: ^10.4.19 + browserslist: ^4.23.0 + cssnano-preset-default: ^6.1.2 + postcss-discard-unused: ^6.0.5 + postcss-merge-idents: ^6.0.3 + postcss-reduce-idents: ^6.0.3 + postcss-zindex: ^6.0.2 + peerDependencies: + postcss: ^8.4.31 + checksum: cf70e27915947412730abb3075587efb66bcea58d7f1b906a7225bb4a40c9ca40150251a2ac33363d4f55bbdeb9ba000c242fa6244ee36cba2477ac07fbbe791 + languageName: node + linkType: hard + "cssnano-preset-default@npm:^5.2.14": version: 5.2.14 resolution: "cssnano-preset-default@npm:5.2.14" @@ -9118,6 +10602,46 @@ __metadata: languageName: node linkType: hard +"cssnano-preset-default@npm:^6.1.2": + version: 6.1.2 + resolution: "cssnano-preset-default@npm:6.1.2" + dependencies: + browserslist: ^4.23.0 + css-declaration-sorter: ^7.2.0 + cssnano-utils: ^4.0.2 + postcss-calc: ^9.0.1 + postcss-colormin: ^6.1.0 + postcss-convert-values: ^6.1.0 + postcss-discard-comments: ^6.0.2 + postcss-discard-duplicates: ^6.0.3 + postcss-discard-empty: ^6.0.3 + postcss-discard-overridden: ^6.0.2 + postcss-merge-longhand: ^6.0.5 + postcss-merge-rules: ^6.1.1 + postcss-minify-font-values: ^6.1.0 + postcss-minify-gradients: ^6.0.3 + postcss-minify-params: ^6.1.0 + postcss-minify-selectors: ^6.0.4 + postcss-normalize-charset: ^6.0.2 + postcss-normalize-display-values: ^6.0.2 + postcss-normalize-positions: ^6.0.2 + postcss-normalize-repeat-style: ^6.0.2 + postcss-normalize-string: ^6.0.2 + postcss-normalize-timing-functions: ^6.0.2 + postcss-normalize-unicode: ^6.1.0 + postcss-normalize-url: ^6.0.2 + postcss-normalize-whitespace: ^6.0.2 + postcss-ordered-values: ^6.0.2 + postcss-reduce-initial: ^6.1.0 + postcss-reduce-transforms: ^6.0.2 + postcss-svgo: ^6.0.3 + postcss-unique-selectors: ^6.0.4 + peerDependencies: + postcss: ^8.4.31 + checksum: 51d93e52df7141143947dc4695b5087c04b41ea153e4f4c0282ac012b62c7457c6aca244f604ae94fa3b4840903a30a1e7df38f8610e0b304d05e3065375ee56 + languageName: node + linkType: hard + "cssnano-utils@npm:^3.1.0": version: 3.1.0 resolution: "cssnano-utils@npm:3.1.0" @@ -9127,7 +10651,16 @@ __metadata: languageName: node linkType: hard -"cssnano@npm:^5.1.12, cssnano@npm:^5.1.15, cssnano@npm:^5.1.8": +"cssnano-utils@npm:^4.0.2": + version: 4.0.2 + resolution: "cssnano-utils@npm:4.0.2" + peerDependencies: + postcss: ^8.4.31 + checksum: f04c6854e75d847c7a43aff835e003d5bc7387ddfc476f0ad3a2d63663d0cec41047d46604c1717bf6b5a8e24e54bb519e465ff78d62c7e073c7cbe2279bebaf + languageName: node + linkType: hard + +"cssnano@npm:^5.1.12, cssnano@npm:^5.1.8": version: 5.1.15 resolution: "cssnano@npm:5.1.15" dependencies: @@ -9140,6 +10673,18 @@ __metadata: languageName: node linkType: hard +"cssnano@npm:^6.0.1, cssnano@npm:^6.1.2": + version: 6.1.2 + resolution: "cssnano@npm:6.1.2" + dependencies: + cssnano-preset-default: ^6.1.2 + lilconfig: ^3.1.1 + peerDependencies: + postcss: ^8.4.31 + checksum: 65aad92c5ee0089ffd4cd933c18c65edbf7634f7c3cd833a499dc948aa7e4168be22130dfe83bde07fcdc87f7c45a02d09040b7f439498208bc90b8d5a9abcc8 + languageName: node + linkType: hard + "csso@npm:^4.2.0": version: 4.2.0 resolution: "csso@npm:4.2.0" @@ -9149,6 +10694,15 @@ __metadata: languageName: node linkType: hard +"csso@npm:^5.0.5": + version: 5.0.5 + resolution: "csso@npm:5.0.5" + dependencies: + css-tree: ~2.2.0 + checksum: 0ad858d36bf5012ed243e9ec69962a867509061986d2ee07cc040a4b26e4d062c00d4c07e5ba8d430706ceb02dd87edd30a52b5937fd45b1b6f2119c4993d59a + languageName: node + linkType: hard + "csstype@npm:^3.0.2": version: 3.1.3 resolution: "csstype@npm:3.1.3" @@ -9264,7 +10818,7 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.2.2": +"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.1": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052 @@ -9540,11 +11094,11 @@ __metadata: version: 0.0.0-use.local resolution: "docs@workspace:docs" dependencies: - "@docusaurus/core": ^3.0.1 - "@docusaurus/module-type-aliases": ^3.0.1 - "@docusaurus/preset-classic": ^3.0.1 - "@docusaurus/tsconfig": ^3.0.1 - "@docusaurus/types": ^3.0.1 + "@docusaurus/core": ^3.5.2 + "@docusaurus/module-type-aliases": ^3.5.2 + "@docusaurus/preset-classic": ^3.5.2 + "@docusaurus/tsconfig": ^3.5.2 + "@docusaurus/types": ^3.5.2 "@easyops-cn/docusaurus-search-local": ^0.35.0 "@mdx-js/react": ^3.0.0 "@noir-lang/noir_js": "workspace:*" @@ -9734,6 +11288,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.28": + version: 1.5.29 + resolution: "electron-to-chromium@npm:1.5.29" + checksum: c1de62aaea88c9b3ba32f8f2703b9d77a81633099a8f61365eaf9855d36e72189dcd99b9c3b8b2804afa403ac2ce0b00c23affa6f19d17b04ce0076f66a546b6 + languageName: node + linkType: hard + "elliptic@npm:6.5.4, elliptic@npm:^6.5.2, elliptic@npm:^6.5.4": version: 6.5.4 resolution: "elliptic@npm:6.5.4" @@ -10068,6 +11629,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 47b029c83de01b0d17ad99ed766347b974b0d628e848de404018f3abee728e987da0d2d370ad4574aa3d5b5bfc368754fd085d69a30f8e75903486ec4b5b709e + languageName: node + linkType: hard + "escape-goat@npm:^2.0.0": version: 2.1.1 resolution: "escape-goat@npm:2.1.1" @@ -11015,7 +12583,7 @@ __metadata: languageName: node linkType: hard -"fraction.js@npm:^4.3.6": +"fraction.js@npm:^4.3.6, fraction.js@npm:^4.3.7": version: 4.3.7 resolution: "fraction.js@npm:4.3.7" checksum: e1553ae3f08e3ba0e8c06e43a3ab20b319966dfb7ddb96fd9b5d0ee11a66571af7f993229c88ebbb0d4a816eb813a24ed48207b140d442a8f76f33763b8d1f3f @@ -11040,7 +12608,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^11.1.1": +"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": version: 11.2.0 resolution: "fs-extra@npm:11.2.0" dependencies: @@ -12477,10 +14045,10 @@ __metadata: languageName: node linkType: hard -"infima@npm:0.2.0-alpha.43": - version: 0.2.0-alpha.43 - resolution: "infima@npm:0.2.0-alpha.43" - checksum: fc5f79240e940eddd750439511767092ccb4051e5e91d253ec7630a9e7ce691812da3aa0f05e46b4c0a95dbfadeae5714fd0073f8d2df12e5aaff0697a1d6aa2 +"infima@npm:0.2.0-alpha.44": + version: 0.2.0-alpha.44 + resolution: "infima@npm:0.2.0-alpha.44" + checksum: e9871f4056c0c8b311fcd32e2864d23a8f6807af5ff32d3c4d8271ad9971b5a7ea5016787a6b215893bb3e9f5f14326816bc05151d576dd375b0d79279cdfa8b languageName: node linkType: hard @@ -13213,7 +14781,7 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^29.1.2": +"jest-worker@npm:^29.1.2, jest-worker@npm:^29.4.3": version: 29.7.0 resolution: "jest-worker@npm:29.7.0" dependencies: @@ -13731,6 +15299,13 @@ __metadata: languageName: node linkType: hard +"lilconfig@npm:^3.1.1": + version: 3.1.2 + resolution: "lilconfig@npm:3.1.2" + checksum: 4e8b83ddd1d0ad722600994e6ba5d858ddca14f0587aa6b9c8185e17548149b5e13d4d583d811e9e9323157fa8c6a527e827739794c7502b59243c58e210b8c3 + languageName: node + linkType: hard + "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -14433,6 +16008,20 @@ __metadata: languageName: node linkType: hard +"mdn-data@npm:2.0.28": + version: 2.0.28 + resolution: "mdn-data@npm:2.0.28" + checksum: f51d587a6ebe8e426c3376c74ea6df3e19ec8241ed8e2466c9c8a3904d5d04397199ea4f15b8d34d14524b5de926d8724ae85207984be47e165817c26e49e0aa + languageName: node + linkType: hard + +"mdn-data@npm:2.0.30": + version: 2.0.30 + resolution: "mdn-data@npm:2.0.30" + checksum: d6ac5ac7439a1607df44b22738ecf83f48e66a0874e4482d6424a61c52da5cde5750f1d1229b6f5fa1b80a492be89465390da685b11f97d62b8adcc6e88189aa + languageName: node + linkType: hard + "mdurl@npm:^1.0.0": version: 1.0.1 resolution: "mdurl@npm:1.0.1" @@ -15520,6 +17109,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: ef55a3d853e1269a6d6279b7692cd6ff3e40bc74947945101138745bfdc9a5edabfe72cb19a31a8e45752e1910c4c65c77d931866af6357f242b172b7283f5b3 + languageName: node + linkType: hard + "nopt@npm:^7.0.0": version: 7.2.0 resolution: "nopt@npm:7.2.0" @@ -16248,6 +17844,13 @@ __metadata: languageName: node linkType: hard +"picocolors@npm:^1.0.1, picocolors@npm:^1.1.0": + version: 1.1.0 + resolution: "picocolors@npm:1.1.0" + checksum: a64d653d3a188119ff45781dfcdaeedd7625583f45280aea33fcb032c7a0d3959f2368f9b192ad5e8aade75b74dbd954ffe3106c158509a45e4c18ab379a2acd + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -16329,17 +17932,43 @@ __metadata: languageName: node linkType: hard +"postcss-calc@npm:^9.0.1": + version: 9.0.1 + resolution: "postcss-calc@npm:9.0.1" + dependencies: + postcss-selector-parser: ^6.0.11 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.2 + checksum: 7327ed83bfec544ab8b3e38353baa72ff6d04378b856db4ad82dbd68ce0b73668867ef182b5d4025f9dd9aa9c64aacc50cd1bd9db8d8b51ccc4cb97866b9d72b + languageName: node + linkType: hard + "postcss-colormin@npm:^5.3.1": version: 5.3.1 resolution: "postcss-colormin@npm:5.3.1" dependencies: - browserslist: ^4.21.4 + browserslist: ^4.21.4 + caniuse-api: ^3.0.0 + colord: ^2.9.1 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: e5778baab30877cd1f51e7dc9d2242a162aeca6360a52956acd7f668c5bc235c2ccb7e4df0370a804d65ebe00c5642366f061db53aa823f9ed99972cebd16024 + languageName: node + linkType: hard + +"postcss-colormin@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-colormin@npm:6.1.0" + dependencies: + browserslist: ^4.23.0 caniuse-api: ^3.0.0 - colord: ^2.9.1 + colord: ^2.9.3 postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: e5778baab30877cd1f51e7dc9d2242a162aeca6360a52956acd7f668c5bc235c2ccb7e4df0370a804d65ebe00c5642366f061db53aa823f9ed99972cebd16024 + postcss: ^8.4.31 + checksum: 55a1525de345d953bc7f32ecaa5ee6275ef0277c27d1f97ff06a1bd1a2fedf7f254e36dc1500621f1df20c25a6d2485a74a0b527d8ff74eb90726c76efe2ac8e languageName: node linkType: hard @@ -16355,6 +17984,18 @@ __metadata: languageName: node linkType: hard +"postcss-convert-values@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-convert-values@npm:6.1.0" + dependencies: + browserslist: ^4.23.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 43e9f66af9bdec3c76695f9dde36885abc01f662c370c490b45d895459caab2c5792f906f3ddad107129133e41485a65634da7f699eef916a636e47f6a37a299 + languageName: node + linkType: hard + "postcss-discard-comments@npm:^5.1.2": version: 5.1.2 resolution: "postcss-discard-comments@npm:5.1.2" @@ -16364,6 +18005,15 @@ __metadata: languageName: node linkType: hard +"postcss-discard-comments@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-discard-comments@npm:6.0.2" + peerDependencies: + postcss: ^8.4.31 + checksum: c1731ccc8d1e3d910412a61395988d3033365e6532d9e5432ad7c74add8c9dcb0af0c03d4e901bf0d2b59ea4e7297a0c77a547ff2ed1b1cc065559cc0de43b4e + languageName: node + linkType: hard + "postcss-discard-duplicates@npm:^5.1.0": version: 5.1.0 resolution: "postcss-discard-duplicates@npm:5.1.0" @@ -16373,6 +18023,15 @@ __metadata: languageName: node linkType: hard +"postcss-discard-duplicates@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-discard-duplicates@npm:6.0.3" + peerDependencies: + postcss: ^8.4.31 + checksum: 308e3fb84c35e4703532de1efa5d6e8444cc5f167d0e40f42d7ea3fa3a37d9d636fd10729847d078e0c303eee16f8548d14b6f88a3fce4e38a2b452648465175 + languageName: node + linkType: hard + "postcss-discard-empty@npm:^5.1.1": version: 5.1.1 resolution: "postcss-discard-empty@npm:5.1.1" @@ -16382,6 +18041,15 @@ __metadata: languageName: node linkType: hard +"postcss-discard-empty@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-discard-empty@npm:6.0.3" + peerDependencies: + postcss: ^8.4.31 + checksum: bad305572faa066026a295faab37e718cee096589ab827b19c990c55620b2b2a1ce9f0145212651737a66086db01b2676c1927bbb8408c5f9cb42686d5959f00 + languageName: node + linkType: hard + "postcss-discard-overridden@npm:^5.1.0": version: 5.1.0 resolution: "postcss-discard-overridden@npm:5.1.0" @@ -16391,6 +18059,15 @@ __metadata: languageName: node linkType: hard +"postcss-discard-overridden@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-discard-overridden@npm:6.0.2" + peerDependencies: + postcss: ^8.4.31 + checksum: a38e0fe7a36f83cb9b73c1ba9ee2a48cf93c69ec0ea5753935824ffb71e958e58ae0393171c0f3d0014a397469d09bbb0d56bb5ab80f0280722967e2e273aebb + languageName: node + linkType: hard + "postcss-discard-unused@npm:^5.1.0": version: 5.1.0 resolution: "postcss-discard-unused@npm:5.1.0" @@ -16402,6 +18079,17 @@ __metadata: languageName: node linkType: hard +"postcss-discard-unused@npm:^6.0.5": + version: 6.0.5 + resolution: "postcss-discard-unused@npm:6.0.5" + dependencies: + postcss-selector-parser: ^6.0.16 + peerDependencies: + postcss: ^8.4.31 + checksum: 7962640773240186de38125f142a6555b7f9b2493c4968e0f0b11c6629b2bf43ac70b9fc4ee78aa732d82670ad8bf802b2febc9a9864b022eb68530eded26836 + languageName: node + linkType: hard + "postcss-loader@npm:^7.0.0, postcss-loader@npm:^7.3.3": version: 7.3.3 resolution: "postcss-loader@npm:7.3.3" @@ -16428,6 +18116,18 @@ __metadata: languageName: node linkType: hard +"postcss-merge-idents@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-merge-idents@npm:6.0.3" + dependencies: + cssnano-utils: ^4.0.2 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: b45780d6d103b8e45a580032747ee6e1842f81863672341a6b4961397e243ca896217bf1f3ee732376a766207d5f610ba8924cf08cf6d5bbd4b093133fd05d70 + languageName: node + linkType: hard + "postcss-merge-longhand@npm:^5.1.7": version: 5.1.7 resolution: "postcss-merge-longhand@npm:5.1.7" @@ -16440,6 +18140,18 @@ __metadata: languageName: node linkType: hard +"postcss-merge-longhand@npm:^6.0.5": + version: 6.0.5 + resolution: "postcss-merge-longhand@npm:6.0.5" + dependencies: + postcss-value-parser: ^4.2.0 + stylehacks: ^6.1.1 + peerDependencies: + postcss: ^8.4.31 + checksum: 9ae5acf47dc0c1f494684ae55672d55bba7f5ee11c9c0f266aabd7c798e9f7394c6096363cd95685fd21ef088740389121a317772cf523ca22c915009bca2617 + languageName: node + linkType: hard + "postcss-merge-rules@npm:^5.1.4": version: 5.1.4 resolution: "postcss-merge-rules@npm:5.1.4" @@ -16454,6 +18166,20 @@ __metadata: languageName: node linkType: hard +"postcss-merge-rules@npm:^6.1.1": + version: 6.1.1 + resolution: "postcss-merge-rules@npm:6.1.1" + dependencies: + browserslist: ^4.23.0 + caniuse-api: ^3.0.0 + cssnano-utils: ^4.0.2 + postcss-selector-parser: ^6.0.16 + peerDependencies: + postcss: ^8.4.31 + checksum: 43f60a1c88806491cf752ae7871676de0e7a2a9d6d2fc6bc894068cc35a910a63d30f7c7d79545e0926c8b3a9ec583e5e8357203c40b5bad5ff58133b0c900f6 + languageName: node + linkType: hard + "postcss-minify-font-values@npm:^5.1.0": version: 5.1.0 resolution: "postcss-minify-font-values@npm:5.1.0" @@ -16465,6 +18191,17 @@ __metadata: languageName: node linkType: hard +"postcss-minify-font-values@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-minify-font-values@npm:6.1.0" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 985e4dd2f89220a4442a822aad7dff016ab58a9dbb7bbca9d01c2d07d5a1e7d8c02e1c6e836abb4c9b4e825b4b80d99ee1f5899e74bf0d969095037738e6e452 + languageName: node + linkType: hard + "postcss-minify-gradients@npm:^5.1.1": version: 5.1.1 resolution: "postcss-minify-gradients@npm:5.1.1" @@ -16478,6 +18215,19 @@ __metadata: languageName: node linkType: hard +"postcss-minify-gradients@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-minify-gradients@npm:6.0.3" + dependencies: + colord: ^2.9.3 + cssnano-utils: ^4.0.2 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 89b95088c3830f829f6d4636d1be4d4f13300bf9f1577c48c25169c81e11ec0026760b9abb32112b95d2c622f09d3b737f4d2975a7842927ccb567e1002ef7b3 + languageName: node + linkType: hard + "postcss-minify-params@npm:^5.1.4": version: 5.1.4 resolution: "postcss-minify-params@npm:5.1.4" @@ -16491,6 +18241,19 @@ __metadata: languageName: node linkType: hard +"postcss-minify-params@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-minify-params@npm:6.1.0" + dependencies: + browserslist: ^4.23.0 + cssnano-utils: ^4.0.2 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 1e1cc3057d9bcc532c70e40628e96e3aea0081d8072dffe983a270a8cd59c03ac585e57d036b70e43d4ee725f274a05a6a8efac5a715f448284e115c13f82a46 + languageName: node + linkType: hard + "postcss-minify-selectors@npm:^5.2.1": version: 5.2.1 resolution: "postcss-minify-selectors@npm:5.2.1" @@ -16502,6 +18265,17 @@ __metadata: languageName: node linkType: hard +"postcss-minify-selectors@npm:^6.0.4": + version: 6.0.4 + resolution: "postcss-minify-selectors@npm:6.0.4" + dependencies: + postcss-selector-parser: ^6.0.16 + peerDependencies: + postcss: ^8.4.31 + checksum: 150221a84422ca7627c67ee691ee51e0fe2c3583c8108801e9fc93d3be8b538c2eb04fcfdc908270d7eeaeaf01594a20b81311690a873efccb8a23aeafe1c354 + languageName: node + linkType: hard + "postcss-modules-extract-imports@npm:^3.0.0": version: 3.0.0 resolution: "postcss-modules-extract-imports@npm:3.0.0" @@ -16555,6 +18329,15 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-charset@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-charset@npm:6.0.2" + peerDependencies: + postcss: ^8.4.31 + checksum: 5b8aeb17d61578a8656571cd5d5eefa8d4ee7126a99a41fdd322078002a06f2ae96f649197b9c01067a5f3e38a2e4b03e0e3fda5a0ec9e3d7ad056211ce86156 + languageName: node + linkType: hard + "postcss-normalize-display-values@npm:^5.1.0": version: 5.1.0 resolution: "postcss-normalize-display-values@npm:5.1.0" @@ -16566,6 +18349,17 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-display-values@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-display-values@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: da30a9394b0e4a269ccad8d240693a6cd564bcc60e24db67caee00f70ddfbc070ad76faed64c32e6eec9ed02e92565488b7879d4fd6c40d877c290eadbb0bb28 + languageName: node + linkType: hard + "postcss-normalize-positions@npm:^5.1.1": version: 5.1.1 resolution: "postcss-normalize-positions@npm:5.1.1" @@ -16577,6 +18371,17 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-positions@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-positions@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 44fb77583fae4d71b76e38226cf770570876bcf5af6940dc9aeac7a7e2252896b361e0249044766cff8dad445f925378f06a005d6541597573c20e599a62b516 + languageName: node + linkType: hard + "postcss-normalize-repeat-style@npm:^5.1.1": version: 5.1.1 resolution: "postcss-normalize-repeat-style@npm:5.1.1" @@ -16588,6 +18393,17 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-repeat-style@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-repeat-style@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: bebdac63bec6777ead3e265fc12527b261cf8d0da1b7f0abb12bda86fd53b7058e4afe392210ac74dac012e413bb1c2a46a1138c89f82b8bf70b81711f620f8c + languageName: node + linkType: hard + "postcss-normalize-string@npm:^5.1.0": version: 5.1.0 resolution: "postcss-normalize-string@npm:5.1.0" @@ -16599,6 +18415,17 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-string@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-string@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 5e8e253c528b542accafc142846fb33643c342a787c86e5b68c6287c7d8f63c5ae7d4d3fc28e3daf80821cc26a91add135e58bdd62ff9c735fca65d994898c7d + languageName: node + linkType: hard + "postcss-normalize-timing-functions@npm:^5.1.0": version: 5.1.0 resolution: "postcss-normalize-timing-functions@npm:5.1.0" @@ -16610,6 +18437,17 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-timing-functions@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-timing-functions@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 1970f5aad04be11f99d51c59e27debb6fd7b49d0fa4a8879062b42c82113f8e520a284448727add3b54de85deefb8bd5fe554f618406586e9ad8fc9d060609f1 + languageName: node + linkType: hard + "postcss-normalize-unicode@npm:^5.1.1": version: 5.1.1 resolution: "postcss-normalize-unicode@npm:5.1.1" @@ -16622,6 +18460,18 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-unicode@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-normalize-unicode@npm:6.1.0" + dependencies: + browserslist: ^4.23.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 69ef35d06242061f0c504c128b83752e0f8daa30ebb26734de7d090460910be0b2efd8b17b1d64c3c85b95831a041faad9ad0aaba80e239406a79cfad3d63568 + languageName: node + linkType: hard + "postcss-normalize-url@npm:^5.1.0": version: 5.1.0 resolution: "postcss-normalize-url@npm:5.1.0" @@ -16634,6 +18484,17 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-url@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-url@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: bef51a18bbfee4fbf0381fec3c91e6c0dace36fca053bbd5f228e653d2732b6df3985525d79c4f7fc89f840ed07eb6d226e9d7503ecdc6f16d6d80cacae9df33 + languageName: node + linkType: hard + "postcss-normalize-whitespace@npm:^5.1.1": version: 5.1.1 resolution: "postcss-normalize-whitespace@npm:5.1.1" @@ -16645,6 +18506,17 @@ __metadata: languageName: node linkType: hard +"postcss-normalize-whitespace@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-whitespace@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 6081eb3a4b305749eec02c00a95c2d236336a77ee636bb1d939f18d5dfa5ba82b7cf7fa072e83f9133d0bc984276596af3fe468bdd67c742ce69e9c63dbc218d + languageName: node + linkType: hard + "postcss-ordered-values@npm:^5.1.3": version: 5.1.3 resolution: "postcss-ordered-values@npm:5.1.3" @@ -16657,6 +18529,18 @@ __metadata: languageName: node linkType: hard +"postcss-ordered-values@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-ordered-values@npm:6.0.2" + dependencies: + cssnano-utils: ^4.0.2 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: c3d96177b4ffa43754e835e30c40043cc75ab1e95eb6c55ac8723eb48c13a12e986250e63d96619bbbd1a098876a1c0c1b3b7a8e1de1108a009cf7aa0beac834 + languageName: node + linkType: hard + "postcss-reduce-idents@npm:^5.2.0": version: 5.2.0 resolution: "postcss-reduce-idents@npm:5.2.0" @@ -16668,6 +18552,17 @@ __metadata: languageName: node linkType: hard +"postcss-reduce-idents@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-reduce-idents@npm:6.0.3" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 1feff316838f947386c908f50807cf1b9589fd09b8e8df633a01f2640af5492833cc892448938ceba10ab96826c44767b8f2e1569d587579423f2db81202f7c7 + languageName: node + linkType: hard + "postcss-reduce-initial@npm:^5.1.2": version: 5.1.2 resolution: "postcss-reduce-initial@npm:5.1.2" @@ -16680,6 +18575,18 @@ __metadata: languageName: node linkType: hard +"postcss-reduce-initial@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-reduce-initial@npm:6.1.0" + dependencies: + browserslist: ^4.23.0 + caniuse-api: ^3.0.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 39e4034ffbf62a041b66944c5cebc4b17f656e76b97568f7f6230b0b886479e5c75b02ae4ba48c472cb0bde47489f9ed1fe6110ae8cff0d7b7165f53c2d64a12 + languageName: node + linkType: hard + "postcss-reduce-transforms@npm:^5.1.0": version: 5.1.0 resolution: "postcss-reduce-transforms@npm:5.1.0" @@ -16691,6 +18598,27 @@ __metadata: languageName: node linkType: hard +"postcss-reduce-transforms@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-reduce-transforms@npm:6.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: c424cc554eb5d253b7687b64925a13fc16759f058795d223854f5a20d9bca641b5f25d0559d03287e63f07a4629c24ac78156adcf604483fcad3c51721da0a08 + languageName: node + linkType: hard + +"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.16": + version: 6.1.2 + resolution: "postcss-selector-parser@npm:6.1.2" + dependencies: + cssesc: ^3.0.0 + util-deprecate: ^1.0.2 + checksum: ce9440fc42a5419d103f4c7c1847cb75488f3ac9cbe81093b408ee9701193a509f664b4d10a2b4d82c694ee7495e022f8f482d254f92b7ffd9ed9dea696c6f84 + languageName: node + linkType: hard + "postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9": version: 6.0.13 resolution: "postcss-selector-parser@npm:6.0.13" @@ -16701,7 +18629,7 @@ __metadata: languageName: node linkType: hard -"postcss-sort-media-queries@npm:^4.2.1, postcss-sort-media-queries@npm:^4.4.1": +"postcss-sort-media-queries@npm:^4.2.1": version: 4.4.1 resolution: "postcss-sort-media-queries@npm:4.4.1" dependencies: @@ -16712,6 +18640,17 @@ __metadata: languageName: node linkType: hard +"postcss-sort-media-queries@npm:^5.2.0": + version: 5.2.0 + resolution: "postcss-sort-media-queries@npm:5.2.0" + dependencies: + sort-css-media-queries: 2.2.0 + peerDependencies: + postcss: ^8.4.23 + checksum: d4a976a64b53234762cc35c06ce97c1684bd7a64ead17e84c2047676c7307945be7c005235e6aac7c4620e1f835d6ba1a7dcf018ab7fe0a47657c62c96ad9f35 + languageName: node + linkType: hard + "postcss-svgo@npm:^5.1.0": version: 5.1.0 resolution: "postcss-svgo@npm:5.1.0" @@ -16724,6 +18663,18 @@ __metadata: languageName: node linkType: hard +"postcss-svgo@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-svgo@npm:6.0.3" + dependencies: + postcss-value-parser: ^4.2.0 + svgo: ^3.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 1a7d1c8dea555884a7791e28ec2c22ea92331731067584ff5a23042a0e615f88fefde04e1140f11c262a728ef9fab6851423b40b9c47f9ae05353bd3c0ff051a + languageName: node + linkType: hard + "postcss-unique-selectors@npm:^5.1.1": version: 5.1.1 resolution: "postcss-unique-selectors@npm:5.1.1" @@ -16735,6 +18686,17 @@ __metadata: languageName: node linkType: hard +"postcss-unique-selectors@npm:^6.0.4": + version: 6.0.4 + resolution: "postcss-unique-selectors@npm:6.0.4" + dependencies: + postcss-selector-parser: ^6.0.16 + peerDependencies: + postcss: ^8.4.31 + checksum: b09df9943b4e858e88b30f3d279ce867a0490df806f1f947d286b0a4e95ba923f1229c385e5bf365f4f124f1edccda41ec18ccad4ba8798d829279d6dc971203 + languageName: node + linkType: hard + "postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": version: 4.2.0 resolution: "postcss-value-parser@npm:4.2.0" @@ -16751,6 +18713,15 @@ __metadata: languageName: node linkType: hard +"postcss-zindex@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-zindex@npm:6.0.2" + peerDependencies: + postcss: ^8.4.31 + checksum: 394119e47b0fb098dc53d1bcf71b5500ab29605fe106526b2e81290bff179174ee00a82a4d4be5a42d4ef4138e8a3d6aabeef3b06cf7cb15b851848c8585d53b + languageName: node + linkType: hard + "postcss@npm:^8.4.14, postcss@npm:^8.4.17, postcss@npm:^8.4.21, postcss@npm:^8.4.26": version: 8.4.32 resolution: "postcss@npm:8.4.32" @@ -16762,6 +18733,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.24, postcss@npm:^8.4.38": + version: 8.4.47 + resolution: "postcss@npm:8.4.47" + dependencies: + nanoid: ^3.3.7 + picocolors: ^1.1.0 + source-map-js: ^1.2.1 + checksum: f78440a9d8f97431dd2ab1ab8e1de64f12f3eff38a3d8d4a33919b96c381046a314658d2de213a5fa5eb296b656de76a3ec269fdea27f16d5ab465b916a0f52c + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -17249,6 +19231,17 @@ __metadata: languageName: node linkType: hard +"react-loadable@npm:@docusaurus/react-loadable@6.0.0": + version: 6.0.0 + resolution: "@docusaurus/react-loadable@npm:6.0.0" + dependencies: + "@types/react": "*" + peerDependencies: + react: "*" + checksum: 4c32061b2fc10689d5d8ba11ead71b69e4c8a55fcfeafb551a6747b1a7b496c4f2d8dbb5d023f5cafc2a9aea9d14582bdb324d11e6f9b8c3049d45b74439203f + languageName: node + linkType: hard + "react-router-config@npm:^5.1.1": version: 5.1.1 resolution: "react-router-config@npm:5.1.1" @@ -18158,7 +20151,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0": +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.0.1, schema-utils@npm:^4.2.0": version: 4.2.0 resolution: "schema-utils@npm:4.2.0" dependencies: @@ -18630,6 +20623,16 @@ __metadata: languageName: node linkType: hard +"snake-case@npm:^3.0.4": + version: 3.0.4 + resolution: "snake-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: 0a7a79900bbb36f8aaa922cf111702a3647ac6165736d5dc96d3ef367efc50465cac70c53cd172c382b022dac72ec91710608e5393de71f76d7142e6fd80e8a3 + languageName: node + linkType: hard + "sockjs@npm:^0.3.24": version: 0.3.24 resolution: "sockjs@npm:0.3.24" @@ -18686,6 +20689,20 @@ __metadata: languageName: node linkType: hard +"sort-css-media-queries@npm:2.2.0": + version: 2.2.0 + resolution: "sort-css-media-queries@npm:2.2.0" + checksum: c090c9a27be40f3e50f5f9bc9d85a8af0e2c5152565eca34bdb028d952749bce169bc5abef21a5a385ca6221a0869640c9faf58f082ac46de9085ebdb506291f + languageName: node + linkType: hard + +"source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 4eb0cd997cdf228bc253bcaff9340afeb706176e64868ecd20efbe6efea931465f43955612346d6b7318789e5265bdc419bc7669c1cebe3db0eb255f57efa76b + languageName: node + linkType: hard + "source-map-js@npm:^1.0.2": version: 1.0.2 resolution: "source-map-js@npm:1.0.2" @@ -19055,6 +21072,18 @@ __metadata: languageName: node linkType: hard +"stylehacks@npm:^6.1.1": + version: 6.1.1 + resolution: "stylehacks@npm:6.1.1" + dependencies: + browserslist: ^4.23.0 + postcss-selector-parser: ^6.0.16 + peerDependencies: + postcss: ^8.4.31 + checksum: 7bef69822280a23817caa43969de76d77ba34042e9f1f7baaeda8f22b1d8c20f1f839ad028552c169e158e387830f176feccd0324b07ef6ec657cba1dd0b2466 + languageName: node + linkType: hard + "superstruct@npm:^1.0.3": version: 1.0.3 resolution: "superstruct@npm:1.0.3" @@ -19120,6 +21149,23 @@ __metadata: languageName: node linkType: hard +"svgo@npm:^3.0.2, svgo@npm:^3.2.0": + version: 3.3.2 + resolution: "svgo@npm:3.3.2" + dependencies: + "@trysound/sax": 0.2.0 + commander: ^7.2.0 + css-select: ^5.1.0 + css-tree: ^2.3.1 + css-what: ^6.1.0 + csso: ^5.0.5 + picocolors: ^1.0.0 + bin: + svgo: ./bin/svgo + checksum: a3f8aad597dec13ab24e679c4c218147048dc1414fe04e99447c5f42a6e077b33d712d306df84674b5253b98c9b84dfbfb41fdd08552443b04946e43d03e054e + languageName: node + linkType: hard + "synckit@npm:^0.8.6": version: 0.8.8 resolution: "synckit@npm:0.8.8" @@ -20138,6 +22184,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.1.0": + version: 1.1.1 + resolution: "update-browserslist-db@npm:1.1.1" + dependencies: + escalade: ^3.2.0 + picocolors: ^1.1.0 + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 2ea11bd2562122162c3e438d83a1f9125238c0844b6d16d366e3276d0c0acac6036822dc7df65fc5a89c699cdf9f174acf439c39bedf3f9a2f3983976e4b4c3e + languageName: node + linkType: hard + "update-check@npm:1.5.4": version: 1.5.4 resolution: "update-check@npm:1.5.4" diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index ccecdbd1b24..e7696e83232 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -3379,7 +3379,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/noir_codegen@portal:../noir/packages/noir_codegen::locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: - "@noir-lang/types": 0.35.0 + "@noir-lang/types": 0.36.0 glob: ^10.3.10 ts-command-line-args: ^2.5.1 bin: @@ -3388,13 +3388,13 @@ __metadata: linkType: soft "@noir-lang/noir_js@file:../noir/packages/noir_js::locator=%40aztec%2Faztec3-packages%40workspace%3A.": - version: 0.35.0 - resolution: "@noir-lang/noir_js@file:../noir/packages/noir_js#../noir/packages/noir_js::hash=518513&locator=%40aztec%2Faztec3-packages%40workspace%3A." + version: 0.36.0 + resolution: "@noir-lang/noir_js@file:../noir/packages/noir_js#../noir/packages/noir_js::hash=b897b0&locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: - "@noir-lang/acvm_js": 0.51.0 - "@noir-lang/noirc_abi": 0.35.0 - "@noir-lang/types": 0.35.0 - checksum: 785c9cabed8bc7d13231f1437cd667f07746380bed88b9e75091bb35df6913b50aae86dad054e7a1bf83fdfc5689b3c9b7aed1a44172de5056a81b24527caf41 + "@noir-lang/acvm_js": 0.52.0 + "@noir-lang/noirc_abi": 0.36.0 + "@noir-lang/types": 0.36.0 + checksum: 80eab489930f98827554644d8031a4b884042e24a0786bea001cd8ad4aca7b15b95bc97efa00dcd2301f7efd10dcc35ce8cb9dce0c4e492127701dbafaca34db languageName: node linkType: hard @@ -3402,7 +3402,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/noirc_abi@portal:../noir/packages/noirc_abi::locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: - "@noir-lang/types": 0.35.0 + "@noir-lang/types": 0.36.0 languageName: node linkType: soft