├── .cargo-husky └── hooks │ └── pre-commit ├── .cargo └── config.toml ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .vscode └── settings.json ├── Cargo.lock ├── Cargo.toml ├── Makefile ├── README.md ├── benchmarks ├── dazefield_element_mul.json ├── fast_ntt.json ├── project_euler_1.json ├── project_euler_2.json ├── project_euler_3_i600851.json ├── project_euler_4_i10_to_50.json ├── project_euler_5.json ├── project_euler_6.json ├── project_euler_7_i101.json ├── recufier_merkle_root.json ├── simple_map_on_bfe.json └── verify_authentication_path.json ├── profiles ├── dazefield_element_mul.profile ├── fast_ntt.profile ├── project_euler_1.profile ├── project_euler_2.profile ├── project_euler_3_i600851.profile ├── project_euler_4_i10_to_50.profile ├── project_euler_5.profile ├── project_euler_6.profile ├── project_euler_7_i101.profile ├── recufier_merkle_root.profile ├── verify_stark_proof_inner_padded_height_1024_0_input_words.profile └── verify_stark_proof_inner_padded_height_256_0_input_words.profile ├── src ├── ast.rs ├── ast_types.rs ├── ast_types │ ├── abstract_argument.rs │ ├── array_type.rs │ ├── custom_type_oil.rs │ ├── enum_type.rs │ ├── field_id.rs │ ├── function_type.rs │ ├── struct_type.rs │ └── tuple.rs ├── composite_types.rs ├── custom_type_resolver.rs ├── graft.rs ├── lib.rs ├── libraries.rs ├── libraries │ ├── bfe.rs │ ├── bfield_codec.rs │ ├── boxed.rs │ ├── core.rs │ ├── core │ │ ├── array.rs │ │ ├── option_type.rs │ │ └── result_type.rs │ ├── hasher.rs │ ├── polynomial.rs │ ├── recufy.rs │ ├── recufy │ │ └── vm_proof_iter.rs │ ├── tasm.rs │ ├── unsigned_integers.rs │ ├── vector.rs │ └── xfe.rs ├── main.rs ├── ssa.rs ├── subroutine.rs ├── tasm_code_generator.rs ├── tasm_code_generator │ ├── data_type.rs │ ├── data_type │ │ ├── array_type.rs │ │ ├── enum_type.rs │ │ ├── struct_type.rs │ │ └── tuple_type.rs │ ├── function_state.rs │ ├── inner_function_tasm_code.rs │ ├── match_code.rs │ ├── outer_function_tasm_code.rs │ └── stack.rs ├── tests_and_benchmarks.rs ├── tests_and_benchmarks │ ├── benchmarks.rs │ ├── benchmarks │ │ └── mmr.rs │ ├── ozk.rs │ ├── ozk │ │ ├── ozk_parsing.rs │ │ ├── programs.rs │ │ ├── programs │ │ │ ├── algebraic_hasher.rs │ │ │ ├── algebraic_hasher │ │ │ │ ├── hash_atomic_values.rs │ │ │ │ ├── hash_boxed_fields.rs │ │ │ │ ├── hash_boxed_values.rs │ │ │ │ └── sample_scalars.rs │ │ │ ├── arithmetic.rs │ │ │ ├── arithmetic │ │ │ │ ├── bfe_add.rs │ │ │ │ ├── bfe_inverse.rs │ │ │ │ ├── dazefield_element_mul.rs │ │ │ │ ├── ilog2_u32.rs │ │ │ │ ├── mod_pow_u32.rs │ │ │ │ ├── montyred.rs │ │ │ │ ├── wrapping_sub.rs │ │ │ │ ├── xfe_bfe.rs │ │ │ │ ├── xfe_inverse.rs │ │ │ │ └── xfe_mod_pow_u32.rs │ │ │ ├── arrays.rs │ │ │ ├── arrays │ │ │ │ ├── array_in_struct.rs │ │ │ │ ├── array_to_vec.rs │ │ │ │ ├── bfe_array.rs │ │ │ │ ├── bfe_array_boxed.rs │ │ │ │ ├── repeat_syntax.rs │ │ │ │ ├── vec_to_array.rs │ │ │ │ └── xfe_array.rs │ │ │ ├── boxed.rs │ │ │ ├── boxed │ │ │ │ ├── bfe.rs │ │ │ │ ├── bfe_pair.rs │ │ │ │ ├── box_a_list_simple.rs │ │ │ │ ├── box_a_struct_with_list_field_simple.rs │ │ │ │ ├── box_a_struct_with_two_list_fields.rs │ │ │ │ ├── box_an_array_simple.rs │ │ │ │ ├── box_complex_flat_struct.rs │ │ │ │ ├── digest_pair.rs │ │ │ │ ├── enum_to_memory_simple.rs │ │ │ │ ├── flat_tuples.rs │ │ │ │ ├── method_on_nested_struct_simple.rs │ │ │ │ ├── methods_on_boxed_tuple_structs.rs │ │ │ │ ├── methods_on_nested_structs_not_copy.rs │ │ │ │ ├── nested_tuples.rs │ │ │ │ ├── ref_struct_typecheck_fail.rs │ │ │ │ ├── ref_struct_typecheck_succeed_bc_boxed.rs │ │ │ │ ├── simple_struct_copy.rs │ │ │ │ ├── tuple_struct_one_element.rs │ │ │ │ ├── tuple_struct_one_element_simple.rs │ │ │ │ ├── tuple_struct_two_elements_copy.rs │ │ │ │ ├── tuple_struct_two_elements_not_copy.rs │ │ │ │ └── tuple_struct_with_vec.rs │ │ │ ├── composite_types.rs │ │ │ ├── composite_types │ │ │ │ ├── composite_types_from_associated_functions.rs │ │ │ │ └── composite_types_from_methods.rs │ │ │ ├── destructuring.rs │ │ │ ├── destructuring │ │ │ │ └── digest.rs │ │ │ ├── enums.rs │ │ │ ├── enums │ │ │ │ ├── box_enum_dyn_sized_variant_field.rs │ │ │ │ ├── box_enum_simple.rs │ │ │ │ ├── box_enum_two_dyn_sized_variant_fields.rs │ │ │ │ ├── boxed_advanced_tuple_data.rs │ │ │ │ ├── boxed_match_with_wildcard_binding.rs │ │ │ │ ├── boxed_multiple_tuple_data.rs │ │ │ │ ├── boxed_multiple_tuple_data_to_stack.rs │ │ │ │ ├── boxed_proof_item_simple.rs │ │ │ │ ├── custom_struct_in_data.rs │ │ │ │ ├── enum_with_non_copy_struct_data.rs │ │ │ │ ├── enum_with_struct_data.rs │ │ │ │ ├── enum_with_struct_with_two_vecs.rs │ │ │ │ ├── match_with_wildcard_bindings.rs │ │ │ │ ├── move_boxed_enum_to_stack.rs │ │ │ │ ├── rust_by_example_enums.rs │ │ │ │ ├── two_variants_no_data.rs │ │ │ │ └── two_variants_one_data.rs │ │ │ ├── match_expr_boxed.rs │ │ │ ├── match_expr_boxed │ │ │ │ ├── simple_enum_type.rs │ │ │ │ ├── very_simple.rs │ │ │ │ └── with_catch_all.rs │ │ │ ├── match_expr_on_stack.rs │ │ │ ├── match_expr_on_stack │ │ │ │ ├── catch_all_condition.rs │ │ │ │ ├── option_type.rs │ │ │ │ ├── panic_in_arm_body.rs │ │ │ │ ├── three_variants.rs │ │ │ │ └── three_variants_type.rs │ │ │ ├── match_stmt_boxed.rs │ │ │ ├── match_stmt_boxed │ │ │ │ └── set_array_value_from_memory.rs │ │ │ ├── neptune_consensus.rs │ │ │ ├── neptune_consensus │ │ │ │ ├── claims.rs │ │ │ │ ├── claims │ │ │ │ │ └── single_proof_claims.rs │ │ │ │ ├── single_proof.rs │ │ │ │ └── typescript_timelock.rs │ │ │ ├── option_types.rs │ │ │ ├── option_types │ │ │ │ ├── is_some_is_none_unwrap.rs │ │ │ │ └── mutable_values.rs │ │ │ ├── other.rs │ │ │ ├── other │ │ │ │ ├── hash_varlen.rs │ │ │ │ ├── import_type_declaration.rs │ │ │ │ ├── nested_tuples.rs │ │ │ │ ├── returning_block_expr_u32.rs │ │ │ │ ├── simple_encode.rs │ │ │ │ ├── simple_map_on_bfe.rs │ │ │ │ ├── simple_struct.rs │ │ │ │ └── value.rs │ │ │ ├── project_euler.rs │ │ │ ├── project_euler │ │ │ │ ├── pe1.rs │ │ │ │ ├── pe2.rs │ │ │ │ ├── pe3.rs │ │ │ │ ├── pe4.rs │ │ │ │ ├── pe5.rs │ │ │ │ ├── pe6.rs │ │ │ │ └── pe7.rs │ │ │ ├── recufier.rs │ │ │ ├── recufier │ │ │ │ ├── arithmetic_domain.rs │ │ │ │ ├── challenges.rs │ │ │ │ ├── eval_arg.rs │ │ │ │ ├── fast_ntt.rs │ │ │ │ ├── fast_ntt_to_basic_snippet.rs │ │ │ │ ├── fri_verify.rs │ │ │ │ ├── merkle_root.rs │ │ │ │ ├── merkle_root_autogen.rs │ │ │ │ ├── stark_parameters.rs │ │ │ │ ├── verify.rs │ │ │ │ ├── vm_proof_iter_next_as.rs │ │ │ │ └── xfe_ntt_recursive.rs │ │ │ ├── result_types.rs │ │ │ ├── result_types │ │ │ │ ├── copy_types.rs │ │ │ │ ├── non_copy_types.rs │ │ │ │ ├── prelude_match.rs │ │ │ │ ├── question_mark_operator.rs │ │ │ │ ├── simple_unwrap.rs │ │ │ │ └── unwrap_crash.rs │ │ │ ├── sponge_hasher.rs │ │ │ ├── sponge_hasher │ │ │ │ ├── absorb_once_squeeze_once.rs │ │ │ │ ├── init.rs │ │ │ │ └── pad_and_absorb_all.rs │ │ │ ├── structs.rs │ │ │ ├── structs │ │ │ │ ├── declaration_on_stack_with_list.rs │ │ │ │ ├── exceed_allowed_field_size.rs │ │ │ │ ├── nested_structs.rs │ │ │ │ ├── simple_declaration_on_stack.rs │ │ │ │ ├── simple_declaration_on_stack_spilled.rs │ │ │ │ ├── simple_nested_struct.rs │ │ │ │ ├── simple_struct.rs │ │ │ │ ├── struct_with_array.rs │ │ │ │ ├── struct_with_methods.rs │ │ │ │ ├── struct_with_simple_methods.rs │ │ │ │ ├── struct_with_two_vecs_to_stack.rs │ │ │ │ ├── struct_with_vecs.rs │ │ │ │ └── struct_with_xfe_and_xfes_to_stack.rs │ │ │ ├── type_forcing.rs │ │ │ ├── type_forcing │ │ │ │ ├── bfield_element.rs │ │ │ │ ├── nested_struct.rs │ │ │ │ └── simple_struct.rs │ │ │ ├── vectors.rs │ │ │ └── vectors │ │ │ │ ├── clone_from_many.rs │ │ │ │ ├── clone_from_simple.rs │ │ │ │ ├── clone_from_very_simple.rs │ │ │ │ └── split_off.rs │ │ └── rust_shadows.rs │ ├── programs.rs │ ├── programs │ │ ├── arithmetic.rs │ │ ├── arithmetic │ │ │ ├── bfe.rs │ │ │ ├── bool.rs │ │ │ ├── mixed.rs │ │ │ ├── u128.rs │ │ │ ├── u32.rs │ │ │ ├── u64.rs │ │ │ └── xfe.rs │ │ ├── bfield_codec.rs │ │ ├── hashing.rs │ │ ├── io.rs │ │ ├── local_functions.rs │ │ ├── mmr.rs │ │ ├── other.rs │ │ ├── spill_to_memory.rs │ │ ├── vectors.rs │ │ └── vectors │ │ │ ├── basic.rs │ │ │ └── map.rs │ ├── test_helpers.rs │ └── test_helpers │ │ └── shared_test.rs └── type_checker.rs └── test_program.rs /.cargo-husky/hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This hook was defined by sword-smith 4 | # It's intended to be copied to `.git/hooks/` by `cargo-husky`. 5 | 6 | set -e 7 | 8 | echo '+cargo clippy --all-targets -- -D warnings' 9 | cargo clippy --all-targets -- -D warnings 10 | echo '+cargo fmt --all -- --check' 11 | cargo fmt --all -- --check 12 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # workaround for rustc 1.80 running out of stack space when building triton-vm 2 | [env] 3 | RUST_MIN_STACK = "33554432" 4 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request: 6 | branches: 7 | - master 8 | 9 | name: Rust 10 | 11 | jobs: 12 | runner-matrix: 13 | name: format, lint, test 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | os: [ubuntu-latest, windows-latest, macos-latest] 18 | runs-on: ${{ matrix.os }} 19 | steps: 20 | - name: Checkout sources 21 | uses: actions/checkout@v3 22 | 23 | - name: Install stable toolchain 24 | uses: actions-rs/toolchain@v1 25 | with: 26 | profile: minimal 27 | toolchain: stable 28 | override: true 29 | components: rustfmt, clippy 30 | 31 | - name: Run cargo fmt 32 | uses: actions-rs/cargo@v1 33 | with: 34 | command: fmt 35 | args: --all -- --check 36 | 37 | - name: Run cargo clippy 38 | uses: actions-rs/cargo@v1 39 | with: 40 | command: clippy 41 | args: -- -D warnings 42 | 43 | - name: Run cargo test without benches 44 | uses: actions-rs/cargo@v1 45 | with: 46 | command: test 47 | args: -- --skip benches 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | 3 | ### JetBrains IDEs ### 4 | **/.idea/** 5 | 6 | # Directory specified in Makefile 7 | /makefile-target 8 | 9 | # Files for Triton-VM debugger 10 | program.tasm 11 | vm_state.json 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.showUnlinkedFileNotification": false 3 | } -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tasm-lang" 3 | version = "0.0.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | anyhow = "1" 8 | chrono = "^0.4.38" 9 | clap = "4.5" 10 | inflections = "1.1" 11 | itertools = "0.14" 12 | num = "0.4" 13 | quote = "1.0" 14 | rand = "0.9.0" 15 | regex = "1.10" 16 | strum = { version = "0.27", features = ["derive"] } 17 | syn = { version = "1.0", features = ["full", "extra-traits"] } 18 | tasm-lib = "0.48.0" 19 | 20 | [dev-dependencies] 21 | anyhow = "1" 22 | arbitrary = { version = "1", features = ["derive"] } 23 | proptest = "1.5" 24 | proptest-arbitrary-interop = "0.1" 25 | reqwest = { version = "0.12", features = ["blocking"] } 26 | serde = { version = "1", features = ["derive"] } 27 | serde_derive = "1" 28 | serde_json = "1" 29 | test-strategy = "0.4" 30 | 31 | [dev-dependencies.cargo-husky] 32 | version = "1" 33 | default-features = false 34 | features = ["user-hooks"] 35 | 36 | [lints.clippy] 37 | used_underscore_binding = "warn" 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | prog :=tasm-lang 3 | 4 | # Treat all warnings as errors 5 | export RUSTFLAGS = -Dwarnings 6 | 7 | # Set another target dir than default to avoid builds from `make` 8 | # to invalidate cache from barebones use of `cargo` commands. 9 | # The cache is cleared when a new `RUSTFLAGS` value is encountered, 10 | # so to prevent the two builds from interfering, we use two dirs. 11 | export CARGO_TARGET_DIR=./makefile-target 12 | 13 | all: lint format build test bench-no-run 14 | 15 | build: 16 | cargo build 17 | rustup check 18 | @echo "Update with \`rustup install stable\` if needed." 19 | 20 | doc: 21 | cargo doc --no-deps 22 | xdg-open "target/doc/twenty_first/index.html" 23 | 24 | check: 25 | cargo check 26 | 27 | ctags: 28 | # Do `cargo install rusty-tags` 29 | # See https://github.com/dan-t/rusty-tags 30 | rusty-tags vi 31 | 32 | format: 33 | cargo fmt --all -- --check 34 | 35 | install: 36 | cp target/$(target)/$(prog) ~/bin/$(prog)$(extension) 37 | 38 | lint: 39 | cargo clippy --all-targets -- -D warnings 40 | 41 | # Get a stack trace upon kernel panic (may slow down implementation) 42 | test: export RUST_BACKTRACE = 1 43 | test: 44 | cargo test 45 | 46 | fast-tests: 47 | RUSTFLAGS="-C opt-level=3 -C debug-assertions=no" cargo t 48 | 49 | bench: 50 | cargo bench 51 | 52 | bench-no-run: 53 | cargo bench --no-run 54 | 55 | # Run prove/verify on `verify_factorial_program`. Meant to measure recursive proof generation. 56 | prove-recursive: 57 | RUSTFLAGS="-C opt-level=3 -C debug-assertions=no" DYING_TO_PROVE=1 PROFILE_AS_YOU_GO=1 cargo t recursive_proof_verification -- --test-threads=1 --nocapture --ignored 58 | 59 | help: 60 | @echo "usage: make [debug=1]" 61 | 62 | clean: 63 | @echo " ._. ██  ██  ███  ██ ██ █████ ████ ██ █████  ███  ██  ██" 64 | @echo " c/-| ███  ███ ██ ██ ████  ██    ██    ██ ██    ██ ██ ███ ██" 65 | @echo " c/--| ████████ █████ ███   ███  ██  ██ ███  █████ ██████" 66 | @echo " / /| ██ ██ ██ ██ ██ ████  ██   ██  ██ ██   ██ ██ ██ ███" 67 | @echo " mmm ' ' ██    ██ ██ ██ ██ ██ █████  ████ █████ █████ ██ ██ ██  ██" 68 | @rm -rf target 69 | -------------------------------------------------------------------------------- /benchmarks/dazefield_element_mul.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "dazefield_element_mul", 4 | "benchmark_result": { 5 | "clock_cycle_count": 1915, 6 | "hash_table_height": 504, 7 | "u32_table_height": 559, 8 | "op_stack_table_height": 1386, 9 | "ram_table_height": 20 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "dazefield_element_mul", 15 | "benchmark_result": { 16 | "clock_cycle_count": 1915, 17 | "hash_table_height": 504, 18 | "u32_table_height": 939, 19 | "op_stack_table_height": 1386, 20 | "ram_table_height": 20 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/fast_ntt.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "fast_ntt", 4 | "benchmark_result": { 5 | "clock_cycle_count": 64639, 6 | "hash_table_height": 642, 7 | "u32_table_height": 2575, 8 | "op_stack_table_height": 57234, 9 | "ram_table_height": 4069 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "fast_ntt", 15 | "benchmark_result": { 16 | "clock_cycle_count": 149515, 17 | "hash_table_height": 642, 18 | "u32_table_height": 5358, 19 | "op_stack_table_height": 132610, 20 | "ram_table_height": 9451 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/project_euler_1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "project_euler_1", 4 | "benchmark_result": { 5 | "clock_cycle_count": 54961, 6 | "hash_table_height": 72, 7 | "u32_table_height": 48359, 8 | "op_stack_table_height": 39570, 9 | "ram_table_height": 0 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "project_euler_1", 15 | "benchmark_result": { 16 | "clock_cycle_count": 54961, 17 | "hash_table_height": 72, 18 | "u32_table_height": 48359, 19 | "op_stack_table_height": 39570, 20 | "ram_table_height": 0 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/project_euler_2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "project_euler_2", 4 | "benchmark_result": { 5 | "clock_cycle_count": 1498, 6 | "hash_table_height": 66, 7 | "u32_table_height": 1732, 8 | "op_stack_table_height": 1108, 9 | "ram_table_height": 0 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "project_euler_2", 15 | "benchmark_result": { 16 | "clock_cycle_count": 1498, 17 | "hash_table_height": 66, 18 | "u32_table_height": 1732, 19 | "op_stack_table_height": 1108, 20 | "ram_table_height": 0 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/project_euler_3_i600851.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "project_euler_3_i600851", 4 | "benchmark_result": { 5 | "clock_cycle_count": 47482, 6 | "hash_table_height": 642, 7 | "u32_table_height": 15918, 8 | "op_stack_table_height": 34540, 9 | "ram_table_height": 1728 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "project_euler_3_i600851", 15 | "benchmark_result": { 16 | "clock_cycle_count": 47482, 17 | "hash_table_height": 642, 18 | "u32_table_height": 15918, 19 | "op_stack_table_height": 34540, 20 | "ram_table_height": 1728 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/project_euler_4_i10_to_50.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "project_euler_4_i10_to_50", 4 | "benchmark_result": { 5 | "clock_cycle_count": 304384, 6 | "hash_table_height": 270, 7 | "u32_table_height": 24612, 8 | "op_stack_table_height": 229374, 9 | "ram_table_height": 12093 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "project_euler_4_i10_to_50", 15 | "benchmark_result": { 16 | "clock_cycle_count": 304384, 17 | "hash_table_height": 270, 18 | "u32_table_height": 24612, 19 | "op_stack_table_height": 229374, 20 | "ram_table_height": 12093 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/project_euler_5.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "project_euler_5", 4 | "benchmark_result": { 5 | "clock_cycle_count": 262, 6 | "hash_table_height": 84, 7 | "u32_table_height": 183, 8 | "op_stack_table_height": 192, 9 | "ram_table_height": 0 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "project_euler_5", 15 | "benchmark_result": { 16 | "clock_cycle_count": 262, 17 | "hash_table_height": 84, 18 | "u32_table_height": 183, 19 | "op_stack_table_height": 192, 20 | "ram_table_height": 0 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/project_euler_6.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "project_euler_6", 4 | "benchmark_result": { 5 | "clock_cycle_count": 257, 6 | "hash_table_height": 114, 7 | "u32_table_height": 277, 8 | "op_stack_table_height": 186, 9 | "ram_table_height": 0 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "project_euler_6", 15 | "benchmark_result": { 16 | "clock_cycle_count": 257, 17 | "hash_table_height": 114, 18 | "u32_table_height": 277, 19 | "op_stack_table_height": 186, 20 | "ram_table_height": 0 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/project_euler_7_i101.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "project_euler_7_i101", 4 | "benchmark_result": { 5 | "clock_cycle_count": 69253, 6 | "hash_table_height": 198, 7 | "u32_table_height": 34007, 8 | "op_stack_table_height": 54754, 9 | "ram_table_height": 2921 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "project_euler_7_i101", 15 | "benchmark_result": { 16 | "clock_cycle_count": 1141429, 17 | "hash_table_height": 198, 18 | "u32_table_height": 578643, 19 | "op_stack_table_height": 911824, 20 | "ram_table_height": 47150 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/recufier_merkle_root.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "recufier_merkle_root", 4 | "benchmark_result": { 5 | "clock_cycle_count": 2332, 6 | "hash_table_height": 228, 7 | "u32_table_height": 603, 8 | "op_stack_table_height": 1832, 9 | "ram_table_height": 81 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "recufier_merkle_root", 15 | "benchmark_result": { 16 | "clock_cycle_count": 38572, 17 | "hash_table_height": 1668, 18 | "u32_table_height": 10305, 19 | "op_stack_table_height": 30152, 20 | "ram_table_height": 1281 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/simple_map_on_bfe.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "simple_map_on_bfe", 4 | "benchmark_result": { 5 | "clock_cycle_count": 616, 6 | "hash_table_height": 174, 7 | "u32_table_height": 265, 8 | "op_stack_table_height": 434, 9 | "ram_table_height": 39 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "simple_map_on_bfe", 15 | "benchmark_result": { 16 | "clock_cycle_count": 10021, 17 | "hash_table_height": 174, 18 | "u32_table_height": 4753, 19 | "op_stack_table_height": 7084, 20 | "ram_table_height": 609 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /benchmarks/verify_authentication_path.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "verify_authentication_path", 4 | "benchmark_result": { 5 | "clock_cycle_count": 10648, 6 | "hash_table_height": 1032, 7 | "u32_table_height": 4133, 8 | "op_stack_table_height": 8338, 9 | "ram_table_height": 568 10 | }, 11 | "case": "CommonCase" 12 | }, 13 | { 14 | "name": "verify_authentication_path", 15 | "benchmark_result": { 16 | "clock_cycle_count": 203741, 17 | "hash_table_height": 1146, 18 | "u32_table_height": 29182, 19 | "op_stack_table_height": 138944, 20 | "ram_table_height": 4064 21 | }, 22 | "case": "WorstCase" 23 | } 24 | ] -------------------------------------------------------------------------------- /profiles/project_euler_1.profile: -------------------------------------------------------------------------------- 1 | project_euler_1: 2 | | Subroutine | Processor | Op Stack | RAM | Hash | U32 | 3 | |:--------------------------------------------|---------------------:|---------------------:|---------------------:|---------------------:|---------------------:| 4 | | main | 54960 (100.0%) | 39570 (100.0%) | 0 ( NaN%) | 0 ( 0.0%) | 48359 (100.0%) | 5 | | ··_binop_Lt__LboolR_bool_4_while_loop | 54951 (100.0%) | 39564 (100.0%) | 0 ( NaN%) | 0 ( 0.0%) | 48359 (100.0%) | 6 | | ····_binop_Or__LboolR_bool_15_else | 1066 ( 1.9%) | 0 ( 0.0%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 7 | | ····tasmlib_arithmetic_u32_safe_add | 8991 ( 16.4%) | 6993 ( 17.7%) | 0 ( NaN%) | 0 ( 0.0%) | 9719 ( 20.1%) | 8 | | ····_binop_Or__LboolR_bool_15_then | 7922 ( 14.4%) | 5592 ( 14.1%) | 0 ( NaN%) | 0 ( 0.0%) | 7678 ( 15.9%) | 9 | | ······tasmlib_arithmetic_u32_safe_add | 4194 ( 7.6%) | 3262 ( 8.2%) | 0 ( NaN%) | 0 ( 0.0%) | 7678 ( 15.9%) | 10 | | ··tasmlib_io_write_to_stdout___u32 | 3 ( 0.0%) | 1 ( 0.0%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 11 | | Total | 54961 (100.0%) | 39570 (100.0%) | 0 ( NaN%) | 72 (100.0%) | 48359 (100.0%) | 12 | -------------------------------------------------------------------------------- /profiles/project_euler_2.profile: -------------------------------------------------------------------------------- 1 | project_euler_2: 2 | | Subroutine | Processor | Op Stack | RAM | Hash | U32 | 3 | |:--------------------------------------------|---------------------:|---------------------:|---------------------:|---------------------:|---------------------:| 4 | | main | 1497 ( 99.9%) | 1108 (100.0%) | 0 ( NaN%) | 0 ( 0.0%) | 1732 (100.0%) | 5 | | ··_unaryop_not__LboolR_bool_6_while_loop | 1487 ( 99.3%) | 1100 ( 99.3%) | 0 ( NaN%) | 0 ( 0.0%) | 1732 (100.0%) | 6 | | ····_binop_Eq__LboolR_bool_11_else | 42 ( 2.8%) | 0 ( 0.0%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 7 | | ····tasmlib_arithmetic_u32_safe_add | 288 ( 19.2%) | 224 ( 20.2%) | 0 ( NaN%) | 0 ( 0.0%) | 423 ( 24.4%) | 8 | | ····_binop_Eq__LboolR_bool_11_then | 187 ( 12.5%) | 132 ( 11.9%) | 0 ( NaN%) | 0 ( 0.0%) | 142 ( 8.2%) | 9 | | ······tasmlib_arithmetic_u32_safe_add | 99 ( 6.6%) | 77 ( 6.9%) | 0 ( NaN%) | 0 ( 0.0%) | 142 ( 8.2%) | 10 | | ··tasmlib_io_write_to_stdout___u32 | 3 ( 0.2%) | 1 ( 0.1%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 11 | | Total | 1498 (100.0%) | 1108 (100.0%) | 0 ( NaN%) | 66 (100.0%) | 1732 (100.0%) | 12 | -------------------------------------------------------------------------------- /profiles/project_euler_5.profile: -------------------------------------------------------------------------------- 1 | project_euler_5: 2 | | Subroutine | Processor | Op Stack | RAM | Hash | U32 | 3 | |:---------------------------------------------------------------|---------------------:|---------------------:|---------------------:|---------------------:|---------------------:| 4 | | main | 261 ( 99.6%) | 192 (100.0%) | 0 ( NaN%) | 0 ( 0.0%) | 183 (100.0%) | 5 | | ··tasmlib_arithmetic_u32_safe_pow | 181 ( 69.1%) | 130 ( 67.7%) | 0 ( NaN%) | 0 ( 0.0%) | 57 ( 31.1%) | 6 | | ····tasmlib_arithmetic_u32_safe_pow_while_acc | 165 ( 63.0%) | 120 ( 62.5%) | 0 ( NaN%) | 0 ( 0.0%) | 57 ( 31.1%) | 7 | | ······tasmlib_arithmetic_u32_safe_pow_mul_acc_with_bpow2 | 18 ( 6.9%) | 12 ( 6.2%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 8 | | ··tasmlib_arithmetic_u32_safe_mul | 63 ( 24.0%) | 49 ( 25.5%) | 0 ( NaN%) | 0 ( 0.0%) | 126 ( 68.9%) | 9 | | ··tasmlib_io_write_to_stdout___u32 | 3 ( 1.1%) | 1 ( 0.5%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 10 | | Total | 262 (100.0%) | 192 (100.0%) | 0 ( NaN%) | 84 (100.0%) | 183 (100.0%) | 11 | -------------------------------------------------------------------------------- /profiles/project_euler_6.profile: -------------------------------------------------------------------------------- 1 | project_euler_6: 2 | | Subroutine | Processor | Op Stack | RAM | Hash | U32 | 3 | |:---------------------------------------------------------------|---------------------:|---------------------:|---------------------:|---------------------:|---------------------:| 4 | | main | 256 ( 99.6%) | 186 (100.0%) | 0 ( NaN%) | 0 ( 0.0%) | 277 (100.0%) | 5 | | ··tasmlib_arithmetic_u32_safe_pow | 154 ( 59.9%) | 110 ( 59.1%) | 0 ( NaN%) | 0 ( 0.0%) | 102 ( 36.8%) | 6 | | ····tasmlib_arithmetic_u32_safe_pow_while_acc | 138 ( 53.7%) | 100 ( 53.8%) | 0 ( NaN%) | 0 ( 0.0%) | 102 ( 36.8%) | 7 | | ······tasmlib_arithmetic_u32_safe_pow_mul_acc_with_bpow2 | 18 ( 7.0%) | 12 ( 6.5%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 8 | | ··tasmlib_arithmetic_u32_safe_add | 27 ( 10.5%) | 21 ( 11.3%) | 0 ( NaN%) | 0 ( 0.0%) | 17 ( 6.1%) | 9 | | ··tasmlib_arithmetic_u32_safe_mul | 36 ( 14.0%) | 28 ( 15.1%) | 0 ( NaN%) | 0 ( 0.0%) | 74 ( 26.7%) | 10 | | ··tasmlib_arithmetic_u32_safe_sub | 12 ( 4.7%) | 9 ( 4.8%) | 0 ( NaN%) | 0 ( 0.0%) | 26 ( 9.4%) | 11 | | ··tasmlib_io_write_to_stdout___u32 | 3 ( 1.2%) | 1 ( 0.5%) | 0 ( NaN%) | 0 ( 0.0%) | 0 ( 0.0%) | 12 | | Total | 257 (100.0%) | 186 (100.0%) | 0 ( NaN%) | 114 (100.0%) | 277 (100.0%) | 13 | -------------------------------------------------------------------------------- /src/ast_types/abstract_argument.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | use std::fmt::Formatter; 3 | use std::fmt::Result; 4 | 5 | use super::DataType; 6 | use super::FunctionType; 7 | 8 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] 9 | pub(crate) enum AbstractArgument { 10 | FunctionArgument(AbstractFunctionArg), 11 | ValueArgument(AbstractValueArg), 12 | } 13 | 14 | impl AbstractArgument { 15 | pub(crate) fn stack_size(&self) -> usize { 16 | match self { 17 | Self::FunctionArgument(_) => 0, 18 | Self::ValueArgument(arg) => arg.data_type.stack_size(), 19 | } 20 | } 21 | } 22 | 23 | impl Display for AbstractArgument { 24 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { 25 | match self { 26 | Self::FunctionArgument(arg) => write!(f, "{arg}"), 27 | Self::ValueArgument(arg) => write!(f, "{arg}"), 28 | } 29 | } 30 | } 31 | 32 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] 33 | pub(crate) struct AbstractFunctionArg { 34 | pub(crate) abstract_name: String, 35 | pub(crate) function_type: FunctionType, 36 | } 37 | 38 | impl Display for AbstractFunctionArg { 39 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { 40 | write!(f, "fn ({}): {}", self.abstract_name, self.function_type) 41 | } 42 | } 43 | 44 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] 45 | pub(crate) struct AbstractValueArg { 46 | pub(crate) name: String, 47 | pub(crate) data_type: DataType, 48 | pub(crate) mutable: bool, 49 | } 50 | 51 | impl Display for AbstractValueArg { 52 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { 53 | write!(f, "{}: {}", self.name, self.data_type) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ast_types/array_type.rs: -------------------------------------------------------------------------------- 1 | use super::DataType; 2 | 3 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] 4 | pub(crate) struct ArrayType { 5 | pub(crate) element_type: Box, 6 | pub(crate) length: usize, 7 | } 8 | 9 | impl ArrayType { 10 | pub(crate) fn size_in_memory(&self) -> usize { 11 | self.element_type.stack_size() * self.length 12 | } 13 | } 14 | 15 | impl From<&ArrayType> for DataType { 16 | fn from(array_type: &ArrayType) -> Self { 17 | DataType::Array(array_type.to_owned()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/ast_types/field_id.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | 3 | use anyhow::bail; 4 | 5 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] 6 | pub(crate) enum FieldId { 7 | NamedField(String), 8 | UnnamedField(usize), 9 | } 10 | 11 | impl From<&str> for FieldId { 12 | fn from(value: &str) -> Self { 13 | Self::NamedField(value.to_owned()) 14 | } 15 | } 16 | 17 | impl From<&String> for FieldId { 18 | fn from(value: &String) -> Self { 19 | Self::NamedField(value.to_owned()) 20 | } 21 | } 22 | 23 | impl From for FieldId { 24 | fn from(value: String) -> Self { 25 | Self::NamedField(value) 26 | } 27 | } 28 | 29 | impl From<&usize> for FieldId { 30 | fn from(value: &usize) -> Self { 31 | Self::UnnamedField(*value) 32 | } 33 | } 34 | 35 | impl From for FieldId { 36 | fn from(value: usize) -> Self { 37 | Self::UnnamedField(value) 38 | } 39 | } 40 | 41 | impl From for FieldId { 42 | fn from(value: u32) -> Self { 43 | Self::UnnamedField(value as usize) 44 | } 45 | } 46 | 47 | impl TryFrom<&FieldId> for usize { 48 | type Error = anyhow::Error; 49 | 50 | fn try_from(value: &FieldId) -> Result { 51 | match value { 52 | FieldId::NamedField(_) => bail!("Cannot convert named field to usize"), 53 | FieldId::UnnamedField(tuple_index) => Ok(*tuple_index), 54 | } 55 | } 56 | } 57 | 58 | impl Display for FieldId { 59 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 60 | let output = match self { 61 | FieldId::NamedField(name) => name.to_owned(), 62 | FieldId::UnnamedField(tuple_index) => tuple_index.to_string(), 63 | }; 64 | write!(f, "{output}") 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/ast_types/function_type.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | 3 | use super::DataType; 4 | 5 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] 6 | pub(crate) struct FunctionType { 7 | pub(crate) input_argument: DataType, 8 | pub(crate) output: DataType, 9 | } 10 | 11 | impl Display for FunctionType { 12 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 13 | write!(f, "{} -> {}", self.input_argument, self.output) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | tasm_lang::main() 3 | } 4 | -------------------------------------------------------------------------------- /src/tasm_code_generator/data_type/tuple_type.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::triton_asm; 2 | use tasm_lib::triton_vm::prelude::LabelledInstruction; 3 | 4 | use crate::ast_types::Tuple; 5 | use crate::tasm_code_generator::move_top_stack_value_to_memory; 6 | use crate::tasm_code_generator::CompilerState; 7 | 8 | impl Tuple { 9 | /// ```text 10 | /// BEFORE: _ [value] *value 11 | /// AFTER: _ 12 | /// ``` 13 | pub(crate) fn store_to_memory(&self, state: &mut CompilerState) -> Vec { 14 | if self.is_copy() { 15 | return move_top_stack_value_to_memory(None, self.stack_size()); 16 | } 17 | 18 | let label_for_subroutine = format!("store_{}_to_memory", self.label_friendly_name()); 19 | 20 | let call_store_sr = triton_asm!(call { 21 | label_for_subroutine 22 | }); 23 | if state.contains_subroutine(&label_for_subroutine) { 24 | return call_store_sr; 25 | } 26 | 27 | let mut subroutine = triton_asm!( 28 | {label_for_subroutine}: 29 | ); 30 | 31 | let field_pointer_pointer = state.static_memory_allocation(1); 32 | for (_field_id, dtype) in self.field_ids_and_types_reversed() { 33 | // _ [[fields] [current_field]] *current_field_or_field_size 34 | 35 | let handle_field = 36 | dtype.encode_as_field_leave_next_free_address(state, field_pointer_pointer); 37 | subroutine.extend(handle_field); 38 | // _ [[fields]] *next_field_or_field_size 39 | } 40 | 41 | subroutine.extend(triton_asm!( 42 | // _ *next_free_word 43 | 44 | pop 1 45 | // _ 46 | 47 | return 48 | )); 49 | state.add_subroutine(subroutine.try_into().unwrap()); 50 | 51 | call_store_sr 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/tasm_code_generator/function_state.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::collections::HashSet; 3 | 4 | use super::ValueIdentifier; 5 | use crate::tasm_code_generator::InnerFunctionTasmCode; 6 | use crate::tasm_code_generator::SubRoutine; 7 | use crate::tasm_code_generator::VStack; 8 | 9 | pub(crate) type VarAddr = HashMap; 10 | 11 | /// State for managing the compilation of a single function 12 | #[derive(Clone, Debug, Default)] 13 | 14 | pub(crate) struct FunctionState { 15 | pub(crate) vstack: VStack, 16 | pub(crate) var_addr: VarAddr, 17 | pub(crate) spill_required: HashSet, 18 | pub(crate) subroutines: Vec, 19 | } 20 | 21 | impl FunctionState { 22 | /// Add a compiled function and its subroutines to the list of subroutines, thus 23 | /// preserving the structure that would get lost if lists of instructions were 24 | /// simply concatenated. 25 | pub(crate) fn add_compiled_fn_to_subroutines(&mut self, mut function: InnerFunctionTasmCode) { 26 | self.subroutines.append(&mut function.sub_routines); 27 | self.subroutines.push(function.call_depth_zero_code); 28 | } 29 | 30 | /// Force the compiler's view of the stack and bindings to specific values 31 | pub(crate) fn restore_stack_and_bindings( 32 | &mut self, 33 | previous_stack: &VStack, 34 | previous_var_addr: &VarAddr, 35 | ) { 36 | previous_stack.clone_into(&mut self.vstack); 37 | previous_var_addr.clone_into(&mut self.var_addr); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/tasm_code_generator/inner_function_tasm_code.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::triton_asm; 2 | 3 | use crate::subroutine::SubRoutine; 4 | 5 | #[derive(Clone, Debug)] 6 | pub(crate) struct InnerFunctionTasmCode { 7 | pub(crate) name: String, 8 | pub(crate) call_depth_zero_code: SubRoutine, 9 | pub(crate) sub_routines: Vec, 10 | } 11 | 12 | impl InnerFunctionTasmCode { 13 | /// Return a dummy value, needed to allow recursive calls for methods. 14 | /// This dummy-value is guaranteed to crash if it is ever invoked. 15 | pub(crate) fn dummy_value(name: &str) -> Self { 16 | Self { 17 | name: name.to_owned(), 18 | call_depth_zero_code: triton_asm!({name}: push 0 assert return) 19 | .try_into() 20 | .unwrap(), 21 | sub_routines: vec![], 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks.rs: -------------------------------------------------------------------------------- 1 | mod benchmarks; 2 | mod ozk; 3 | mod programs; 4 | mod test_helpers; 5 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/benchmarks.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::fs::create_dir_all; 3 | use std::io::Write; 4 | use std::path::Path; 5 | use std::path::PathBuf; 6 | 7 | use tasm_lib::empty_stack; 8 | use tasm_lib::snippet_bencher::write_benchmarks; 9 | use tasm_lib::snippet_bencher::BenchmarkCase; 10 | use tasm_lib::snippet_bencher::NamedBenchmarkResult; 11 | use tasm_lib::triton_vm::prelude::*; 12 | 13 | use crate::ast; 14 | use crate::type_checker::Typing; 15 | 16 | pub(crate) mod mmr; 17 | 18 | #[derive(Debug, Default, Clone)] 19 | pub(crate) struct BenchmarkInput { 20 | pub(crate) input_args: Vec>, 21 | pub(crate) memory: HashMap, 22 | pub(crate) std_in: Vec, 23 | pub(crate) non_determinism: NonDeterminism, 24 | } 25 | 26 | fn benchmark_code( 27 | function_name: String, 28 | code: Vec, 29 | benchmark_input: BenchmarkInput, 30 | case: BenchmarkCase, 31 | ) -> NamedBenchmarkResult { 32 | let mut stack = empty_stack(); 33 | for input_arg in benchmark_input.input_args { 34 | stack.extend(input_arg.encode().into_iter().rev()); 35 | } 36 | 37 | // Run the tasm-lib's execute function without requesting initialization of the dynamic 38 | // memory allocator, as this is the compiler's responsibility. 39 | let benchmark_result = tasm_lib::linker::execute_bench( 40 | &code, 41 | &stack, 42 | benchmark_input.std_in, 43 | benchmark_input.non_determinism, 44 | None, 45 | ); 46 | 47 | NamedBenchmarkResult { 48 | name: function_name, 49 | benchmark_result, 50 | case, 51 | } 52 | } 53 | 54 | pub(crate) fn profile(function_name: String, code: Vec, case: BenchmarkInput) { 55 | // Write profile for common-case input 56 | let nondeterminism = case.non_determinism; 57 | let public_input = PublicInput::from(case.std_in); 58 | assert!( 59 | case.input_args.is_empty(), 60 | "Can only profile on empty input for now" 61 | ); 62 | assert!( 63 | case.memory.is_empty(), 64 | "Can only profile on empty init memory for now" 65 | ); 66 | let program: Program = Program::new(&code); 67 | let profile = 68 | tasm_lib::generate_full_profile(&function_name, program, &public_input, &nondeterminism); 69 | 70 | let mut path = PathBuf::new(); 71 | path.push("profiles"); 72 | create_dir_all(&path).expect("profiles directory should exist"); 73 | 74 | path.push(Path::new(&function_name).with_extension("profile")); 75 | let mut file = std::fs::File::create(&path).expect("open file for writing"); 76 | write!(file, "{profile}").unwrap(); 77 | } 78 | 79 | pub(crate) fn execute_and_write_benchmark( 80 | function_name: String, 81 | code: Vec, 82 | common_case: BenchmarkInput, 83 | worst_case: BenchmarkInput, 84 | ) { 85 | let benchmark_result_common = benchmark_code( 86 | function_name.clone(), 87 | code.clone(), 88 | common_case.clone(), 89 | BenchmarkCase::CommonCase, 90 | ); 91 | let benchmark_result_worst = benchmark_code( 92 | function_name.clone(), 93 | code.clone(), 94 | worst_case, 95 | BenchmarkCase::WorstCase, 96 | ); 97 | 98 | write_benchmarks(vec![benchmark_result_common, benchmark_result_worst]); 99 | } 100 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/benchmarks/mmr.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod benchmark { 3 | use std::collections::HashMap; 4 | 5 | use rand::random; 6 | use tasm_lib::rust_shadowing_helper_functions; 7 | use tasm_lib::triton_vm::prelude::*; 8 | use tasm_lib::twenty_first::math::other::random_elements; 9 | use tasm_lib::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; 10 | use tasm_lib::twenty_first::util_types::mmr::mmr_trait::Mmr; 11 | 12 | use crate::tests_and_benchmarks::benchmarks::execute_and_write_benchmark; 13 | use crate::tests_and_benchmarks::benchmarks::BenchmarkInput; 14 | use crate::tests_and_benchmarks::programs; 15 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 16 | 17 | #[test] 18 | fn verify_mmr_ap_benchmark() { 19 | fn prepare_benchmark_case(log2_size: u32) -> BenchmarkInput { 20 | let leaf_count_after_add = 1u64 << log2_size; 21 | let peaks: Vec = random_elements(log2_size as usize); 22 | let mut mmra = MmrAccumulator::init(peaks, leaf_count_after_add - 1); 23 | 24 | let own_leaf: Digest = random(); 25 | let mp = mmra.append(own_leaf); 26 | let auth_path = mp.authentication_path; 27 | 28 | let mut memory = HashMap::default(); 29 | let peaks_pointer: BFieldElement = 10000u64.into(); 30 | let peaks = mmra.peaks(); 31 | rust_shadowing_helper_functions::list::list_insert(peaks_pointer, peaks, &mut memory); 32 | 33 | let leaf_index = leaf_count_after_add - 1; 34 | let ap_pointer: BFieldElement = 20000u64.into(); 35 | rust_shadowing_helper_functions::list::list_insert(ap_pointer, auth_path, &mut memory); 36 | 37 | let good_inputs = vec![ 38 | bfe_lit(peaks_pointer), 39 | u64_lit(mmra.num_leafs()), 40 | bfe_lit(ap_pointer), 41 | u64_lit(leaf_index), 42 | digest_lit(own_leaf), 43 | ]; 44 | 45 | BenchmarkInput { 46 | input_args: good_inputs, 47 | memory, 48 | std_in: vec![], 49 | non_determinism: NonDeterminism::new(vec![]), 50 | } 51 | } 52 | 53 | let rast = programs::mmr::verify_authentication_path_with_local_function(); 54 | let (code, fn_name) = compile_for_run_test(&rast); 55 | 56 | let common_case = prepare_benchmark_case(31); 57 | let worst_case = prepare_benchmark_case(50); 58 | 59 | execute_and_write_benchmark(fn_name, code, common_case, worst_case) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk.rs: -------------------------------------------------------------------------------- 1 | // Programs defined in the `ozk::programs` directory must be translatable by both Rust and 2 | // tasm-lang, so we need to give tasm-lang some rope here. 3 | pub(crate) mod ozk_parsing; 4 | #[allow(clippy::needless_return)] 5 | mod programs; 6 | #[cfg(test)] 7 | pub(crate) mod rust_shadows; 8 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs.rs: -------------------------------------------------------------------------------- 1 | mod algebraic_hasher; 2 | mod arithmetic; 3 | mod arrays; 4 | mod boxed; 5 | mod composite_types; 6 | mod destructuring; 7 | mod enums; 8 | mod match_expr_boxed; 9 | mod match_expr_on_stack; 10 | mod match_stmt_boxed; 11 | mod neptune_consensus; 12 | mod option_types; 13 | mod other; 14 | mod project_euler; 15 | pub(crate) mod recufier; 16 | mod result_types; 17 | mod sponge_hasher; 18 | mod structs; 19 | mod type_forcing; 20 | mod vectors; 21 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/algebraic_hasher.rs: -------------------------------------------------------------------------------- 1 | mod hash_atomic_values; 2 | mod hash_boxed_fields; 3 | mod hash_boxed_values; 4 | mod sample_scalars; 5 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/algebraic_hasher/hash_atomic_values.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test { 3 | use tasm::wrap_main_with_io; 4 | use tasm_lib::triton_vm::prelude::*; 5 | use twenty_first::math::other::random_elements; 6 | 7 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 8 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 9 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 10 | 11 | fn hash_atomic_values() { 12 | let digest: Digest = tasm::tasmlib_io_read_stdin___digest(); 13 | let digest_digest: Digest = Tip5::hash(&digest); 14 | tasm::tasmlib_io_write_to_stdout___digest(digest_digest); 15 | 16 | let bfe: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 17 | let bfe_digest: Digest = Tip5::hash(&bfe); 18 | tasm::tasmlib_io_write_to_stdout___digest(bfe_digest); 19 | 20 | let xfe: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 21 | let xfe_digest: Digest = Tip5::hash(&xfe); 22 | tasm::tasmlib_io_write_to_stdout___digest(xfe_digest); 23 | 24 | return; 25 | } 26 | 27 | #[test] 28 | fn hash_values_on_stack_test() { 29 | let std_in = random_elements(Digest::LEN * 3); 30 | let native_output = 31 | wrap_main_with_io(&hash_atomic_values)(std_in.clone(), NonDeterminism::default()); 32 | 33 | let entrypoint = EntrypointLocation::disk( 34 | "algebraic_hasher", 35 | "hash_atomic_values", 36 | "test::hash_atomic_values", 37 | ); 38 | let vm_output = TritonVMTestCase::new(entrypoint.clone()) 39 | .with_std_in(std_in) 40 | .execute() 41 | .unwrap(); 42 | assert_eq!(native_output, vm_output.public_output); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/algebraic_hasher/hash_boxed_fields.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::prelude::TasmObject; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | const SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS: u64 = 84; 7 | 8 | #[derive(TasmObject, BFieldCodec)] 9 | struct OneDField { 10 | a: Vec, 11 | } 12 | 13 | fn one_dynamically_sized_field() { 14 | let test_struct: Box = 15 | OneDField::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap(); 16 | let ts_digest: Digest = Tip5::hash(&test_struct.a); 17 | 18 | tasm::tasmlib_io_write_to_stdout___digest(ts_digest); 19 | 20 | return; 21 | } 22 | 23 | #[derive(TasmObject, BFieldCodec)] 24 | struct OneSField { 25 | a: Digest, 26 | } 27 | 28 | fn one_statically_sized_field() { 29 | let test_struct: Box = 30 | OneSField::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap(); 31 | let ts_digest: Digest = Tip5::hash(&test_struct.a); 32 | tasm::tasmlib_io_write_to_stdout___digest(ts_digest); 33 | return; 34 | } 35 | 36 | #[cfg(test)] 37 | mod test { 38 | use rand::random; 39 | use tasm::wrap_main_with_io; 40 | use tasm_lib::triton_vm::prelude::*; 41 | use twenty_first::math::other::random_elements; 42 | 43 | use super::*; 44 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 45 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 46 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 47 | 48 | #[test] 49 | fn one_dynamically_sized_field_test() { 50 | let test_struct = OneDField { 51 | a: random_elements(2), 52 | }; 53 | let non_determinism = init_memory_from( 54 | &test_struct, 55 | BFieldElement::new(SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS), 56 | ); 57 | let native_output = 58 | wrap_main_with_io(&one_dynamically_sized_field)(vec![], non_determinism.clone()); 59 | 60 | let entrypoint = EntrypointLocation::disk( 61 | "algebraic_hasher", 62 | "hash_boxed_fields", 63 | "one_dynamically_sized_field", 64 | ); 65 | let vm_output = TritonVMTestCase::new(entrypoint.clone()) 66 | .with_non_determinism(non_determinism) 67 | .execute() 68 | .unwrap(); 69 | assert_eq!(native_output, vm_output.public_output); 70 | } 71 | 72 | #[test] 73 | fn one_statically_sized_field_test() { 74 | let test_struct = OneSField { a: random() }; 75 | let non_determinism = init_memory_from( 76 | &test_struct, 77 | BFieldElement::new(SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS), 78 | ); 79 | let native_output = 80 | wrap_main_with_io(&one_statically_sized_field)(vec![], non_determinism.clone()); 81 | 82 | let entrypoint = EntrypointLocation::disk( 83 | "algebraic_hasher", 84 | "hash_boxed_fields", 85 | "one_statically_sized_field", 86 | ); 87 | let vm_output = TritonVMTestCase::new(entrypoint.clone()) 88 | .with_non_determinism(non_determinism) 89 | .execute() 90 | .unwrap(); 91 | assert_eq!(native_output, vm_output.public_output); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic.rs: -------------------------------------------------------------------------------- 1 | mod bfe_add; 2 | mod bfe_inverse; 3 | mod dazefield_element_mul; 4 | mod ilog2_u32; 5 | mod mod_pow_u32; 6 | pub(crate) mod montyred; 7 | mod wrapping_sub; 8 | mod xfe_bfe; 9 | mod xfe_inverse; 10 | mod xfe_mod_pow_u32; 11 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic/bfe_add.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn main() { 6 | let a: BFieldElement = BFieldElement::new(14); 7 | let b: BFieldElement = BFieldElement::new(15); 8 | let c: BFieldElement = a + b; 9 | tasm::tasmlib_io_write_to_stdout___bfe(c); 10 | 11 | let d: u64 = 1001 + (1u64 << 32); 12 | let e: BFieldElement = BFieldElement::new(d); 13 | tasm::tasmlib_io_write_to_stdout___bfe(e); 14 | 15 | let f: u64 = 1001000 + (1u64 << 32); 16 | let g: BFieldElement = BFieldElement::new(f); 17 | tasm::tasmlib_io_write_to_stdout___bfe(g); 18 | 19 | return; 20 | } 21 | 22 | #[cfg(test)] 23 | mod test { 24 | use super::*; 25 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 26 | use crate::tests_and_benchmarks::ozk::rust_shadows; 27 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 28 | 29 | #[test] 30 | fn add_bfe_ozk_test_same_file() { 31 | // Test function on host machine 32 | let stdin = vec![]; 33 | let non_determinism = NonDeterminism::new(vec![]); 34 | let expected_output = vec![ 35 | BFieldElement::new(29), 36 | BFieldElement::new(1001 + (1u64 << 32)), 37 | BFieldElement::new(1001000 + (1u64 << 32)), 38 | ]; 39 | let native_output = 40 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 41 | assert_eq!(native_output, expected_output); 42 | 43 | let entrypoint = EntrypointLocation::disk("arithmetic", "bfe_add", "main"); 44 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 45 | 46 | assert_eq!(expected_output, vm_output.public_output); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic/bfe_inverse.rs: -------------------------------------------------------------------------------- 1 | use num::One; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | fn main() { 7 | let bfe: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 8 | tasm::tasmlib_io_write_to_stdout___bfe(bfe.inverse()); 9 | 10 | assert!(BFieldElement::one() == bfe.inverse() * bfe); 11 | 12 | return; 13 | } 14 | 15 | #[cfg(test)] 16 | mod test { 17 | use std::panic::catch_unwind; 18 | 19 | use num::Zero; 20 | use tasm_lib::twenty_first::math::other::random_elements; 21 | 22 | use super::*; 23 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 24 | use crate::tests_and_benchmarks::ozk::rust_shadows::wrap_main_with_io; 25 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 26 | 27 | #[test] 28 | fn bfe_inverse_test() { 29 | let std_in = random_elements(1); 30 | let native_output = wrap_main_with_io(&main)(std_in.clone(), NonDeterminism::default()); 31 | let entrypoint = EntrypointLocation::disk("arithmetic", "bfe_inverse", "main"); 32 | let vm_output = TritonVMTestCase::new(entrypoint) 33 | .with_std_in(std_in) 34 | .execute() 35 | .unwrap(); 36 | assert_eq!(native_output, vm_output.public_output); 37 | } 38 | 39 | #[test] 40 | fn bfe_crash_on_zero_input_arg() { 41 | let std_in = vec![BFieldElement::zero()]; 42 | catch_unwind(|| { 43 | let rust_program = wrap_main_with_io(&main); 44 | rust_program(std_in.clone(), NonDeterminism::default()); 45 | }) 46 | .unwrap_err(); 47 | 48 | let entrypoint = EntrypointLocation::disk("arithmetic", "bfe_inverse", "main"); 49 | let err = TritonVMTestCase::new(entrypoint) 50 | .with_std_in(std_in) 51 | .execute() 52 | .unwrap_err(); 53 | let err = err.downcast::().unwrap(); 54 | assert_eq!(InstructionError::InverseOfZero, err); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic/ilog2_u32.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn output_ilog2() { 6 | let value: u32 = tasm::tasmlib_io_read_stdin___u32(); 7 | tasm::tasmlib_io_write_to_stdout___u32(value.ilog2()); 8 | 9 | return; 10 | } 11 | 12 | #[cfg(test)] 13 | mod test { 14 | use num::Zero; 15 | use test_strategy::proptest; 16 | 17 | use super::*; 18 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 19 | use crate::tests_and_benchmarks::ozk::rust_shadows; 20 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 21 | 22 | #[proptest(cases = 10)] 23 | fn ilog2_proptest(value: u32) { 24 | let entrypoint = EntrypointLocation::disk("arithmetic", "ilog2_u32", "output_ilog2"); 25 | let std_in = vec![BFieldElement::new(value as u64)]; 26 | let native_output = rust_shadows::wrap_main_with_io(&output_ilog2)( 27 | std_in.clone(), 28 | NonDeterminism::default(), 29 | ); 30 | let vm_output = TritonVMTestCase::new(entrypoint) 31 | .with_std_in(std_in.clone()) 32 | .execute() 33 | .unwrap(); 34 | assert_eq!(native_output, vm_output.public_output); 35 | } 36 | 37 | #[test] 38 | fn ilog2_unit_test() { 39 | let entrypoint = EntrypointLocation::disk("arithmetic", "ilog2_u32", "output_ilog2"); 40 | let test_case = TritonVMTestCase::new(entrypoint); 41 | let compiled = test_case.compile(); 42 | 43 | let test_cases = (1..100).chain([u32::MAX - 1, u32::MAX]); 44 | for i in test_cases { 45 | let std_in = vec![BFieldElement::new(i as u64)]; 46 | let native_output = rust_shadows::wrap_main_with_io(&output_ilog2)( 47 | std_in.clone(), 48 | NonDeterminism::default(), 49 | ); 50 | 51 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 52 | &compiled, 53 | vec![], 54 | std_in, 55 | NonDeterminism::default(), 56 | 0, 57 | ) 58 | .unwrap(); 59 | assert_eq!(native_output, vm_output.public_output); 60 | } 61 | } 62 | 63 | #[test] 64 | fn ilog2_of_zero_verify_crash_negative_test() { 65 | let std_in = vec![BFieldElement::zero()]; 66 | let entrypoint = EntrypointLocation::disk("arithmetic", "ilog2_u32", "output_ilog2"); 67 | let err = TritonVMTestCase::new(entrypoint) 68 | .with_std_in(std_in.clone()) 69 | .execute() 70 | .unwrap_err(); 71 | let err = err.downcast::().unwrap(); 72 | assert_eq!(InstructionError::LogarithmOfZero, err); 73 | 74 | // Verify that host-machine execution environment also crashes 75 | let host_machine_execution_result = std::panic::catch_unwind(|| { 76 | rust_shadows::wrap_main_with_io(&output_ilog2)( 77 | std_in.clone(), 78 | NonDeterminism::default(), 79 | ) 80 | }); 81 | assert!(host_machine_execution_result.is_err()); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic/mod_pow_u32.rs: -------------------------------------------------------------------------------- 1 | use num::One; 2 | use tasm_lib::triton_vm::prelude::*; 3 | use tasm_lib::twenty_first::math::traits::ModPowU32; 4 | 5 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 6 | 7 | fn main() { 8 | let base_number: BFieldElement = BFieldElement::new(144449u64); 9 | let mut pow_expected: BFieldElement = BFieldElement::one(); 10 | let threshold: u32 = 50; 11 | let mut exponent: u32 = 0; 12 | while exponent <= threshold { 13 | assert!(pow_expected == base_number.mod_pow_u32(exponent)); 14 | pow_expected *= base_number; 15 | exponent += 1; 16 | } 17 | 18 | tasm::tasmlib_io_write_to_stdout___bfe(base_number.mod_pow_u32(exponent)); 19 | 20 | return; 21 | } 22 | 23 | #[cfg(test)] 24 | mod test { 25 | use super::*; 26 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 27 | use crate::tests_and_benchmarks::ozk::rust_shadows; 28 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 29 | 30 | #[test] 31 | fn mod_pow_u32_test() { 32 | // Test function on host machine 33 | let stdin = vec![]; 34 | let non_determinism = NonDeterminism::default(); 35 | let native_output = rust_shadows::wrap_main_with_io(&main)(stdin, non_determinism); 36 | 37 | let expected_output = vec![BFieldElement::new(144449u64).mod_pow_u32(51)]; 38 | assert_eq!(native_output, expected_output); 39 | 40 | let entrypoint = EntrypointLocation::disk("arithmetic", "mod_pow_u32", "main"); 41 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 42 | 43 | assert_eq!(expected_output, vm_output.public_output); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic/wrapping_sub.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | assert!(2u64 == 3u64.wrapping_sub(1u64)); 3 | assert!( 4 | 0x0000_0004_0000_0003u64 == 0x0000_000b_0000_0005u64.wrapping_sub(0x0000_0007_0000_0002u64) 5 | ); 6 | 7 | return; 8 | } 9 | 10 | #[cfg(test)] 11 | mod test { 12 | 13 | use itertools::Itertools; 14 | use tasm_lib::triton_vm::prelude::*; 15 | 16 | use super::*; 17 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 18 | use crate::tests_and_benchmarks::ozk::rust_shadows; 19 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 20 | 21 | #[test] 22 | fn wrapping_sub_test() { 23 | let stdin = vec![]; 24 | let non_determinism = NonDeterminism::default(); 25 | let expected_output = vec![]; 26 | let native_output = rust_shadows::wrap_main_with_io(&main)(stdin, non_determinism); 27 | assert_eq!(native_output, expected_output); 28 | 29 | let entrypoint_location = 30 | ozk_parsing::EntrypointLocation::disk("arithmetic", "wrapping_sub", "main"); 31 | let vm_output = TritonVMTestCase::new(entrypoint_location) 32 | .execute() 33 | .unwrap(); 34 | 35 | if expected_output != vm_output.public_output { 36 | panic!( 37 | "expected:\n{}\n\ngot:\n{}", 38 | expected_output.iter().join(","), 39 | vm_output.public_output.iter().join(",") 40 | ); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic/xfe_bfe.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn main() { 6 | let bfe: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 7 | let xfe: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 8 | tasm::tasmlib_io_write_to_stdout___xfe(xfe + bfe); 9 | tasm::tasmlib_io_write_to_stdout___xfe(xfe - bfe); 10 | 11 | return; 12 | } 13 | 14 | #[cfg(test)] 15 | mod test { 16 | use tasm_lib::twenty_first::math::other::random_elements; 17 | 18 | use super::*; 19 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 20 | use crate::tests_and_benchmarks::ozk::rust_shadows; 21 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 22 | 23 | #[test] 24 | fn xfe_bfe_arithmetic() { 25 | let std_in = random_elements(4); 26 | let native_output_add = 27 | rust_shadows::wrap_main_with_io(&main)(std_in.clone(), NonDeterminism::default()); 28 | let entrypoint_add = EntrypointLocation::disk("arithmetic", "xfe_bfe", "main"); 29 | let vm_output = TritonVMTestCase::new(entrypoint_add) 30 | .with_std_in(std_in) 31 | .execute() 32 | .unwrap(); 33 | assert_eq!(native_output_add, vm_output.public_output); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arithmetic/xfe_inverse.rs: -------------------------------------------------------------------------------- 1 | use num::One; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | fn main() { 7 | let xfe: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 8 | tasm::tasmlib_io_write_to_stdout___xfe(xfe.inverse()); 9 | 10 | assert!(XFieldElement::one() == xfe.inverse() * xfe); 11 | 12 | return; 13 | } 14 | 15 | fn no_name_clash_on_bfe_and_xfe_inverse() { 16 | let xfe: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 17 | let bfe: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 18 | 19 | assert!(XFieldElement::one() == xfe.inverse() * xfe); 20 | assert!(BFieldElement::one() == bfe.inverse() * bfe); 21 | 22 | tasm::tasmlib_io_write_to_stdout___xfe(xfe.inverse()); 23 | tasm::tasmlib_io_write_to_stdout___bfe(bfe.inverse()); 24 | 25 | return; 26 | } 27 | 28 | #[cfg(test)] 29 | mod test { 30 | use std::panic::catch_unwind; 31 | 32 | use num::Zero; 33 | use tasm_lib::twenty_first::math::other::random_elements; 34 | use tasm_lib::twenty_first::math::x_field_element::EXTENSION_DEGREE; 35 | 36 | use super::*; 37 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 38 | use crate::tests_and_benchmarks::ozk::rust_shadows::wrap_main_with_io; 39 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 40 | 41 | #[test] 42 | fn xfe_inverse_test() { 43 | let std_in = random_elements(EXTENSION_DEGREE); 44 | let native_output = wrap_main_with_io(&main)(std_in.clone(), NonDeterminism::default()); 45 | let entrypoint = EntrypointLocation::disk("arithmetic", "xfe_inverse", "main"); 46 | let vm_output = TritonVMTestCase::new(entrypoint) 47 | .with_std_in(std_in) 48 | .execute() 49 | .unwrap(); 50 | assert_eq!(native_output, vm_output.public_output); 51 | } 52 | 53 | #[test] 54 | fn no_name_clash_bfe_xfe_inverse_test() { 55 | let std_in = random_elements(EXTENSION_DEGREE + 1); 56 | let native_output = wrap_main_with_io(&no_name_clash_on_bfe_and_xfe_inverse)( 57 | std_in.clone(), 58 | NonDeterminism::default(), 59 | ); 60 | let entrypoint = EntrypointLocation::disk( 61 | "arithmetic", 62 | "xfe_inverse", 63 | "no_name_clash_on_bfe_and_xfe_inverse", 64 | ); 65 | let vm_output = TritonVMTestCase::new(entrypoint) 66 | .with_std_in(std_in) 67 | .execute() 68 | .unwrap(); 69 | assert_eq!(native_output, vm_output.public_output); 70 | } 71 | 72 | #[test] 73 | fn xfe_crash_on_zero_input_arg() { 74 | let std_in = vec![BFieldElement::zero(); EXTENSION_DEGREE]; 75 | catch_unwind(|| { 76 | let rust_program = wrap_main_with_io(&main); 77 | rust_program(std_in.clone(), NonDeterminism::default()); 78 | }) 79 | .unwrap_err(); 80 | 81 | let entrypoint = EntrypointLocation::disk("arithmetic", "xfe_inverse", "main"); 82 | let err = TritonVMTestCase::new(entrypoint) 83 | .with_std_in(std_in) 84 | .execute() 85 | .unwrap_err(); 86 | let err = err.downcast::().unwrap(); 87 | assert_eq!(InstructionError::InverseOfZero, err); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arrays.rs: -------------------------------------------------------------------------------- 1 | mod array_to_vec; 2 | mod bfe_array; 3 | mod bfe_array_boxed; 4 | mod repeat_syntax; 5 | mod vec_to_array; 6 | mod xfe_array; 7 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arrays/array_in_struct.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TritonVM/tasm-lang/18e982dfdbebfec5fdf8316b9e2d4b7fb4a353c4/src/tests_and_benchmarks/ozk/programs/arrays/array_in_struct.rs -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arrays/array_to_vec.rs: -------------------------------------------------------------------------------- 1 | use num::Zero; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | fn main() { 7 | let mut array: [XFieldElement; 3] = [XFieldElement::zero(); 3]; 8 | array[0] = tasm::tasmlib_io_read_stdin___xfe(); 9 | array[1] = tasm::tasmlib_io_read_stdin___xfe(); 10 | array[2] = tasm::tasmlib_io_read_stdin___xfe(); 11 | let as_vec: Vec = array.to_vec(); 12 | tasm::tasmlib_io_write_to_stdout___xfe(as_vec[0]); 13 | tasm::tasmlib_io_write_to_stdout___xfe(as_vec[1]); 14 | tasm::tasmlib_io_write_to_stdout___xfe(as_vec[2]); 15 | 16 | return; 17 | } 18 | 19 | #[cfg(test)] 20 | mod test { 21 | use tasm_lib::twenty_first::math::other::random_elements; 22 | use tasm_lib::twenty_first::math::x_field_element::EXTENSION_DEGREE; 23 | 24 | use super::*; 25 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 26 | use crate::tests_and_benchmarks::ozk::rust_shadows; 27 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 28 | 29 | #[test] 30 | fn array_to_vec() { 31 | let std_in = random_elements(3 * EXTENSION_DEGREE); 32 | let native_output = 33 | rust_shadows::wrap_main_with_io(&main)(std_in.clone(), NonDeterminism::default()); 34 | let entrypoint_add = EntrypointLocation::disk("arrays", "array_to_vec", "main"); 35 | let vm_output = TritonVMTestCase::new(entrypoint_add) 36 | .with_std_in(std_in) 37 | .execute() 38 | .unwrap(); 39 | assert_eq!(native_output, vm_output.public_output); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/arrays/vec_to_array.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | #[allow(clippy::vec_init_then_push)] 6 | fn succeed_conversion() { 7 | let mut as_vec: Vec = Vec::::default(); 8 | as_vec.push(tasm::tasmlib_io_read_stdin___xfe()); 9 | as_vec.push(tasm::tasmlib_io_read_stdin___xfe()); 10 | as_vec.push(tasm::tasmlib_io_read_stdin___xfe()); 11 | let as_array: [XFieldElement; 3] = <[XFieldElement; 3]>::try_from(as_vec).unwrap(); 12 | tasm::tasmlib_io_write_to_stdout___xfe(as_array[0]); 13 | tasm::tasmlib_io_write_to_stdout___xfe(as_array[1]); 14 | tasm::tasmlib_io_write_to_stdout___xfe(as_array[2]); 15 | 16 | return; 17 | } 18 | 19 | #[allow(clippy::vec_init_then_push)] 20 | fn _fail_conversion() { 21 | let mut as_vec: Vec = Vec::::default(); 22 | as_vec.push(tasm::tasmlib_io_read_stdin___xfe()); 23 | as_vec.push(tasm::tasmlib_io_read_stdin___xfe()); 24 | as_vec.push(tasm::tasmlib_io_read_stdin___xfe()); 25 | let conv_res: Result<[XFieldElement; 4], _> = <[XFieldElement; 4]>::try_from(as_vec); 26 | let boxed_conv_res: Box> = 27 | Box::>::new(conv_res); 28 | assert!(boxed_conv_res.is_err()); 29 | assert!(!boxed_conv_res.is_ok()); 30 | 31 | return; 32 | } 33 | 34 | #[cfg(test)] 35 | mod test { 36 | use tasm_lib::twenty_first::math::other::random_elements; 37 | use tasm_lib::twenty_first::math::x_field_element::EXTENSION_DEGREE; 38 | 39 | use super::*; 40 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 41 | use crate::tests_and_benchmarks::ozk::rust_shadows; 42 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 43 | 44 | #[test] 45 | fn vec_to_array_positive_test() { 46 | let std_in = random_elements(3 * EXTENSION_DEGREE); 47 | let native_output = rust_shadows::wrap_main_with_io(&succeed_conversion)( 48 | std_in.clone(), 49 | NonDeterminism::default(), 50 | ); 51 | let vm_output = TritonVMTestCase::new(EntrypointLocation::disk( 52 | "arrays", 53 | "vec_to_array", 54 | "succeed_conversion", 55 | )) 56 | .with_std_in(std_in.clone()) 57 | .execute() 58 | .unwrap(); 59 | assert_eq!(native_output, vm_output.public_output); 60 | } 61 | 62 | #[test] 63 | fn vec_to_array_negative_test() { 64 | let std_in = random_elements(3 * EXTENSION_DEGREE); 65 | assert!(TritonVMTestCase::new(EntrypointLocation::disk( 66 | "arrays", 67 | "vec_to_array", 68 | "_fail_conversion", 69 | )) 70 | .with_std_in(std_in) 71 | .execute() 72 | .is_ok()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed.rs: -------------------------------------------------------------------------------- 1 | mod bfe; 2 | mod bfe_pair; 3 | mod box_a_list_simple; 4 | mod box_a_struct_with_list_field_simple; 5 | mod box_a_struct_with_two_list_fields; 6 | mod box_an_array_simple; 7 | mod box_complex_flat_struct; 8 | mod digest_pair; 9 | mod enum_to_memory_simple; 10 | mod flat_tuples; 11 | mod method_on_nested_struct_simple; 12 | mod methods_on_boxed_tuple_structs; 13 | mod methods_on_nested_structs_not_copy; 14 | mod nested_tuples; 15 | mod ref_struct_typecheck_fail; 16 | mod ref_struct_typecheck_succeed_bc_boxed; 17 | mod simple_struct_copy; 18 | mod tuple_struct_one_element; 19 | mod tuple_struct_one_element_simple; 20 | mod tuple_struct_two_elements_copy; 21 | mod tuple_struct_two_elements_not_copy; 22 | mod tuple_struct_with_vec; 23 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/bfe.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn main() { 6 | // Store two BFieldElements in memory. Then read them out again. 7 | let a: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 8 | let b: BFieldElement = BFieldElement::new((1u64 << 40) + 132); 9 | let boxed_a: Box = Box::::new(a); 10 | let boxed_b: Box = Box::::new(b); 11 | 12 | assert!(a == *boxed_a); 13 | assert!(b == *boxed_b); 14 | 15 | tasm::tasmlib_io_write_to_stdout___bfe(*boxed_b); 16 | tasm::tasmlib_io_write_to_stdout___bfe(*boxed_a); 17 | 18 | return; 19 | } 20 | 21 | #[cfg(test)] 22 | mod test { 23 | use itertools::Itertools; 24 | use rand::random; 25 | 26 | use super::*; 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 28 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 29 | use crate::tests_and_benchmarks::ozk::rust_shadows; 30 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 31 | 32 | #[test] 33 | fn boxed_bfe_test() { 34 | // Test function on host machine 35 | let rand: BFieldElement = random(); 36 | let stdin = vec![rand]; 37 | let non_determinism = NonDeterminism::new(vec![]); 38 | // let expected_output = vec![BFieldElement::new((1u64 << 40) + 132), rand]; 39 | let native_output = 40 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 41 | // assert_eq!(native_output, expected_output); 42 | 43 | // Test function in Triton VM 44 | let entrypoint_location = EntrypointLocation::disk("boxed", "bfe", "main"); 45 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 46 | let expected_stack_diff = 0; 47 | println!("test_program:\n{}", test_program.iter().join("\n")); 48 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 49 | &test_program, 50 | vec![], 51 | stdin, 52 | NonDeterminism::new(vec![]), 53 | expected_stack_diff, 54 | ) 55 | .unwrap(); 56 | if native_output != vm_output.public_output { 57 | panic!( 58 | "expected:\n{}\n\ngot:\n{}", 59 | native_output.iter().join(","), 60 | vm_output.public_output.iter().join(",") 61 | ); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/bfe_pair.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn main() { 6 | // Store two BFieldElements in memory. Then read them out again. 7 | let a: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 8 | let b: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 9 | let boxed_ab: Box<(BFieldElement, BFieldElement)> = 10 | Box::<(BFieldElement, BFieldElement)>::new((a, b)); 11 | let e: (BFieldElement, BFieldElement) = *boxed_ab; 12 | assert!(a == e.0); 13 | assert!(b == e.1); 14 | 15 | tasm::tasmlib_io_write_to_stdout___bfe(e.1); 16 | tasm::tasmlib_io_write_to_stdout___bfe(e.0); 17 | tasm::tasmlib_io_write_to_stdout___bfe(e.0); 18 | 19 | return; 20 | } 21 | 22 | #[cfg(test)] 23 | mod test { 24 | use rand::random; 25 | 26 | use super::*; 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 28 | use crate::tests_and_benchmarks::ozk::rust_shadows; 29 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 30 | 31 | #[test] 32 | fn boxed_bfe_pair_test() { 33 | let a: BFieldElement = random(); 34 | let b: BFieldElement = random(); 35 | let stdin = vec![a, b]; 36 | let expected_output = vec![b, a, a]; 37 | 38 | let native_output = 39 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), NonDeterminism::default()); 40 | assert_eq!(native_output, expected_output); 41 | 42 | let entrypoint = EntrypointLocation::disk("boxed", "bfe_pair", "main"); 43 | let vm_output = TritonVMTestCase::new(entrypoint) 44 | .with_std_in(stdin) 45 | .execute() 46 | .unwrap(); 47 | assert_eq!(expected_output, vm_output.public_output); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/box_a_list_simple.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test { 3 | use tasm_lib::triton_vm::prelude::*; 4 | 5 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 6 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 7 | use crate::tests_and_benchmarks::ozk::rust_shadows; 8 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 9 | 10 | #[allow(clippy::vec_init_then_push)] 11 | fn main() { 12 | let mut list: Vec = Vec::::default(); 13 | list.push(BFieldElement::new(102)); 14 | let boxed_list: Box> = Box::>::new(list); 15 | tasm::tasmlib_io_write_to_stdout___bfe(boxed_list[0]); 16 | 17 | return; 18 | } 19 | 20 | #[test] 21 | fn box_a_list_simple() { 22 | let native_output = 23 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 24 | let entrypoint = EntrypointLocation::disk("boxed", "box_a_list_simple", "test::main"); 25 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 26 | assert_eq!(native_output, vm_output.public_output); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/box_a_struct_with_list_field_simple.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | #[derive(BFieldCodec)] 6 | struct WithListField { 7 | bfes: Vec, 8 | } 9 | 10 | #[allow(clippy::vec_init_then_push)] 11 | fn main() { 12 | let mut list: Vec = Vec::::default(); 13 | list.push(BFieldElement::new(102)); 14 | list.push(BFieldElement::new(2222)); 15 | list.push(BFieldElement::new(3333333)); 16 | let wlf: WithListField = WithListField { bfes: list }; 17 | let boxed: Box = Box::::new(wlf); 18 | tasm::tasmlib_io_write_to_stdout___bfe(boxed.bfes[0]); 19 | tasm::tasmlib_io_write_to_stdout___bfe(boxed.bfes[1]); 20 | tasm::tasmlib_io_write_to_stdout___bfe(boxed.bfes[2]); 21 | 22 | return; 23 | } 24 | 25 | #[cfg(test)] 26 | mod test { 27 | use super::*; 28 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 29 | use crate::tests_and_benchmarks::ozk::rust_shadows; 30 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 31 | 32 | #[test] 33 | fn box_a_struct_with_list_field_simple() { 34 | let native_output = 35 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 36 | let entrypoint = 37 | EntrypointLocation::disk("boxed", "box_a_struct_with_list_field_simple", "main"); 38 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 39 | assert_eq!(native_output, vm_output.public_output); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/box_a_struct_with_two_list_fields.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | #[derive(BFieldCodec)] 6 | struct WithListFields { 7 | bfes: Vec, 8 | xfes: Vec, 9 | } 10 | 11 | #[allow(clippy::redundant_field_names)] 12 | fn main() { 13 | let mut bfes: Vec = Vec::::default(); 14 | let mut xfes: Vec = Vec::::default(); 15 | bfes.push(BFieldElement::new(102)); 16 | bfes.push(BFieldElement::new(2222)); 17 | xfes.push(tasm::tasmlib_io_read_stdin___xfe()); 18 | xfes.push(tasm::tasmlib_io_read_stdin___xfe()); 19 | let wlf: WithListFields = WithListFields { 20 | bfes: bfes, 21 | xfes: xfes, 22 | }; 23 | let boxed: Box = Box::::new(wlf); 24 | tasm::tasmlib_io_write_to_stdout___bfe(boxed.bfes[0]); 25 | tasm::tasmlib_io_write_to_stdout___xfe(boxed.xfes[0]); 26 | tasm::tasmlib_io_write_to_stdout___xfe(boxed.xfes[1]); 27 | tasm::tasmlib_io_write_to_stdout___bfe(boxed.bfes[1]); 28 | 29 | return; 30 | } 31 | 32 | #[cfg(test)] 33 | mod test { 34 | use tasm_lib::twenty_first::math::other::random_elements; 35 | 36 | use super::*; 37 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 38 | use crate::tests_and_benchmarks::ozk::rust_shadows; 39 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 40 | 41 | #[test] 42 | fn box_a_struct_with_two_list_fields() { 43 | let stdin = random_elements(6); 44 | let native_output = 45 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), NonDeterminism::default()); 46 | let entrypoint = 47 | EntrypointLocation::disk("boxed", "box_a_struct_with_two_list_fields", "main"); 48 | let vm_output = TritonVMTestCase::new(entrypoint) 49 | .with_std_in(stdin) 50 | .execute() 51 | .unwrap(); 52 | assert_eq!(native_output, vm_output.public_output); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/box_an_array_simple.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test { 3 | use tasm_lib::triton_vm::prelude::*; 4 | 5 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 6 | use crate::tests_and_benchmarks::ozk::rust_shadows; 7 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 8 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 9 | 10 | fn main() { 11 | let array: [BFieldElement; 2] = [BFieldElement::new(101), BFieldElement::new(102)]; 12 | let boxed_array: Box<[BFieldElement; 2]> = Box::<[BFieldElement; 2]>::new(array); 13 | tasm::tasmlib_io_write_to_stdout___bfe(boxed_array[0]); 14 | 15 | return; 16 | } 17 | 18 | #[test] 19 | fn box_an_array_simple() { 20 | let entrypoint = EntrypointLocation::disk("boxed", "box_an_array_simple", "test::main"); 21 | let native_output = 22 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 23 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 24 | assert_eq!(native_output, vm_output.public_output); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/method_on_nested_struct_simple.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Copy)] 2 | struct OuterStruct(InnerStruct); 3 | 4 | #[derive(Clone, Copy)] 5 | struct InnerStruct(u32); 6 | 7 | impl InnerStruct { 8 | fn double(self) -> u32 { 9 | return self.0 + self.0; 10 | } 11 | } 12 | 13 | fn main() { 14 | let inner_a: InnerStruct = InnerStruct(2001); 15 | let outer_struct: OuterStruct = OuterStruct(inner_a); 16 | let outer_struct_boxed: Box = Box::::new(outer_struct); 17 | assert!(4002 == outer_struct_boxed.0.double()); 18 | 19 | return; 20 | } 21 | 22 | #[cfg(test)] 23 | mod test { 24 | use tasm_lib::triton_vm::prelude::*; 25 | 26 | use super::*; 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 28 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 29 | use crate::tests_and_benchmarks::ozk::rust_shadows; 30 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 31 | 32 | #[test] 33 | fn methods_on_nested_structs_simple_test() { 34 | let stdin = vec![]; 35 | let non_determinism = NonDeterminism::default(); 36 | let native_output = 37 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 38 | 39 | let entrypoint_location = 40 | EntrypointLocation::disk("boxed", "method_on_nested_struct_simple", "main"); 41 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 42 | 43 | let expected_stack_diff = 0; 44 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 45 | &test_program, 46 | vec![], 47 | stdin, 48 | non_determinism, 49 | expected_stack_diff, 50 | ) 51 | .unwrap() 52 | .public_output; 53 | 54 | assert_eq!(native_output, vm_output); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/methods_on_boxed_tuple_structs.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | #[derive(Clone, Copy)] 4 | struct TupleStructA(u128, u64); 5 | 6 | impl TupleStructA { 7 | fn _half_value(primary_value: u128) -> TupleStructA { 8 | assert!(primary_value < (1u128 << 65)); 9 | return TupleStructA(primary_value, (primary_value / 2) as u64); 10 | } 11 | 12 | fn sum(&self) -> u128 { 13 | return self.0 + self.1 as u128; 14 | } 15 | } 16 | 17 | fn main() { 18 | let a_0: u128 = tasm::tasmlib_io_read_stdin___u128(); 19 | let a_1: u64 = tasm::tasmlib_io_read_stdin___u64(); 20 | let tsa: TupleStructA = TupleStructA(a_0, a_1); 21 | let tsa_boxed: Box = Box::::new(tsa); 22 | tasm::tasmlib_io_write_to_stdout___u128(tsa_boxed.sum()); 23 | 24 | return; 25 | } 26 | 27 | #[cfg(test)] 28 | mod test { 29 | use itertools::Itertools; 30 | use rand::random; 31 | use tasm_lib::triton_vm::prelude::*; 32 | 33 | use super::*; 34 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 35 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 36 | use crate::tests_and_benchmarks::ozk::rust_shadows; 37 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 38 | 39 | #[test] 40 | fn method_on_boxed_tuple() { 41 | let a_0: u128 = random(); 42 | let a_1: u64 = random(); 43 | let mut a0_encoded_reverse = a_0.encode(); 44 | a0_encoded_reverse.reverse(); 45 | let mut a1_encoded_reverse = a_1.encode(); 46 | a1_encoded_reverse.reverse(); 47 | let expected_output = (a_0 + a_1 as u128).encode(); 48 | let stdin = [a0_encoded_reverse, a1_encoded_reverse].concat(); 49 | let non_determinism = NonDeterminism::new(vec![]); 50 | let native_output = 51 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 52 | assert_eq!(native_output, expected_output); 53 | 54 | // Test function in Triton VM 55 | let entrypoint_location = 56 | EntrypointLocation::disk("boxed", "methods_on_boxed_tuple_structs", "main"); 57 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 58 | let expected_stack_diff = 0; 59 | println!("test_program:\n{}", test_program.iter().join("\n")); 60 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 61 | &test_program, 62 | vec![], 63 | stdin, 64 | non_determinism, 65 | expected_stack_diff, 66 | ) 67 | .unwrap(); 68 | if expected_output != vm_output.public_output { 69 | panic!( 70 | "expected:\n{}\n\ngot:\n{}", 71 | expected_output.iter().join(","), 72 | vm_output.public_output.iter().join(",") 73 | ); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/ref_struct_typecheck_fail.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::needless_borrow)] 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | // Expect a type check error 6 | struct SomeStruct(u64); 7 | 8 | impl SomeStruct { 9 | #[allow(dead_code)] 10 | fn new(value: u64) -> SomeStruct { 11 | return SomeStruct(value + 0xabcde123u64); 12 | } 13 | 14 | // This function expects `Box` as receiver but is called with a `SomeStruct` as receiver. 15 | // So the type check should fail. 16 | #[allow(dead_code)] 17 | fn valued(&self) -> u64 { 18 | return self.0; 19 | } 20 | } 21 | 22 | #[allow(dead_code)] 23 | fn main() { 24 | let a: SomeStruct = SomeStruct::new(tasm::tasmlib_io_read_stdin___u64()); 25 | tasm::tasmlib_io_write_to_stdout___u64(a.valued()); // <-- Type check should fail here 26 | return; 27 | } 28 | 29 | #[cfg(test)] 30 | mod test { 31 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 32 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 33 | 34 | #[should_panic] 35 | #[test] 36 | fn ref_struct_typecheck_fail_test() { 37 | let entrypoint = EntrypointLocation::disk("boxed", "ref_struct_typecheck_fail", "main"); 38 | let _test_program = ozk_parsing::compile_for_test(&entrypoint); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/ref_struct_typecheck_succeed_bc_boxed.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | // Since struct is not copy, you cannot just call `&self` methods 4 | // without explicitly creating a `Box` value. 5 | struct NonCopyStruct(u64); 6 | 7 | impl NonCopyStruct { 8 | fn new(value: u64) -> NonCopyStruct { 9 | return NonCopyStruct(value + 0xabcde123u64); 10 | } 11 | 12 | fn valued(&self) -> u64 { 13 | return self.0; 14 | } 15 | } 16 | 17 | #[allow(dead_code)] 18 | fn main() { 19 | let a: NonCopyStruct = NonCopyStruct::new(tasm::tasmlib_io_read_stdin___u64()); 20 | let boxed_a: Box = Box::::new(a); 21 | tasm::tasmlib_io_write_to_stdout___u64(boxed_a.valued()); 22 | return; 23 | } 24 | 25 | #[cfg(test)] 26 | mod test { 27 | use itertools::Itertools; 28 | use rand::random; 29 | use tasm_lib::triton_vm::prelude::*; 30 | 31 | use super::*; 32 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 33 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 34 | use crate::tests_and_benchmarks::ozk::rust_shadows; 35 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 36 | 37 | #[test] 38 | fn ref_struct_typecheck_succeed_bc_boxed_test() { 39 | // Verify that compilation works 40 | let entrypoint = 41 | EntrypointLocation::disk("boxed", "ref_struct_typecheck_succeed_bc_boxed", "main"); 42 | let _test_program = ozk_parsing::compile_for_test(&entrypoint); 43 | 44 | // Test function in Triton VM 45 | let rand: u64 = random::() / 2; 46 | let mut encoded = rand.encode(); 47 | encoded.reverse(); 48 | let stdin = encoded; 49 | let expected_output = (rand + 0xabcde123u64).encode(); 50 | let vm_output = TritonVMTestCase::new(entrypoint) 51 | .with_std_in(stdin.clone()) 52 | .execute() 53 | .unwrap(); 54 | if expected_output != vm_output.public_output { 55 | panic!( 56 | "expected:\n{}\n\ngot:\n{}", 57 | expected_output.iter().join(","), 58 | vm_output.public_output.iter().join(",") 59 | ); 60 | } 61 | 62 | // Test function on host machine 63 | let native_output = 64 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), NonDeterminism::default()); 65 | assert_eq!(native_output, expected_output); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/simple_struct_copy.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::twenty_first::prelude::Digest; 2 | use tasm_lib::twenty_first::prelude::XFieldElement; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[derive(Clone, Copy)] 7 | struct SimpleStruct { 8 | a: u32, 9 | b: Digest, 10 | c: XFieldElement, 11 | } 12 | 13 | fn main() { 14 | let struct_0: SimpleStruct = SimpleStruct { 15 | a: 403, 16 | b: tasm::tasmlib_io_read_stdin___digest(), 17 | c: tasm::tasmlib_io_read_stdin___xfe(), 18 | }; 19 | let boxed_struct_0: Box = Box::::new(struct_0); 20 | tasm::tasmlib_io_write_to_stdout___u32(boxed_struct_0.a); 21 | tasm::tasmlib_io_write_to_stdout___digest(boxed_struct_0.b); 22 | tasm::tasmlib_io_write_to_stdout___xfe(boxed_struct_0.c); 23 | 24 | return; 25 | } 26 | 27 | #[cfg(test)] 28 | mod test { 29 | use tasm_lib::triton_vm::prelude::*; 30 | use tasm_lib::twenty_first::math::other::random_elements; 31 | 32 | use super::*; 33 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 34 | use crate::tests_and_benchmarks::ozk::rust_shadows; 35 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 36 | 37 | #[test] 38 | fn boxed_simple_copy_struct() { 39 | let stdin = random_elements(8); 40 | let native_output = 41 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), NonDeterminism::default()); 42 | 43 | let entrypoint = EntrypointLocation::disk("boxed", "simple_struct_copy", "main"); 44 | let vm_output = TritonVMTestCase::new(entrypoint) 45 | .with_std_in(stdin) 46 | .execute() 47 | .unwrap(); 48 | assert_eq!(native_output, vm_output.public_output); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/tuple_struct_one_element.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | #[derive(Clone, Copy)] 4 | struct TupleStruct1(u128); 5 | 6 | fn main() { 7 | let a: u128 = tasm::tasmlib_io_read_stdin___u128(); 8 | let b: u128 = tasm::tasmlib_io_read_stdin___u128(); 9 | let a_copied: u128 = a; 10 | let ts_a: TupleStruct1 = TupleStruct1(a); 11 | let ts_b: TupleStruct1 = TupleStruct1(b); 12 | let boxed_ts_a: Box = Box::::new(ts_a); 13 | let boxed_ts_b: Box = Box::::new(ts_b); 14 | assert!(a_copied == a); 15 | assert!(ts_a.0 == a); 16 | 17 | let ts_again_a: TupleStruct1 = *boxed_ts_a; 18 | let ts_again_b: TupleStruct1 = *boxed_ts_b; 19 | let b_again: u128 = ts_again_b.0; 20 | let a_again: u128 = ts_again_a.0; 21 | 22 | assert!(a == a_again); 23 | tasm::tasmlib_io_write_to_stdout___u128(a); 24 | tasm::tasmlib_io_write_to_stdout___u128(a_again); 25 | assert!(b == b_again); 26 | 27 | tasm::tasmlib_io_write_to_stdout___u128(b); 28 | tasm::tasmlib_io_write_to_stdout___u128(b_again); 29 | 30 | return; 31 | } 32 | 33 | #[cfg(test)] 34 | mod test { 35 | use itertools::Itertools; 36 | use rand::random; 37 | use tasm_lib::triton_vm::prelude::*; 38 | 39 | use super::*; 40 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 41 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 42 | use crate::tests_and_benchmarks::ozk::rust_shadows; 43 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 44 | 45 | #[test] 46 | fn tuple_struct_test() { 47 | // Test function on host machine 48 | let a: u128 = random(); 49 | let b: u128 = random(); 50 | let mut a_encoded_reverse = a.encode(); 51 | a_encoded_reverse.reverse(); 52 | let mut b_encoded_reverse = b.encode(); 53 | b_encoded_reverse.reverse(); 54 | 55 | let expected_output = [a.encode(), a.encode(), b.encode(), b.encode()].concat(); 56 | let stdin = [a_encoded_reverse, b_encoded_reverse].concat(); 57 | let non_determinism = NonDeterminism::new(vec![]); 58 | let native_output = 59 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 60 | assert_eq!(native_output, expected_output); 61 | 62 | // Test function in Triton VM 63 | let entrypoint_location = 64 | EntrypointLocation::disk("boxed", "tuple_struct_one_element", "main"); 65 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 66 | let expected_stack_diff = 0; 67 | println!("test_program:\n{}", test_program.iter().join("\n")); 68 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 69 | &test_program, 70 | vec![], 71 | stdin, 72 | NonDeterminism::new(vec![]), 73 | expected_stack_diff, 74 | ) 75 | .unwrap(); 76 | if expected_output != vm_output.public_output { 77 | panic!( 78 | "expected:\n{}\n\ngot:\n{}", 79 | expected_output.iter().join(","), 80 | vm_output.public_output.iter().join(",") 81 | ); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/tuple_struct_one_element_simple.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Copy)] 2 | struct TupleStruct1(u32); 3 | 4 | fn main() { 5 | let a: u32 = 112; 6 | let ts_a: TupleStruct1 = TupleStruct1(a); 7 | let boxed_ts_a: Box = Box::::new(ts_a); 8 | assert!(ts_a.0 == a); 9 | assert!(boxed_ts_a.0 == a); 10 | 11 | let ts_again_a: TupleStruct1 = *boxed_ts_a; 12 | let a_again: u32 = ts_again_a.0; 13 | assert!(a == a_again); 14 | 15 | return; 16 | } 17 | 18 | #[cfg(test)] 19 | mod test { 20 | use tasm_lib::triton_vm::prelude::NonDeterminism; 21 | 22 | use super::*; 23 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 24 | use crate::tests_and_benchmarks::ozk::rust_shadows; 25 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 26 | 27 | #[test] 28 | fn tuple_struct_one_element_simple_test() { 29 | let native_output = 30 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 31 | 32 | let entrypoint = 33 | EntrypointLocation::disk("boxed", "tuple_struct_one_element_simple", "main"); 34 | let vm_output = TritonVMTestCase::new(entrypoint) 35 | .execute() 36 | .unwrap() 37 | .public_output; 38 | 39 | assert_eq!(native_output, vm_output); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/tuple_struct_two_elements_copy.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | #[derive(Clone, Copy)] 4 | struct TupleStruct2(u32, u32); // TODO: Use (u128, XFieldElement) here instead 5 | 6 | fn main() { 7 | let a: u32 = tasm::tasmlib_io_read_stdin___u32(); 8 | let b: u32 = tasm::tasmlib_io_read_stdin___u32(); 9 | let ts: TupleStruct2 = TupleStruct2(a, b); 10 | let boxed_ts: Box = Box::::new(ts); 11 | assert!(ts.0 == a); 12 | 13 | let ts_again: TupleStruct2 = *boxed_ts; 14 | let b_again: u32 = ts_again.1; 15 | let a_again: u32 = ts_again.0; 16 | 17 | assert!(a == a_again); 18 | tasm::tasmlib_io_write_to_stdout___u32(a); 19 | tasm::tasmlib_io_write_to_stdout___u32(a_again); 20 | assert!(b == b_again); 21 | 22 | tasm::tasmlib_io_write_to_stdout___u32(b); 23 | tasm::tasmlib_io_write_to_stdout___u32(b_again); 24 | 25 | return; 26 | } 27 | 28 | #[cfg(test)] 29 | mod test { 30 | use itertools::Itertools; 31 | use rand::random; 32 | use tasm_lib::triton_vm::prelude::*; 33 | 34 | use super::*; 35 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 36 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 37 | use crate::tests_and_benchmarks::ozk::rust_shadows; 38 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 39 | 40 | #[test] 41 | fn tuple_struct_two_elements_copy_test() { 42 | // Test function on host machine 43 | let a: u32 = random(); 44 | let mut a_encoded_reverse = a.encode(); 45 | a_encoded_reverse.reverse(); 46 | let b: u32 = random(); 47 | let mut b_encoded_reverse = b.encode(); 48 | b_encoded_reverse.reverse(); 49 | 50 | let stdin = [a_encoded_reverse, b_encoded_reverse].concat(); 51 | let non_determinism = NonDeterminism::new(vec![]); 52 | let native_output = 53 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 54 | 55 | // Test function in Triton VM 56 | let entrypoint_location = 57 | EntrypointLocation::disk("boxed", "tuple_struct_two_elements_copy", "main"); 58 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 59 | let expected_stack_diff = 0; 60 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 61 | &test_program, 62 | vec![], 63 | stdin, 64 | NonDeterminism::new(vec![]), 65 | expected_stack_diff, 66 | ); 67 | match vm_output { 68 | Ok(vm_output) => { 69 | if native_output != vm_output.public_output { 70 | panic!( 71 | "expected:\n{}\n\ngot:\n{}\nCode was:\n{}\n", 72 | native_output.iter().join(","), 73 | vm_output.public_output.iter().join(","), 74 | test_program.iter().join("\n"), 75 | ); 76 | } 77 | } 78 | Err(err) => panic!("{err}\n\nCode was:\n{}", test_program.iter().join("\n"),), 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/tuple_struct_two_elements_not_copy.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | #[derive(Clone)] 4 | struct TupleStruct2(u32, u64); // TODO: Use (u128, XFieldElement) here instead 5 | 6 | fn main() { 7 | let a: u32 = tasm::tasmlib_io_read_stdin___u32(); 8 | let b: u64 = tasm::tasmlib_io_read_stdin___u64(); 9 | let ts: TupleStruct2 = TupleStruct2(a, b); 10 | let boxed_ts: Box = Box::::new(ts); 11 | 12 | assert!(a == boxed_ts.0); 13 | assert!(b == boxed_ts.1); 14 | let ts_again: TupleStruct2 = *boxed_ts; 15 | let b_again: u64 = ts_again.1; 16 | let a_again: u32 = ts_again.0; 17 | 18 | assert!(a == a_again); 19 | assert!(b == b_again); 20 | 21 | return; 22 | } 23 | 24 | #[cfg(test)] 25 | mod test { 26 | use itertools::Itertools; 27 | use rand::random; 28 | use tasm_lib::triton_vm::prelude::*; 29 | 30 | use super::*; 31 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 32 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 33 | use crate::tests_and_benchmarks::ozk::rust_shadows; 34 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 35 | 36 | #[test] 37 | fn tuple_struct_two_elements_not_copy_test() { 38 | // Test function on host machine 39 | let a: u32 = random(); 40 | let mut a_encoded_reverse = a.encode(); 41 | a_encoded_reverse.reverse(); 42 | let b: u64 = random(); 43 | let mut b_encoded_reverse = b.encode(); 44 | b_encoded_reverse.reverse(); 45 | 46 | let stdin = [a_encoded_reverse, b_encoded_reverse].concat(); 47 | let non_determinism = NonDeterminism::new(vec![]); 48 | let native_output = 49 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 50 | 51 | // Test function in Triton VM 52 | let entrypoint_location = 53 | EntrypointLocation::disk("boxed", "tuple_struct_two_elements_not_copy", "main"); 54 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 55 | let expected_stack_diff = 0; 56 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 57 | &test_program, 58 | vec![], 59 | stdin, 60 | NonDeterminism::new(vec![]), 61 | expected_stack_diff, 62 | ); 63 | match vm_output { 64 | Ok(vm_output) => { 65 | if native_output != vm_output.public_output { 66 | panic!( 67 | "expected:\n{}\n\ngot:\n{}\nCode was:\n{}\n", 68 | native_output.iter().join(","), 69 | vm_output.public_output.iter().join(","), 70 | test_program.iter().join("\n"), 71 | ); 72 | } 73 | } 74 | Err(err) => panic!("{err}\n\nCode was:\n{}", test_program.iter().join("\n"),), 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/boxed/tuple_struct_with_vec.rs: -------------------------------------------------------------------------------- 1 | use arbitrary::Arbitrary; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[derive(Arbitrary, BFieldCodec, Clone, Debug)] 7 | struct TupleStruct2(Vec, u32); // TODO: Use (u128, XFieldElement) here instead 8 | 9 | fn main() { 10 | let boxed_struct: Box = 11 | TupleStruct2::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap(); 12 | let on_stack: TupleStruct2 = *boxed_struct; 13 | 14 | tasm::tasmlib_io_write_to_stdout___u32(on_stack.1); 15 | tasm::tasmlib_io_write_to_stdout___u32(on_stack.0.len() as u32); 16 | return; 17 | } 18 | 19 | #[cfg(test)] 20 | mod test { 21 | use arbitrary::Unstructured; 22 | use itertools::Itertools; 23 | use rand::random; 24 | 25 | use super::*; 26 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 28 | use crate::tests_and_benchmarks::ozk::rust_shadows; 29 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 30 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 31 | 32 | #[test] 33 | fn move_boxed_tuple_struct_with_vec_test() { 34 | for _ in 0..2 { 35 | let rand: [u8; 100] = random(); 36 | let struct_value = TupleStruct2::arbitrary(&mut Unstructured::new(&rand)).unwrap(); 37 | println!("struct_value: {struct_value:#?}"); 38 | println!( 39 | "struct_value.encoded: {}", 40 | struct_value.encode().iter().join(", ") 41 | ); 42 | let non_determinism = init_memory_from(&struct_value, BFieldElement::new(84)); 43 | { 44 | let mut ram: Vec<(BFieldElement, BFieldElement)> = 45 | non_determinism.ram.clone().into_iter().collect(); 46 | ram.sort_unstable_by_key(|(p, _v)| p.value()); 47 | println!( 48 | "{}", 49 | ram.iter().map(|(p, v)| format!("{p} => {v}")).join(", ") 50 | ); 51 | } 52 | let stdin = vec![]; 53 | 54 | // Run program on host machine 55 | let native_output = 56 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 57 | 58 | // Run test on Triton-VM 59 | let entrypoint_location = 60 | EntrypointLocation::disk("boxed", "tuple_struct_with_vec", "main"); 61 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 62 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 63 | &test_program, 64 | vec![], 65 | stdin, 66 | non_determinism, 67 | 0, 68 | ) 69 | .unwrap(); 70 | if native_output != vm_output.public_output { 71 | panic!( 72 | "native_output:\n{}\nVM output:\n{}. Code was:\n{}\nrand was {}\n", 73 | native_output.iter().join(", "), 74 | vm_output.public_output.iter().join(", "), 75 | test_program.iter().join("\n"), 76 | rand.iter().join(",") 77 | ); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/composite_types.rs: -------------------------------------------------------------------------------- 1 | mod composite_types_from_associated_functions; 2 | mod composite_types_from_methods; 3 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/composite_types/composite_types_from_associated_functions.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | Foo::bar(); 3 | 4 | return; 5 | } 6 | 7 | struct Foo(()); 8 | 9 | impl Foo { 10 | #[allow(clippy::vec_init_then_push)] 11 | fn bar() { 12 | let mut vec: Vec = Vec::::default(); 13 | vec.push(101); 14 | let _array: [u32; 1] = <[u32; 1]>::try_from(vec).unwrap(); 15 | 16 | return; 17 | } 18 | } 19 | 20 | #[cfg(test)] 21 | mod tests { 22 | use tasm_lib::triton_vm::prelude::NonDeterminism; 23 | 24 | use super::*; 25 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 26 | use crate::tests_and_benchmarks::ozk::rust_shadows; 27 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 28 | 29 | #[test] 30 | fn composite_type_associated_function_test() { 31 | let native_output = 32 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 33 | let entrypoint_location = EntrypointLocation::disk( 34 | "composite_types", 35 | "composite_types_from_associated_functions", 36 | "main", 37 | ); 38 | let vm_output = TritonVMTestCase::new(entrypoint_location) 39 | .execute() 40 | .unwrap(); 41 | assert_eq!(native_output, vm_output.public_output); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/composite_types/composite_types_from_methods.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | #[allow(unused_allocation)] 4 | fn main() { 5 | Box::::new(Foo(42)).ref_self_method(); 6 | Foo(43).owned_self_method(); 7 | 8 | return; 9 | } 10 | 11 | struct Foo(u32); 12 | 13 | impl Foo { 14 | #[allow(clippy::vec_init_then_push)] 15 | fn ref_self_method(&self) { 16 | let mut vec: Vec = Vec::::default(); 17 | vec.push(101); 18 | let _array: [u32; 1] = <[u32; 1]>::try_from(vec).unwrap(); 19 | 20 | // print field-0 value to suppress linter-warning 21 | tasm::tasmlib_io_write_to_stdout___u32(self.0); 22 | 23 | return; 24 | } 25 | 26 | #[allow(clippy::vec_init_then_push)] 27 | fn owned_self_method(self) { 28 | let mut vec: Vec = Vec::::default(); 29 | vec.push(101); 30 | let maybe_array: Result<[u32; 1], _> = <[u32; 1]>::try_from(vec); 31 | let array: [u32; 1] = maybe_array.unwrap(); 32 | tasm::tasmlib_io_write_to_stdout___u32(array[0]); 33 | 34 | // print field-0 value to suppress linter-warning 35 | tasm::tasmlib_io_write_to_stdout___u32(self.0); 36 | 37 | return; 38 | } 39 | } 40 | 41 | #[cfg(test)] 42 | mod tests { 43 | use tasm_lib::triton_vm::prelude::NonDeterminism; 44 | 45 | use super::*; 46 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 47 | use crate::tests_and_benchmarks::ozk::rust_shadows; 48 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 49 | 50 | #[test] 51 | fn composite_type_methods_test() { 52 | let native_output = 53 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 54 | let entrypoint_location = 55 | EntrypointLocation::disk("composite_types", "composite_types_from_methods", "main"); 56 | let vm_output = TritonVMTestCase::new(entrypoint_location) 57 | .execute() 58 | .unwrap(); 59 | assert_eq!(native_output, vm_output.public_output); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/destructuring.rs: -------------------------------------------------------------------------------- 1 | mod digest; 2 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/destructuring/digest.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | use crate::twenty_first::prelude::*; 3 | 4 | fn main() { 5 | let digest: Digest = tasm::tasmlib_io_read_stdin___digest(); 6 | let Digest([d0, d1, d2, d3, d4]) = digest; 7 | 8 | tasm::tasmlib_io_write_to_stdout___bfe(d2); 9 | tasm::tasmlib_io_write_to_stdout___bfe(d1); 10 | tasm::tasmlib_io_write_to_stdout___bfe(d4); 11 | tasm::tasmlib_io_write_to_stdout___bfe(d3); 12 | tasm::tasmlib_io_write_to_stdout___bfe(d0); 13 | 14 | return; 15 | } 16 | 17 | #[cfg(test)] 18 | mod tests { 19 | use tasm_lib::twenty_first::math::other::random_elements; 20 | 21 | use super::*; 22 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 23 | use crate::tests_and_benchmarks::ozk::rust_shadows; 24 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 25 | use crate::triton_vm::prelude::*; 26 | 27 | #[test] 28 | fn destructure_digest() { 29 | let entrypoint_location = EntrypointLocation::disk("destructuring", "digest", "main"); 30 | let test_case = TritonVMTestCase::new(entrypoint_location); 31 | let std_in = random_elements(Digest::LEN); 32 | 33 | let native_output = 34 | rust_shadows::wrap_main_with_io(&main)(std_in.clone(), NonDeterminism::default()); 35 | let vm_output = test_case.with_std_in(std_in).execute().unwrap(); 36 | assert_eq!(native_output, vm_output.public_output); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums.rs: -------------------------------------------------------------------------------- 1 | mod box_enum_dyn_sized_variant_field; 2 | mod box_enum_simple; 3 | mod box_enum_two_dyn_sized_variant_fields; 4 | mod boxed_advanced_tuple_data; 5 | mod boxed_match_with_wildcard_binding; 6 | mod boxed_multiple_tuple_data; 7 | mod boxed_multiple_tuple_data_to_stack; 8 | mod boxed_proof_item_simple; 9 | mod custom_struct_in_data; 10 | mod enum_with_non_copy_struct_data; 11 | mod enum_with_struct_data; 12 | mod enum_with_struct_with_two_vecs; 13 | mod match_with_wildcard_bindings; 14 | mod move_boxed_enum_to_stack; 15 | mod rust_by_example_enums; 16 | mod two_variants_no_data; 17 | mod two_variants_one_data; 18 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums/box_enum_dyn_sized_variant_field.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | enum EnumDynSizedVariantField { 6 | A(Vec), 7 | } 8 | 9 | #[allow(clippy::vec_init_then_push)] 10 | fn main() { 11 | let mut bfes: Vec = Vec::::default(); 12 | bfes.push(tasm::tasmlib_io_read_stdin___bfe()); 13 | bfes.push(tasm::tasmlib_io_read_stdin___bfe()); 14 | bfes.push(tasm::tasmlib_io_read_stdin___bfe()); 15 | let a: EnumDynSizedVariantField = EnumDynSizedVariantField::A(bfes); 16 | 17 | let boxed: Box = Box::::new(a); 18 | 19 | match boxed.as_ref() { 20 | EnumDynSizedVariantField::A(bfes_again) => { 21 | tasm::tasmlib_io_write_to_stdout___bfe(bfes_again[2]); 22 | tasm::tasmlib_io_write_to_stdout___bfe(bfes_again[0]); 23 | tasm::tasmlib_io_write_to_stdout___bfe(bfes_again[1]); 24 | tasm::tasmlib_io_write_to_stdout___bfe(bfes_again[1]); 25 | } 26 | }; 27 | 28 | return; 29 | } 30 | 31 | #[cfg(test)] 32 | mod test { 33 | use rand::random; 34 | 35 | use self::tasm::wrap_main_with_io; 36 | use super::*; 37 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 38 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 39 | 40 | #[test] 41 | fn box_enum_dyn_sized_variant_field_test() { 42 | let std_in = vec![random(), random(), random()]; 43 | let native_output = wrap_main_with_io(&main)(std_in.clone(), NonDeterminism::default()); 44 | let entrypoint = 45 | EntrypointLocation::disk("enums", "box_enum_dyn_sized_variant_field", "main"); 46 | let vm_output = TritonVMTestCase::new(entrypoint) 47 | .with_std_in(std_in) 48 | .execute() 49 | .unwrap(); 50 | assert_eq!(native_output, vm_output.public_output); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums/box_enum_simple.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | enum EnumSimple { 4 | A, 5 | B(u128), 6 | } 7 | 8 | /// Verify that boxing an enum works 9 | fn main() { 10 | let a: EnumSimple = EnumSimple::A; 11 | let a_boxed: Box = Box::::new(a); 12 | match a_boxed.as_ref() { 13 | EnumSimple::A => { 14 | tasm::tasmlib_io_write_to_stdout___u32(5); 15 | } 16 | EnumSimple::B(_) => { 17 | panic!(); 18 | } 19 | }; 20 | 21 | let read_from_stdin: u128 = tasm::tasmlib_io_read_stdin___u128(); 22 | let b: EnumSimple = EnumSimple::B(read_from_stdin); 23 | let b_boxed: Box = Box::::new(b); 24 | match b_boxed.as_ref() { 25 | EnumSimple::A => { 26 | panic!(); 27 | } 28 | EnumSimple::B(b_value) => { 29 | assert!(read_from_stdin == *b_value); 30 | tasm::tasmlib_io_write_to_stdout___u128(*b_value); 31 | } 32 | }; 33 | 34 | return; 35 | } 36 | 37 | #[cfg(test)] 38 | mod test { 39 | use rand::random; 40 | use tasm_lib::triton_vm::prelude::*; 41 | 42 | use self::tasm::wrap_main_with_io; 43 | use super::*; 44 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 45 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 46 | 47 | #[test] 48 | fn box_enum_simple_test() { 49 | let stdin: u128 = random(); 50 | let std_in = stdin.encode(); 51 | let native_output = wrap_main_with_io(&main)(std_in.clone(), NonDeterminism::default()); 52 | let entrypoint = EntrypointLocation::disk("enums", "box_enum_simple", "main"); 53 | let vm_output = TritonVMTestCase::new(entrypoint) 54 | .with_std_in(std_in) 55 | .execute() 56 | .unwrap(); 57 | assert_eq!(native_output, vm_output.public_output); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums/boxed_match_with_wildcard_binding.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | #[derive(BFieldCodec)] 6 | pub(crate) enum EnumType { 7 | A(Vec), 8 | B(Vec>), 9 | } 10 | 11 | impl EnumType { 12 | fn discriminant(&self) -> BFieldElement { 13 | #[allow(unused_assignments)] 14 | let mut discriminant: BFieldElement = BFieldElement::new(u32::MAX as u64); 15 | match self { 16 | EnumType::A(_) => { 17 | discriminant = BFieldElement::new(0); 18 | } 19 | EnumType::B(_) => { 20 | discriminant = BFieldElement::new(1); 21 | } 22 | }; 23 | 24 | return discriminant; 25 | } 26 | } 27 | 28 | fn main() { 29 | let boxed_proof_item: Box = 30 | EnumType::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap(); 31 | tasm::tasmlib_io_write_to_stdout___bfe(boxed_proof_item.discriminant()); 32 | 33 | return; 34 | } 35 | 36 | #[cfg(test)] 37 | mod test { 38 | use itertools::Itertools; 39 | use rand::random; 40 | 41 | use super::*; 42 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 43 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 44 | use crate::tests_and_benchmarks::ozk::rust_shadows; 45 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 46 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 47 | 48 | #[test] 49 | fn boxed_match_with_wildcard_binding_test() { 50 | let a_0: Digest = random(); 51 | let proof_item = EnumType::A(vec![a_0]); 52 | let non_determinism = init_memory_from(&proof_item, BFieldElement::new(84)); 53 | let stdin = vec![]; 54 | 55 | // Run test on host machine 56 | let native_output = 57 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 58 | 59 | // Run test on Triton-VM 60 | let entrypoint_location = 61 | EntrypointLocation::disk("enums", "boxed_match_with_wildcard_binding", "main"); 62 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 63 | println!("executing:\n{}", test_program.iter().join("\n")); 64 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 65 | &test_program, 66 | vec![], 67 | stdin, 68 | non_determinism.clone(), 69 | 0, 70 | ) 71 | .unwrap(); 72 | if native_output != vm_output.public_output { 73 | { 74 | let mut ram: Vec<(BFieldElement, BFieldElement)> = 75 | non_determinism.ram.clone().into_iter().collect(); 76 | ram.sort_unstable_by_key(|(p, _v)| p.value()); 77 | println!( 78 | "{}", 79 | ram.iter().map(|(p, v)| format!("{p} => {v}")).join(", ") 80 | ); 81 | } 82 | panic!( 83 | "native_output:\n {}, got:\n{}. Code was:\n{}", 84 | native_output.iter().join(", "), 85 | vm_output.public_output.iter().join(", "), 86 | test_program.iter().join("\n") 87 | ); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums/boxed_multiple_tuple_data.rs: -------------------------------------------------------------------------------- 1 | use arbitrary::Arbitrary; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[derive(Arbitrary, BFieldCodec, Clone, Debug)] 7 | enum EnumType { 8 | A(BFieldElement, BFieldElement), 9 | } 10 | 11 | fn main() { 12 | let boxed_enum_type: Box = 13 | EnumType::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap(); 14 | 15 | match boxed_enum_type.as_ref() { 16 | EnumType::A(elem0, elem1) => { 17 | tasm::tasmlib_io_write_to_stdout___bfe(BFieldElement::new(1)); 18 | tasm::tasmlib_io_write_to_stdout___bfe(*elem0); 19 | tasm::tasmlib_io_write_to_stdout___bfe(*elem1); 20 | } 21 | }; 22 | 23 | return; 24 | } 25 | 26 | #[cfg(test)] 27 | mod test { 28 | use arbitrary::Unstructured; 29 | use itertools::Itertools; 30 | use rand::random; 31 | 32 | use super::*; 33 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 34 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 35 | use crate::tests_and_benchmarks::ozk::rust_shadows; 36 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 37 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 38 | 39 | #[test] 40 | fn boxed_enum_with_multi_tuple_test() { 41 | for _ in 0..2 { 42 | let rand: [u8; 100] = random(); 43 | let enum_value = EnumType::arbitrary(&mut Unstructured::new(&rand)).unwrap(); 44 | let non_determinism = init_memory_from(&enum_value, BFieldElement::new(84)); 45 | let stdin = vec![]; 46 | 47 | // Run program on host machine 48 | let native_output = 49 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 50 | 51 | // Run test on Triton-VM 52 | let entrypoint_location = 53 | EntrypointLocation::disk("enums", "boxed_multiple_tuple_data", "main"); 54 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 55 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 56 | &test_program, 57 | vec![], 58 | stdin, 59 | non_determinism, 60 | 0, 61 | ) 62 | .unwrap(); 63 | if native_output != vm_output.public_output { 64 | panic!( 65 | "native_output:\n{}\nVM output:\n{}. Code was:\n{}\nrand was {}\n", 66 | native_output.iter().join(", "), 67 | vm_output.public_output.iter().join(", "), 68 | test_program.iter().join("\n"), 69 | rand.iter().join(",") 70 | ); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums/boxed_multiple_tuple_data_to_stack.rs: -------------------------------------------------------------------------------- 1 | use arbitrary::Arbitrary; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[derive(Arbitrary, BFieldCodec, Clone, Debug)] 7 | enum EnumType { 8 | A(BFieldElement, BFieldElement), 9 | } 10 | 11 | fn main() { 12 | let b: Box = 13 | EnumType::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap(); 14 | 15 | let on_stack: EnumType = *b; 16 | 17 | match on_stack { 18 | EnumType::A(elem0, elem1) => { 19 | tasm::tasmlib_io_write_to_stdout___bfe(BFieldElement::new(1)); 20 | tasm::tasmlib_io_write_to_stdout___bfe(elem0); 21 | tasm::tasmlib_io_write_to_stdout___bfe(elem1); 22 | } 23 | }; 24 | 25 | return; 26 | } 27 | 28 | #[cfg(test)] 29 | mod test { 30 | use arbitrary::Unstructured; 31 | use itertools::Itertools; 32 | use rand::random; 33 | 34 | use super::*; 35 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 36 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 37 | use crate::tests_and_benchmarks::ozk::rust_shadows; 38 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 39 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 40 | 41 | #[test] 42 | fn boxed_multiple_tuple_data_to_stack_test() { 43 | for _ in 0..2 { 44 | let rand: [u8; 100] = random(); 45 | let enum_value = EnumType::arbitrary(&mut Unstructured::new(&rand)).unwrap(); 46 | let non_determinism = init_memory_from(&enum_value, BFieldElement::new(84)); 47 | let stdin = vec![]; 48 | 49 | // Run program on host machine 50 | let native_output = 51 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 52 | 53 | // Run test on Triton-VM 54 | let entrypoint_location = 55 | EntrypointLocation::disk("enums", "boxed_multiple_tuple_data_to_stack", "main"); 56 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 57 | 58 | { 59 | let mut ram: Vec<(BFieldElement, BFieldElement)> = 60 | non_determinism.ram.clone().into_iter().collect(); 61 | ram.sort_unstable_by_key(|(p, _v)| p.value()); 62 | println!( 63 | "{}", 64 | ram.iter().map(|(p, v)| format!("{p} => {v}")).join(", ") 65 | ); 66 | } 67 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 68 | &test_program, 69 | vec![], 70 | stdin, 71 | non_determinism.clone(), 72 | 0, 73 | ) 74 | .unwrap(); 75 | if native_output != vm_output.public_output { 76 | panic!( 77 | "native_output:\n{}\nVM output:\n{}. Code was:\n{}\nrand was {}\n", 78 | native_output.iter().join(", "), 79 | vm_output.public_output.iter().join(", "), 80 | test_program.iter().join("\n"), 81 | rand.iter().join(",") 82 | ); 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums/custom_struct_in_data.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | struct CustomStruct(u32); 4 | 5 | enum SimpleEnum { 6 | A(CustomStruct), 7 | } 8 | 9 | fn main() { 10 | let a: SimpleEnum = SimpleEnum::A(CustomStruct(100)); 11 | #[allow(unused_assignments)] 12 | let mut output: u32 = 0; 13 | match a { 14 | SimpleEnum::A(value) => { 15 | output = value.0; 16 | } 17 | }; 18 | tasm::tasmlib_io_write_to_stdout___u32(output); 19 | 20 | return; 21 | } 22 | 23 | #[cfg(test)] 24 | mod test { 25 | use itertools::Itertools; 26 | use tasm_lib::triton_vm::prelude::*; 27 | 28 | use super::*; 29 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 30 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 31 | use crate::tests_and_benchmarks::ozk::rust_shadows; 32 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 33 | 34 | #[test] 35 | fn custom_struct_in_enum_data_test() { 36 | let non_determinism = NonDeterminism::default(); 37 | let expected_output = vec![BFieldElement::new(100)]; 38 | let std_in = vec![]; 39 | 40 | // Run test on host machine 41 | let native_output = 42 | rust_shadows::wrap_main_with_io(&main)(std_in.clone(), non_determinism.clone()); 43 | assert_eq!(native_output, expected_output); 44 | 45 | // Run test on Triton-VM 46 | let entrypoint_location = 47 | EntrypointLocation::disk("enums", "custom_struct_in_data", "main"); 48 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 49 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 50 | &test_program, 51 | vec![], 52 | std_in, 53 | non_determinism, 54 | 0, 55 | ) 56 | .unwrap(); 57 | // assert_eq!(expected_output, vm_output.public_output); 58 | if expected_output != vm_output.public_output { 59 | panic!( 60 | "expected_output:\n {}, got:\n{}. Code was:\n{}", 61 | expected_output.iter().join(", "), 62 | vm_output.public_output.iter().join(", "), 63 | test_program.iter().join("\n") 64 | ); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/enums/two_variants_no_data.rs: -------------------------------------------------------------------------------- 1 | pub(crate) enum SimpleEnum { 2 | A, 3 | B, 4 | } 5 | 6 | #[allow(clippy::match_single_binding)] 7 | fn main() { 8 | let a: SimpleEnum = SimpleEnum::A; 9 | let b: SimpleEnum = SimpleEnum::B; 10 | 11 | match a { 12 | SimpleEnum::A => {} 13 | SimpleEnum::B => { 14 | panic!(); 15 | } 16 | }; 17 | 18 | match b { 19 | SimpleEnum::A => { 20 | panic!(); 21 | } 22 | SimpleEnum::B => {} 23 | }; 24 | 25 | match a { 26 | _ => {} 27 | }; 28 | 29 | match a { 30 | SimpleEnum::A => {} 31 | _ => { 32 | panic!(); 33 | } 34 | }; 35 | 36 | return; 37 | } 38 | 39 | #[cfg(test)] 40 | mod test { 41 | use itertools::Itertools; 42 | use tasm_lib::triton_vm::prelude::*; 43 | 44 | use super::*; 45 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 46 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 47 | use crate::tests_and_benchmarks::ozk::rust_shadows; 48 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 49 | 50 | #[test] 51 | fn two_variants_no_data_test() { 52 | // let non_determinism = init_memory_from(&test_struct, BFieldElement::new(300)); 53 | let non_determinism = NonDeterminism::default(); 54 | let expected_output = vec![]; 55 | let std_in = vec![]; 56 | 57 | // Run test on host machine 58 | let native_output = 59 | rust_shadows::wrap_main_with_io(&main)(std_in.clone(), non_determinism.clone()); 60 | assert_eq!(native_output, expected_output); 61 | 62 | // Run test on Triton-VM 63 | let entrypoint_location = EntrypointLocation::disk("enums", "two_variants_no_data", "main"); 64 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 65 | println!("executing:\n{}", test_program.iter().join("\n")); 66 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 67 | &test_program, 68 | vec![], 69 | std_in, 70 | non_determinism, 71 | 0, 72 | ) 73 | .unwrap(); 74 | // assert_eq!(expected_output, vm_output.public_output); 75 | if expected_output != vm_output.public_output { 76 | panic!( 77 | "expected_output:\n {}, got:\n{}. Code was:\n{}", 78 | expected_output.iter().join(", "), 79 | vm_output.public_output.iter().join(", "), 80 | test_program.iter().join("\n") 81 | ); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_expr_boxed.rs: -------------------------------------------------------------------------------- 1 | mod simple_enum_type; 2 | mod very_simple; 3 | mod with_catch_all; 4 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_expr_boxed/simple_enum_type.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | #[derive(BFieldCodec, Clone, Debug)] 4 | pub(super) enum SimpleEnum { 5 | A, 6 | B(BFieldElement), 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_expr_boxed/very_simple.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use super::simple_enum_type::*; 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | fn main() { 7 | let boxed_enum_type: Box = 8 | SimpleEnum::decode(&tasm::load_from_memory(BFieldElement::new(2))).unwrap(); 9 | let evaluated_discriminant: u32 = match boxed_enum_type.as_ref() { 10 | SimpleEnum::A => { 11 | // 12 | 0 13 | } 14 | SimpleEnum::B(inner) => { 15 | // 16 | tasm::tasmlib_io_write_to_stdout___bfe(*inner); 17 | 1 18 | } 19 | }; 20 | 21 | tasm::tasmlib_io_write_to_stdout___u32(evaluated_discriminant); 22 | 23 | return; 24 | } 25 | 26 | #[cfg(test)] 27 | mod test { 28 | use super::*; 29 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 30 | use crate::tests_and_benchmarks::ozk::rust_shadows; 31 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 32 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 33 | 34 | #[test] 35 | fn variant_a_test() { 36 | let variant_a = SimpleEnum::A; 37 | let non_determinism_a = init_memory_from(&variant_a, BFieldElement::new(2)); 38 | let native_output_a = 39 | rust_shadows::wrap_main_with_io(&main)(Vec::default(), non_determinism_a.clone()); 40 | let entrypoint = EntrypointLocation::disk("match_expr_boxed", "very_simple", "main"); 41 | let vm_output_a = TritonVMTestCase::new(entrypoint.clone()) 42 | .with_non_determinism(non_determinism_a) 43 | .execute() 44 | .unwrap(); 45 | assert_eq!(native_output_a, vm_output_a.public_output); 46 | } 47 | 48 | #[test] 49 | fn variant_b_test() { 50 | let variant_b = SimpleEnum::B(BFieldElement::new(12345678901234567890)); 51 | let non_determinism_b = init_memory_from(&variant_b, BFieldElement::new(2)); 52 | let native_output_b = 53 | rust_shadows::wrap_main_with_io(&main)(Vec::default(), non_determinism_b.clone()); 54 | let entrypoint = EntrypointLocation::disk("match_expr_boxed", "very_simple", "main"); 55 | let vm_output_b = TritonVMTestCase::new(entrypoint) 56 | .with_non_determinism(non_determinism_b) 57 | .execute() 58 | .unwrap(); 59 | assert_eq!(native_output_b, vm_output_b.public_output); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_expr_boxed/with_catch_all.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use super::simple_enum_type::*; 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | fn catch_all_on_b() { 7 | let boxed_enum_type: Box = 8 | SimpleEnum::decode(&tasm::load_from_memory(BFieldElement::new(8))).unwrap(); 9 | let evaluated_discriminant: u32 = match boxed_enum_type.as_ref() { 10 | SimpleEnum::A => { 11 | // 12 | 49 13 | } 14 | _ => { 15 | // 16 | 100 17 | } 18 | }; 19 | 20 | tasm::tasmlib_io_write_to_stdout___u32(evaluated_discriminant); 21 | 22 | return; 23 | } 24 | 25 | #[cfg(test)] 26 | mod test { 27 | use itertools::Itertools; 28 | 29 | use super::*; 30 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 31 | use crate::tests_and_benchmarks::ozk::rust_shadows; 32 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 33 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 34 | 35 | #[test] 36 | fn catch_all_on_b_test() { 37 | println!("a"); 38 | let variant_a = SimpleEnum::A; 39 | let non_determinism_a = init_memory_from(&variant_a, BFieldElement::new(8)); 40 | let native_output_a = rust_shadows::wrap_main_with_io(&catch_all_on_b)( 41 | Vec::default(), 42 | non_determinism_a.clone(), 43 | ); 44 | let entrypoint = 45 | EntrypointLocation::disk("match_expr_boxed", "with_catch_all", "catch_all_on_b"); 46 | let code = TritonVMTestCase::new(entrypoint.clone()).compile(); 47 | println!("code:\n{}", code.iter().join("\n")); 48 | let vm_output_a = TritonVMTestCase::new(entrypoint.clone()) 49 | .with_non_determinism(non_determinism_a) 50 | .execute() 51 | .unwrap(); 52 | assert_eq!(native_output_a, vm_output_a.public_output); 53 | 54 | println!("b"); 55 | let variant_b = SimpleEnum::B(BFieldElement::new(12345678901234567890)); 56 | let non_determinism_b = init_memory_from(&variant_b, BFieldElement::new(8)); 57 | let native_output_b = rust_shadows::wrap_main_with_io(&catch_all_on_b)( 58 | Vec::default(), 59 | non_determinism_b.clone(), 60 | ); 61 | let vm_output_b = TritonVMTestCase::new(entrypoint) 62 | .with_non_determinism(non_determinism_b) 63 | .execute() 64 | .unwrap(); 65 | assert_eq!(native_output_b, vm_output_b.public_output); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_expr_on_stack.rs: -------------------------------------------------------------------------------- 1 | mod catch_all_condition; 2 | mod option_type; 3 | mod panic_in_arm_body; 4 | mod three_variants; 5 | mod three_variants_type; 6 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_expr_on_stack/three_variants.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use super::three_variants_type::*; 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[allow(clippy::collapsible_else_if)] 7 | fn main() { 8 | let input: u32 = tasm::tasmlib_io_read_stdin___u32(); 9 | let discriminant: u32 = input % 3; 10 | let val: ThreeVariants = if discriminant == 0 { 11 | ThreeVariants::A 12 | } else { 13 | if discriminant == 1 { 14 | ThreeVariants::B(1u128 << 101) 15 | } else { 16 | ThreeVariants::C(Digest::default()) 17 | } 18 | }; 19 | 20 | let next_variant: ThreeVariants = match val { 21 | ThreeVariants::A => { 22 | tasm::tasmlib_io_write_to_stdout___u32(0); 23 | ThreeVariants::B(303) 24 | } 25 | ThreeVariants::B(_) => { 26 | tasm::tasmlib_io_write_to_stdout___u32(1); 27 | ThreeVariants::C(Digest::default()) 28 | } 29 | ThreeVariants::C(_) => { 30 | tasm::tasmlib_io_write_to_stdout___u32(2); 31 | ThreeVariants::A 32 | } 33 | }; 34 | 35 | let final_discriminant: u32 = match next_variant { 36 | ThreeVariants::A => { 37 | // 38 | tasm::tasmlib_io_write_to_stdout___u32(0); 39 | tasm::tasmlib_io_write_to_stdout___u32(0); 40 | 0 41 | } 42 | ThreeVariants::B(_) => { 43 | // 44 | tasm::tasmlib_io_write_to_stdout___u32(1); 45 | tasm::tasmlib_io_write_to_stdout___u32(1); 46 | 1 47 | } 48 | ThreeVariants::C(_) => { 49 | // 50 | tasm::tasmlib_io_write_to_stdout___u32(2); 51 | tasm::tasmlib_io_write_to_stdout___u32(2); 52 | 2 53 | } 54 | }; 55 | 56 | tasm::tasmlib_io_write_to_stdout___u32(final_discriminant); 57 | 58 | return; 59 | } 60 | 61 | #[cfg(test)] 62 | mod test { 63 | use rand::random; 64 | 65 | use super::*; 66 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 67 | use crate::tests_and_benchmarks::ozk::rust_shadows; 68 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 69 | 70 | #[test] 71 | fn three_variants_test() { 72 | let input: Vec = vec![random()]; 73 | let input: Vec = input 74 | .into_iter() 75 | .map(|x| BFieldElement::new(x as u64)) 76 | .collect(); 77 | let native_output = 78 | rust_shadows::wrap_main_with_io(&main)(input.clone(), NonDeterminism::default()); 79 | let entrypoint = EntrypointLocation::disk("match_expr_on_stack", "three_variants", "main"); 80 | let vm_output = TritonVMTestCase::new(entrypoint) 81 | .with_std_in(input) 82 | .execute() 83 | .unwrap(); 84 | assert_eq!(native_output, vm_output.public_output); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_expr_on_stack/three_variants_type.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | use crate::triton_vm::prelude::Digest; 3 | 4 | pub(super) enum ThreeVariants { 5 | A, 6 | B(u128), 7 | C(Digest), 8 | } 9 | 10 | impl ThreeVariants { 11 | #[allow(clippy::collapsible_else_if)] 12 | pub(super) fn random_from_std_in() -> ThreeVariants { 13 | let input: u32 = tasm::tasmlib_io_read_stdin___u32(); 14 | let discriminant: u32 = input % 3; 15 | return if discriminant == 0 { 16 | ThreeVariants::A 17 | } else { 18 | if discriminant == 1 { 19 | ThreeVariants::B(1u128 << 101) 20 | } else { 21 | ThreeVariants::C(tasm::tasmlib_io_read_stdin___digest()) 22 | } 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_stmt_boxed.rs: -------------------------------------------------------------------------------- 1 | mod set_array_value_from_memory; 2 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/match_stmt_boxed/set_array_value_from_memory.rs: -------------------------------------------------------------------------------- 1 | use num::Zero; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[derive(BFieldCodec, Clone, Debug)] 7 | enum EnumWithArrayData { 8 | A, 9 | B([XFieldElement; 4]), 10 | } 11 | 12 | impl EnumWithArrayData { 13 | pub(crate) fn panic_on_a(&self) -> [XFieldElement; 4] { 14 | #[allow(unused_assignments)] 15 | let mut ood_quotient_segments: [XFieldElement; 4] = [XFieldElement::zero(); 4]; 16 | match self { 17 | EnumWithArrayData::B(xs) => { 18 | ood_quotient_segments = *xs; 19 | } 20 | _ => { 21 | panic!(); 22 | } 23 | }; 24 | 25 | return ood_quotient_segments; 26 | } 27 | } 28 | 29 | fn call_panic_on_a() { 30 | let boxed_enum_type: Box = 31 | EnumWithArrayData::decode(&tasm::load_from_memory(BFieldElement::new(0))).unwrap(); 32 | let array_value: [XFieldElement; 4] = boxed_enum_type.panic_on_a(); 33 | tasm::tasmlib_io_write_to_stdout___xfe(array_value[0]); 34 | tasm::tasmlib_io_write_to_stdout___xfe(array_value[1]); 35 | tasm::tasmlib_io_write_to_stdout___xfe(array_value[2]); 36 | tasm::tasmlib_io_write_to_stdout___xfe(array_value[3]); 37 | 38 | return; 39 | } 40 | 41 | #[cfg(test)] 42 | mod test { 43 | use itertools::Itertools; 44 | 45 | use super::*; 46 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 47 | use crate::tests_and_benchmarks::ozk::rust_shadows; 48 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 49 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 50 | 51 | #[test] 52 | fn call_panic_on_a_variant_b() { 53 | let bfes = (12..=24).map(BFieldElement::new); 54 | let variant_b = EnumWithArrayData::B( 55 | bfes.tuples() 56 | .map(|(i0, i1, i2)| XFieldElement::new([i0, i1, i2])) 57 | .collect_vec() 58 | .try_into() 59 | .unwrap(), 60 | ); 61 | let non_determinism_a = init_memory_from(&variant_b, BFieldElement::new(0)); 62 | let native_output_b = rust_shadows::wrap_main_with_io(&call_panic_on_a)( 63 | Vec::default(), 64 | non_determinism_a.clone(), 65 | ); 66 | let entrypoint = EntrypointLocation::disk( 67 | "match_stmt_boxed", 68 | "set_array_value_from_memory", 69 | "call_panic_on_a", 70 | ); 71 | let vm_output_b = TritonVMTestCase::new(entrypoint.clone()) 72 | .with_non_determinism(non_determinism_a) 73 | .execute() 74 | .unwrap(); 75 | assert_eq!(native_output_b, vm_output_b.public_output); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/neptune_consensus.rs: -------------------------------------------------------------------------------- 1 | mod claims; 2 | mod typescript_timelock; 3 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/neptune_consensus/claims.rs: -------------------------------------------------------------------------------- 1 | mod single_proof_claims; 2 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/option_types.rs: -------------------------------------------------------------------------------- 1 | mod is_some_is_none_unwrap; 2 | mod mutable_values; 3 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/other.rs: -------------------------------------------------------------------------------- 1 | mod hash_varlen; 2 | mod import_type_declaration; 3 | mod nested_tuples; 4 | mod returning_block_expr_u32; 5 | mod simple_encode; 6 | mod simple_map_on_bfe; 7 | mod simple_struct; 8 | mod value; 9 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/other/hash_varlen.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::explicit_auto_deref)] 2 | #![allow(clippy::needless_borrow)] 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | use crate::triton_vm::prelude::*; 6 | 7 | fn main() { 8 | let elements: Box> = 9 | Vec::::decode(&tasm::load_from_memory(BFieldElement::new(2000))).unwrap(); 10 | 11 | let digest: Digest = Tip5::hash_varlen(&(*elements)); 12 | 13 | tasm::tasmlib_io_write_to_stdout___digest(digest); 14 | 15 | return; 16 | } 17 | 18 | #[cfg(test)] 19 | mod test { 20 | use tasm_lib::twenty_first::math::other::random_elements; 21 | 22 | use super::*; 23 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 24 | use crate::tests_and_benchmarks::ozk::rust_shadows; 25 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 26 | 27 | #[test] 28 | fn hash_varlen_test() { 29 | // Test function on host machine 30 | let stdin = vec![]; 31 | let bfe_list = random_elements(111); 32 | let non_determinism = init_memory_from(&bfe_list, 2000u64.into()); 33 | let expected_output = Tip5::hash_varlen(&bfe_list); 34 | let expected_output = expected_output.values().to_vec(); 35 | let native_output = 36 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 37 | assert_eq!(native_output, expected_output); 38 | 39 | // Test function in Triton VM 40 | let entrypoint_location = EntrypointLocation::disk("other", "hash_varlen", "main"); 41 | let rust_ast = entrypoint_location.extract_entrypoint(); 42 | let expected_stack_diff = 0; 43 | let (code, _fn_name) = compile_for_run_test(&rust_ast); 44 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 45 | &code, 46 | vec![], 47 | stdin, 48 | non_determinism, 49 | expected_stack_diff, 50 | ) 51 | .unwrap(); 52 | assert_eq!(expected_output, vm_output.public_output); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/other/import_type_declaration.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use super::simple_struct::*; 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | fn main() { 7 | let ts: Box = 8 | SimpleStruct::decode(&tasm::load_from_memory(BFieldElement::new(300))).unwrap(); 9 | 10 | tasm::tasmlib_io_write_to_stdout___u128(ts.a); 11 | tasm::tasmlib_io_write_to_stdout___bfe(ts.b); 12 | tasm::tasmlib_io_write_to_stdout___bool(ts.c); 13 | tasm::tasmlib_io_write_to_stdout___u32(ts.d.len() as u32); 14 | tasm::tasmlib_io_write_to_stdout___digest(ts.e); 15 | 16 | return; 17 | } 18 | 19 | #[cfg(test)] 20 | mod test { 21 | use arbitrary::Arbitrary; 22 | use arbitrary::Unstructured; 23 | use itertools::Itertools; 24 | use rand::random; 25 | 26 | use super::*; 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 28 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 29 | use crate::tests_and_benchmarks::ozk::rust_shadows; 30 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 31 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 32 | 33 | #[test] 34 | fn import_type_declaration_test() { 35 | let rand: [u8; 2000] = random(); 36 | let test_struct = SimpleStruct::arbitrary(&mut Unstructured::new(&rand)).unwrap(); 37 | let non_determinism = init_memory_from(&test_struct, BFieldElement::new(300)); 38 | let stdin = vec![]; 39 | 40 | // Run test on host machine 41 | let native_output = 42 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 43 | 44 | // Run test on Triton-VM 45 | let entrypoint_location = 46 | EntrypointLocation::disk("other", "import_type_declaration", "main"); 47 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 48 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 49 | &test_program, 50 | vec![], 51 | stdin, 52 | non_determinism, 53 | 0, 54 | ) 55 | .unwrap(); 56 | if native_output != vm_output.public_output { 57 | panic!( 58 | "native_output:\n {}, got:\n{}. Code was:\n{}", 59 | native_output.iter().join(", "), 60 | vm_output.public_output.iter().join(", "), 61 | test_program.iter().join("\n") 62 | ); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/other/returning_block_expr_u32.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | fn main() { 4 | let i: u32 = tasm::tasmlib_io_read_stdin___bfe().value() as u32; 5 | let a: u32 = { 6 | let b: u32 = 100; 7 | let c: u32 = 200; 8 | let j: u32 = tasm::tasmlib_io_read_stdin___bfe().value() as u32; 9 | let k: u32 = tasm::tasmlib_io_read_stdin___bfe().value() as u32; 10 | let d: u32 = 400u32; 11 | 12 | b + c + d + i + j * k 13 | }; 14 | 15 | tasm::tasmlib_io_write_to_stdout___u32(a); 16 | 17 | return; 18 | } 19 | 20 | #[cfg(test)] 21 | mod test { 22 | 23 | use tasm_lib::triton_vm::prelude::*; 24 | 25 | use super::*; 26 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 27 | use crate::tests_and_benchmarks::ozk::rust_shadows; 28 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 29 | 30 | #[test] 31 | fn returning_block_expr_u32_test() { 32 | // Test function on host machine 33 | let i: u32 = 15; 34 | let j: u32 = 16; 35 | let k: u32 = 32; 36 | let stdin = vec![ 37 | BFieldElement::new(i as u64), 38 | BFieldElement::new(j as u64), 39 | BFieldElement::new(k as u64), 40 | ]; 41 | let non_determinism = NonDeterminism::new(vec![]); 42 | let expected_output = vec![BFieldElement::new(100 + 200 + 400 + 15 + 16 * 32)]; 43 | let native_output = 44 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 45 | assert_eq!(native_output, expected_output); 46 | 47 | // Test function in Triton VM 48 | let entrypoint_location = 49 | EntrypointLocation::disk("other", "returning_block_expr_u32", "main"); 50 | let parsed = entrypoint_location.extract_entrypoint(); 51 | let expected_stack_diff = 0; 52 | let vm_output = execute_with_stack_and_ins_safe_lists( 53 | &parsed, 54 | vec![], 55 | stdin, 56 | NonDeterminism::new(vec![]), 57 | expected_stack_diff, 58 | ) 59 | .unwrap(); 60 | assert_eq!(expected_output, vm_output.public_output); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/other/simple_encode.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn main() { 6 | let a: Digest = tasm::tasmlib_io_read_stdin___digest(); 7 | let b: Digest = tasm::tasmlib_io_read_stdin___digest(); 8 | 9 | let a_list: Vec = a.encode(); 10 | let b_list: Vec = b.encode(); 11 | 12 | tasm::tasmlib_io_write_to_stdout___bfe(a_list[3]); 13 | tasm::tasmlib_io_write_to_stdout___bfe(b_list[4]); 14 | tasm::tasmlib_io_write_to_stdout___bfe(a_list[4]); 15 | tasm::tasmlib_io_write_to_stdout___bfe(a_list[1]); 16 | tasm::tasmlib_io_write_to_stdout___bfe(b_list[0]); 17 | 18 | return; 19 | } 20 | 21 | #[cfg(test)] 22 | mod test { 23 | 24 | use tasm_lib::twenty_first::math::other::random_elements; 25 | 26 | use super::*; 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 28 | use crate::tests_and_benchmarks::ozk::rust_shadows; 29 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 30 | 31 | #[test] 32 | fn simple_encode_test() { 33 | // Test function on host machine 34 | let digests: Vec = random_elements(2); 35 | let stdin = [ 36 | digests[0].reversed().encode(), 37 | digests[1].reversed().encode(), 38 | ] 39 | .concat(); 40 | let non_determinism = NonDeterminism::new(vec![]); 41 | let expected_output = vec![ 42 | digests[0].values()[3], 43 | digests[1].values()[4], 44 | digests[0].values()[4], 45 | digests[0].values()[1], 46 | digests[1].values()[0], 47 | ]; 48 | let native_output = 49 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 50 | assert_eq!(native_output, expected_output); 51 | 52 | let entrypoint_location = EntrypointLocation::disk("other", "simple_encode", "main"); 53 | let rust_ast = entrypoint_location.extract_entrypoint(); 54 | let expected_stack_diff = 0; 55 | let vm_output = execute_with_stack_and_ins_safe_lists( 56 | &rust_ast, 57 | vec![], 58 | stdin, 59 | non_determinism, 60 | expected_stack_diff, 61 | ) 62 | .unwrap(); 63 | assert_eq!(expected_output, vm_output.public_output); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/other/simple_struct.rs: -------------------------------------------------------------------------------- 1 | use arbitrary::Arbitrary; 2 | use tasm_lib::prelude::TasmObject; 3 | use tasm_lib::triton_vm::prelude::*; 4 | 5 | #[derive(TasmObject, BFieldCodec, Clone, Arbitrary)] 6 | pub(super) struct SimpleStruct { 7 | pub(crate) a: u128, 8 | pub(crate) b: BFieldElement, 9 | pub(crate) c: bool, 10 | pub(crate) d: Vec, 11 | pub(crate) e: Digest, 12 | } 13 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/other/value.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn main() { 6 | let a: BFieldElement = BFieldElement::new(17u64); 7 | let a_u64: u64 = a.value(); 8 | let b: BFieldElement = BFieldElement::new(a_u64); 9 | tasm::tasmlib_io_write_to_stdout___bfe(b); 10 | 11 | let c: BFieldElement = BFieldElement::new((1 << 32) + 17u64); 12 | let c_u64: u64 = c.value(); 13 | let d: BFieldElement = BFieldElement::new(c_u64); 14 | tasm::tasmlib_io_write_to_stdout___bfe(d); 15 | return; 16 | } 17 | 18 | #[cfg(test)] 19 | mod test { 20 | use tasm_lib::triton_vm::prelude::*; 21 | 22 | use super::*; 23 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 24 | use crate::tests_and_benchmarks::ozk::rust_shadows; 25 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 26 | 27 | #[test] 28 | fn value_test() { 29 | // Test function on host machine 30 | let stdin: Vec = vec![]; 31 | let non_determinism = NonDeterminism::default(); 32 | let native_output = rust_shadows::wrap_main_with_io(&main)(stdin, non_determinism); 33 | 34 | let expected_output = [17, (1 << 32) + 17].map(BFieldElement::new).to_vec(); 35 | assert_eq!(native_output, expected_output); 36 | 37 | let entrypoint = EntrypointLocation::disk("other", "value", "main"); 38 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 39 | 40 | assert_eq!(expected_output, *vm_output.public_output); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/project_euler.rs: -------------------------------------------------------------------------------- 1 | mod pe1; 2 | mod pe2; 3 | mod pe3; 4 | mod pe4; 5 | mod pe5; 6 | mod pe6; 7 | mod pe7; 8 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/project_euler/pe1.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | fn main() { 4 | // https://projecteuler.net/problem=1 5 | let mut i: u32 = 1; 6 | let mut acc: u32 = 0; 7 | 8 | while i < 1000 { 9 | if i % 3 == 0 || i % 5 == 0 { 10 | acc += i; 11 | } 12 | 13 | i += 1; 14 | } 15 | 16 | tasm::tasmlib_io_write_to_stdout___u32(acc); 17 | 18 | return; 19 | } 20 | 21 | #[cfg(test)] 22 | mod test { 23 | use itertools::Itertools; 24 | use tasm_lib::triton_vm::prelude::*; 25 | 26 | use super::*; 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 28 | use crate::tests_and_benchmarks::ozk::rust_shadows; 29 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 30 | 31 | #[test] 32 | fn pe1_test() { 33 | // Test function on host machine 34 | let stdin = vec![]; 35 | let non_determinism = NonDeterminism::default(); 36 | let native_output = 37 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 38 | 39 | let entrypoint = EntrypointLocation::disk("project_euler", "pe1", "main"); 40 | let vm_output = TritonVMTestCase::new(entrypoint) 41 | .with_non_determinism(non_determinism) 42 | .execute() 43 | .unwrap(); 44 | 45 | assert_eq!(native_output, vm_output.public_output); 46 | println!( 47 | "vm_output.public_output: {}", 48 | vm_output.public_output.iter().join(",") 49 | ); 50 | } 51 | } 52 | 53 | mod benches { 54 | use crate::tests_and_benchmarks::benchmarks::execute_and_write_benchmark; 55 | use crate::tests_and_benchmarks::benchmarks::profile; 56 | use crate::tests_and_benchmarks::benchmarks::BenchmarkInput; 57 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 58 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 59 | 60 | #[test] 61 | fn pe1_bench() { 62 | let entrypoint_location = EntrypointLocation::disk("project_euler", "pe1", "main"); 63 | let parsed = entrypoint_location.extract_entrypoint(); 64 | let (code, _) = compile_for_run_test(&parsed); 65 | 66 | let common_case = BenchmarkInput::default(); 67 | let worst_case = BenchmarkInput::default(); 68 | let name = "project_euler_1".to_owned(); 69 | execute_and_write_benchmark(name.clone(), code.clone(), common_case.clone(), worst_case); 70 | profile(name, code, common_case); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/project_euler/pe2.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | fn main() { 4 | // https://projecteuler.net/problem=2 5 | let mut previous: u32 = 1; 6 | let mut current: u32 = 1; 7 | let mut acc: u32 = 0; 8 | while current <= 4_000_000 { 9 | if current % 2 == 0 { 10 | acc += current; 11 | } 12 | 13 | let tmp: u32 = current; 14 | current += previous; 15 | previous = tmp; 16 | } 17 | 18 | tasm::tasmlib_io_write_to_stdout___u32(acc); 19 | 20 | return; 21 | } 22 | 23 | #[cfg(test)] 24 | mod test { 25 | use itertools::Itertools; 26 | use tasm_lib::triton_vm::prelude::*; 27 | 28 | use super::*; 29 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 30 | use crate::tests_and_benchmarks::ozk::rust_shadows; 31 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 32 | 33 | #[test] 34 | fn pe2_test() { 35 | // Test function on host machine 36 | let stdin = vec![]; 37 | let non_determinism = NonDeterminism::default(); 38 | let native_output = rust_shadows::wrap_main_with_io(&main)(stdin, non_determinism); 39 | 40 | let entrypoint = EntrypointLocation::disk("project_euler", "pe2", "main"); 41 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 42 | 43 | assert_eq!(native_output, vm_output.public_output); 44 | assert_eq!(4613732, native_output[0].value()); 45 | 46 | println!( 47 | "vm_output.public_output: {}", 48 | vm_output.public_output.iter().join(",") 49 | ); 50 | } 51 | } 52 | 53 | mod benches { 54 | use crate::tests_and_benchmarks::benchmarks::execute_and_write_benchmark; 55 | use crate::tests_and_benchmarks::benchmarks::profile; 56 | use crate::tests_and_benchmarks::benchmarks::BenchmarkInput; 57 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 58 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 59 | 60 | #[test] 61 | fn pe2_bench() { 62 | let entrypoint_location = EntrypointLocation::disk("project_euler", "pe2", "main"); 63 | let parsed = entrypoint_location.extract_entrypoint(); 64 | let (code, _) = compile_for_run_test(&parsed); 65 | 66 | let common_case = BenchmarkInput::default(); 67 | let worst_case = BenchmarkInput::default(); 68 | let name = "project_euler_2".to_owned(); 69 | execute_and_write_benchmark(name.clone(), code.clone(), common_case.clone(), worst_case); 70 | profile(name, code, common_case); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/project_euler/pe3.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | fn main() { 4 | // https://projecteuler.net/problem=3 5 | 6 | // Notice that the number used on the Project Euler website is `600851475143` 7 | // but we use a smaller number here, since we don't want this test too take 8 | // too long. 9 | // let mut composite_number: u64 = 600851475143; 10 | let mut composite_number: u64 = 600851; 11 | let mut candidate_divisor: u64 = 2; 12 | while candidate_divisor * candidate_divisor <= composite_number { 13 | // Notice that current div mod implementation could be sped up by using 14 | // non-determinism and proving the result instead actually calculating 15 | // the result of the `div_mod` operation as we do here. 16 | if composite_number % candidate_divisor == 0 { 17 | composite_number /= candidate_divisor; 18 | } else { 19 | candidate_divisor += 1; 20 | } 21 | } 22 | 23 | tasm::tasmlib_io_write_to_stdout___u64(composite_number); 24 | 25 | return; 26 | } 27 | 28 | #[cfg(test)] 29 | mod test { 30 | use itertools::Itertools; 31 | use tasm_lib::triton_vm::prelude::*; 32 | 33 | use super::*; 34 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 35 | use crate::tests_and_benchmarks::ozk::rust_shadows; 36 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 37 | 38 | #[test] 39 | fn pe3_test() { 40 | // Test function on host machine 41 | let stdin = vec![]; 42 | let non_determinism = NonDeterminism::default(); 43 | let native_output = rust_shadows::wrap_main_with_io(&main)(stdin, non_determinism); 44 | 45 | let entrypoint = EntrypointLocation::disk("project_euler", "pe3", "main"); 46 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 47 | 48 | assert_eq!(native_output, vm_output.public_output); 49 | println!( 50 | "vm_output.public_output: {}", 51 | vm_output.public_output.iter().join(",") 52 | ); 53 | } 54 | } 55 | 56 | mod benches { 57 | use crate::tests_and_benchmarks::benchmarks::execute_and_write_benchmark; 58 | use crate::tests_and_benchmarks::benchmarks::profile; 59 | use crate::tests_and_benchmarks::benchmarks::BenchmarkInput; 60 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 61 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 62 | 63 | #[test] 64 | fn pe3_bench() { 65 | let entrypoint_location = EntrypointLocation::disk("project_euler", "pe3", "main"); 66 | let parsed = entrypoint_location.extract_entrypoint(); 67 | let (code, _) = compile_for_run_test(&parsed); 68 | 69 | let common_case = BenchmarkInput::default(); 70 | let worst_case = BenchmarkInput::default(); 71 | let name = "project_euler_3_i600851".to_owned(); 72 | execute_and_write_benchmark(name.clone(), code.clone(), common_case.clone(), worst_case); 73 | profile(name, code, common_case); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/project_euler/pe5.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | #[allow(clippy::needless_else)] 4 | fn main() { 5 | // https://projecteuler.net/problem=5 6 | // 2 = 2, 3 = 3, 5 = 5, 6 = 2*3, 7 | // 7 = 7, 8 = 2^3, 9 = 3^2, 10 = 2*5, 11 = 11, 12 = 3*2^2, 13 = 13, 14 = 2*7, 15 = 3 * 5, 8 | // 16 = 2^4, 17 = 17, 18 = 2*3^2, 19 = 19, 20 = 2^2*5 9 | let ret: u32 = 2u32.pow(4) * 3u32.pow(2) * 5 * 7 * 11 * 13 * 17 * 19; 10 | tasm::tasmlib_io_write_to_stdout___u32(ret); 11 | 12 | return; 13 | } 14 | 15 | #[cfg(test)] 16 | mod test { 17 | use itertools::Itertools; 18 | use tasm_lib::triton_vm::prelude::*; 19 | 20 | use super::*; 21 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 22 | use crate::tests_and_benchmarks::ozk::rust_shadows; 23 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 24 | 25 | #[test] 26 | fn pe5_test() { 27 | // Test function on host machine 28 | let stdin = vec![]; 29 | let non_determinism = NonDeterminism::default(); 30 | let native_output = rust_shadows::wrap_main_with_io(&main)(stdin, non_determinism); 31 | 32 | let entrypoint_location = EntrypointLocation::disk("project_euler", "pe5", "main"); 33 | let vm_output = TritonVMTestCase::new(entrypoint_location) 34 | .execute() 35 | .unwrap(); 36 | 37 | assert_eq!(native_output, vm_output.public_output); 38 | println!( 39 | "vm_output.public_output: {}", 40 | vm_output.public_output.iter().join(",") 41 | ); 42 | } 43 | } 44 | 45 | mod benches { 46 | use crate::tests_and_benchmarks::benchmarks::execute_and_write_benchmark; 47 | use crate::tests_and_benchmarks::benchmarks::profile; 48 | use crate::tests_and_benchmarks::benchmarks::BenchmarkInput; 49 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 50 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 51 | 52 | #[test] 53 | fn pe5_bench() { 54 | let entrypoint_location = EntrypointLocation::disk("project_euler", "pe5", "main"); 55 | let parsed = entrypoint_location.extract_entrypoint(); 56 | let (code, _) = compile_for_run_test(&parsed); 57 | 58 | let common_case = BenchmarkInput::default(); 59 | let worst_case = BenchmarkInput::default(); 60 | let name = "project_euler_5".to_owned(); 61 | execute_and_write_benchmark(name.clone(), code.clone(), common_case.clone(), worst_case); 62 | profile(name, code, common_case); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/project_euler/pe6.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | 3 | #[allow(clippy::needless_else)] 4 | fn main() { 5 | // https://projecteuler.net/problem=6 6 | // Let $a = Sum_{i=1}^{100}i**2$, and 7 | // $b = (Sum_{i=1}^{100}i)**2$, then the result is 8 | // $r = b - a$. 9 | 10 | // We know that $Sum_{i=1}^{N}i = N * (N + 1) / 2$, so let's perform that substitution. 11 | // then $b = (N * (N + 1) / 2)**2 = N**2*(N + 1)**2 / 4$. 12 | // The sum of squares in $a$ can be rewritten as: 13 | // $b = N * (N + 1) * (2N + 1) / 6$ 14 | 15 | let n: u32 = 100; 16 | tasm::tasmlib_io_write_to_stdout___u32( 17 | n.pow(2) * (n + 1).pow(2) / 4 - n * (n + 1) * (n * 2 + 1) / 6, 18 | ); 19 | 20 | return; 21 | } 22 | 23 | #[cfg(test)] 24 | mod test { 25 | use itertools::Itertools; 26 | use tasm_lib::triton_vm::prelude::*; 27 | 28 | use super::*; 29 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 30 | use crate::tests_and_benchmarks::ozk::rust_shadows; 31 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 32 | 33 | #[test] 34 | fn pe6_test() { 35 | let stdin = vec![]; 36 | let non_determinism = NonDeterminism::default(); 37 | let native_output = rust_shadows::wrap_main_with_io(&main)(stdin, non_determinism); 38 | 39 | let entrypoint_location = EntrypointLocation::disk("project_euler", "pe6", "main"); 40 | let vm_output = TritonVMTestCase::new(entrypoint_location) 41 | .execute() 42 | .unwrap(); 43 | 44 | assert_eq!(native_output, vm_output.public_output); 45 | println!( 46 | "vm_output.public_output: {}", 47 | vm_output.public_output.iter().join(",") 48 | ); 49 | } 50 | } 51 | 52 | mod benches { 53 | use crate::tests_and_benchmarks::benchmarks::execute_and_write_benchmark; 54 | use crate::tests_and_benchmarks::benchmarks::profile; 55 | use crate::tests_and_benchmarks::benchmarks::BenchmarkInput; 56 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 57 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 58 | 59 | #[test] 60 | fn pe6_bench() { 61 | let entrypoint_location = EntrypointLocation::disk("project_euler", "pe6", "main"); 62 | let parsed = entrypoint_location.extract_entrypoint(); 63 | let (code, _) = compile_for_run_test(&parsed); 64 | 65 | let common_case = BenchmarkInput::default(); 66 | let worst_case = BenchmarkInput::default(); 67 | let name = "project_euler_6".to_owned(); 68 | execute_and_write_benchmark(name.clone(), code.clone(), common_case.clone(), worst_case); 69 | profile(name, code, common_case); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/recufier.rs: -------------------------------------------------------------------------------- 1 | mod arithmetic_domain; 2 | pub(crate) mod challenges; 3 | mod eval_arg; 4 | mod fast_ntt; 5 | mod fast_ntt_to_basic_snippet; 6 | mod fri_verify; 7 | mod merkle_root; 8 | mod merkle_root_autogen; 9 | pub(crate) mod stark_parameters; 10 | pub(crate) mod verify; 11 | mod vm_proof_iter_next_as; 12 | mod xfe_ntt_recursive; 13 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/recufier/arithmetic_domain.rs: -------------------------------------------------------------------------------- 1 | use num::One; 2 | use tasm_lib::triton_vm::prelude::*; 3 | use tasm_lib::twenty_first::math::traits::PrimitiveRootOfUnity; 4 | 5 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] 6 | pub(crate) struct ArithmeticDomain { 7 | pub(crate) offset: BFieldElement, 8 | pub(crate) generator: BFieldElement, 9 | pub(crate) length: usize, 10 | } 11 | 12 | impl ArithmeticDomain { 13 | /// Create a new domain with the given length. 14 | /// No offset is applied, but can added through [`with_offset()`](Self::with_offset). 15 | pub(crate) fn of_length(length: usize) -> ArithmeticDomain { 16 | return ArithmeticDomain { 17 | offset: BFieldElement::one(), 18 | generator: ArithmeticDomain::generator_for_length(length as u64), 19 | length, 20 | }; 21 | } 22 | 23 | /// Set the offset of the domain. 24 | pub(crate) fn with_offset(mut self, offset: BFieldElement) -> ArithmeticDomain { 25 | self.offset = offset; 26 | 27 | return self; 28 | } 29 | 30 | /// Derive a generator for a domain of the given length. 31 | /// The domain length must be a power of 2. 32 | pub(crate) fn generator_for_length(domain_length: u64) -> BFieldElement { 33 | fn is_power_of_two(val: u64) -> bool { 34 | return val != 0u64 && (val & (val - 1)) == 0u64; 35 | } 36 | 37 | assert!(0 == domain_length || is_power_of_two(domain_length)); 38 | 39 | return BFieldElement::primitive_root_of_unity(domain_length).unwrap(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/recufier/challenges.rs: -------------------------------------------------------------------------------- 1 | use arbitrary::Arbitrary; 2 | use tasm_lib::twenty_first::math::x_field_element::XFieldElement; 3 | 4 | #[derive(Debug, Clone, Arbitrary)] 5 | pub(crate) struct Challenges { 6 | #[allow(dead_code)] 7 | // Value is never read, since the position of `Challenges` in memory is statically known. 8 | // Therefore, we need to ignore the linter warning here. 9 | pub challenges: [XFieldElement; 63], 10 | } 11 | 12 | impl Challenges { 13 | pub(crate) const fn count() -> usize { 14 | return 63; 15 | } 16 | } 17 | 18 | #[cfg(test)] 19 | mod tests { 20 | use super::*; 21 | use crate::triton_vm; 22 | 23 | #[test] 24 | fn local_challenges_count_agrees_with_tvm() { 25 | assert_eq!( 26 | triton_vm::challenges::Challenges::COUNT, 27 | Challenges::count() 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/recufier/eval_arg.rs: -------------------------------------------------------------------------------- 1 | use num::One; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[derive(Debug, Clone, Copy, Eq, PartialEq)] 7 | struct EvalArg; 8 | 9 | impl EvalArg { 10 | fn _default_initial() -> XFieldElement { 11 | return XFieldElement::one(); 12 | } 13 | 14 | /// Compute the evaluation for an evaluation argument as specified by `initial`, `challenge`, 15 | /// and `symbols`. This amounts to evaluating polynomial 16 | /// `f(x) = initial·x^n + Σ_i symbols[n-i]·x^i` 17 | /// at point `challenge`, _i.e._, returns `f(challenge)`. 18 | /// Consider using `tasm-lib` snippets directly instead of this code. The `tasm-lib` snippets 19 | /// produce a much shorter execution trace. 20 | fn compute_terminal( 21 | symbols: Vec, 22 | initial: XFieldElement, 23 | challenge: XFieldElement, 24 | ) -> XFieldElement { 25 | let mut acc: XFieldElement = initial; 26 | 27 | let symbols_length: usize = symbols.len(); 28 | let mut i: usize = 0; 29 | while i < symbols_length { 30 | acc = acc * challenge + symbols[i]; 31 | i += 1; 32 | } 33 | 34 | return acc; 35 | } 36 | } 37 | 38 | #[cfg(test)] 39 | mod test { 40 | use rand::Rng; 41 | use tasm_lib::twenty_first::math::other::random_elements; 42 | use tasm_lib::twenty_first::math::x_field_element::EXTENSION_DEGREE; 43 | 44 | use self::tasm::wrap_main_with_io; 45 | use super::*; 46 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 47 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 48 | 49 | fn call_compute_terminal() { 50 | let symbols_length: usize = tasm::tasmlib_io_read_stdin___u32() as usize; 51 | let mut symbols: Vec = Vec::::default(); 52 | 53 | { 54 | let mut i: usize = 0; 55 | while i < symbols_length { 56 | symbols.push(tasm::tasmlib_io_read_stdin___bfe()); 57 | i += 1; 58 | } 59 | } 60 | 61 | let initial: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 62 | let challenge: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 63 | 64 | let terminal: XFieldElement = EvalArg::compute_terminal(symbols, initial, challenge); 65 | tasm::tasmlib_io_write_to_stdout___xfe(terminal); 66 | 67 | return; 68 | } 69 | 70 | #[test] 71 | fn test_eval_arg_compute_terminal() { 72 | let symbols_length: u32 = rand::rng().random_range(0..200); 73 | let std_in = [ 74 | vec![BFieldElement::new(symbols_length as u64)], 75 | random_elements(symbols_length as usize), 76 | random_elements(EXTENSION_DEGREE * 2), 77 | ] 78 | .concat(); 79 | let native_output = 80 | wrap_main_with_io(&call_compute_terminal)(std_in.clone(), NonDeterminism::default()); 81 | let entrypoint = 82 | EntrypointLocation::disk("recufier", "eval_arg", "test::call_compute_terminal"); 83 | let vm_output = TritonVMTestCase::new(entrypoint) 84 | .with_std_in(std_in) 85 | .execute() 86 | .unwrap(); 87 | assert_eq!(native_output, vm_output.public_output); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/recufier/fri_verify.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::prelude::TasmObject; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use super::arithmetic_domain::*; 5 | 6 | #[derive(Debug, Clone, PartialEq, Eq, BFieldCodec, TasmObject)] 7 | struct FriVerify { 8 | pub(crate) expansion_factor: u32, 9 | pub(crate) num_collinearity_checks: u32, 10 | pub(crate) domain_length: u32, 11 | pub(crate) domain_offset: BFieldElement, 12 | domain_generator: BFieldElement, 13 | } 14 | 15 | impl FriVerify { 16 | fn new( 17 | offset: BFieldElement, 18 | domain_length: u32, 19 | expansion_factor: u32, 20 | num_collinearity_checks: u32, 21 | ) -> FriVerify { 22 | let domain: ArithmeticDomain = 23 | ArithmeticDomain::of_length(domain_length as usize).with_offset(offset); 24 | 25 | return FriVerify { 26 | expansion_factor, 27 | num_collinearity_checks, 28 | domain_length, 29 | domain_offset: domain.offset, 30 | domain_generator: domain.generator, 31 | }; 32 | } 33 | } 34 | 35 | #[cfg(test)] 36 | pub(crate) mod test { 37 | use rand::random; 38 | 39 | use super::*; 40 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 41 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 42 | use crate::tests_and_benchmarks::ozk::rust_shadows; 43 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 44 | 45 | fn main() { 46 | let _a: FriVerify = FriVerify::new(BFieldElement::new(7), 32, 4, 3); 47 | 48 | return; 49 | } 50 | 51 | #[test] 52 | fn fri_verify_test() { 53 | // Rust program on host machine 54 | let stdin = vec![random(), random(), random(), random()]; 55 | let non_determinism = NonDeterminism::default(); 56 | let native_output = 57 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 58 | 59 | // Run test on Triton-VM 60 | let entrypoint_location = EntrypointLocation::disk("recufier", "fri_verify", "test::main"); 61 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 62 | 63 | let expected_stack_diff = 0; 64 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 65 | &test_program, 66 | vec![], 67 | Default::default(), 68 | Default::default(), 69 | expected_stack_diff, 70 | ) 71 | .unwrap(); 72 | 73 | assert_eq!(native_output, vm_output.public_output); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/recufier/merkle_root_autogen.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test { 3 | use crate::tests_and_benchmarks::ozk::ozk_parsing::compile_to_basic_snippet; 4 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 5 | use crate::twenty_first::prelude::*; 6 | 7 | /// Output the `Merkle root` implementation as a `BasicSnippet` implementation. 8 | #[test] 9 | fn merkle_root_to_basic_snippet() { 10 | let entrypoint_location = 11 | EntrypointLocation::disk("recufier", "merkle_root_autogen", "test::merkle_root"); 12 | let rust_ast = entrypoint_location.extract_entrypoint(); 13 | let as_bs = compile_to_basic_snippet(rust_ast, std::collections::HashMap::default()); 14 | println!("{as_bs}"); 15 | } 16 | 17 | #[allow(clippy::ptr_arg)] 18 | #[allow(dead_code)] 19 | fn merkle_root(leafs: &Vec, start: usize, stop: usize) -> Digest { 20 | // #[allow(unused_assignments)] 21 | // let mut result: Digest = Digest::default(); 22 | let result: Digest = if stop == start + 1usize { 23 | leafs[start] 24 | } else { 25 | let half: usize = (stop - start) / 2; 26 | let left: Digest = merkle_root(leafs, start, stop - half); 27 | let right: Digest = merkle_root(leafs, start + half, stop); 28 | Tip5::hash_pair(left, right) 29 | }; 30 | 31 | return result; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/result_types.rs: -------------------------------------------------------------------------------- 1 | mod copy_types; 2 | mod non_copy_types; 3 | mod prelude_match; 4 | mod question_mark_operator; 5 | mod simple_unwrap; 6 | mod unwrap_crash; 7 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/result_types/non_copy_types.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | #[allow(clippy::vec_init_then_push)] 6 | fn main() { 7 | let bfe_0: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 8 | let bfe_1: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 9 | let mut bfes: Vec = Vec::::default(); 10 | bfes.push(bfe_0); 11 | bfes.push(bfe_1); 12 | let result_bfes: Result, ()> = Ok(bfes); 13 | 14 | match result_bfes { 15 | Result::Ok(bfes) => { 16 | tasm::tasmlib_io_write_to_stdout___bfe(bfes[0]); 17 | tasm::tasmlib_io_write_to_stdout___bfe(bfes[1]); 18 | tasm::tasmlib_io_write_to_stdout___u32(bfes.len() as u32); 19 | } 20 | Result::Err(_) => { 21 | panic!(); 22 | } 23 | }; 24 | 25 | return; 26 | } 27 | 28 | mod test { 29 | use std::default::Default; 30 | 31 | use itertools::Itertools; 32 | use rand::random; 33 | 34 | use super::*; 35 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 36 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 37 | use crate::tests_and_benchmarks::ozk::rust_shadows; 38 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 39 | 40 | #[test] 41 | fn non_copy_types_test() { 42 | let stdin = vec![random(), random()]; 43 | let non_determinism = NonDeterminism::default(); 44 | let native_output = 45 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 46 | let entrypoint_location = 47 | EntrypointLocation::disk("result_types", "non_copy_types", "main"); 48 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 49 | let expected_stack_diff = 0; 50 | println!("test_program:\n{}", test_program.iter().join("\n")); 51 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 52 | &test_program, 53 | vec![], 54 | stdin, 55 | NonDeterminism::default(), 56 | expected_stack_diff, 57 | ) 58 | .unwrap(); 59 | assert_eq!(native_output, vm_output.public_output); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/result_types/prelude_match.rs: -------------------------------------------------------------------------------- 1 | use num::One; 2 | use tasm_lib::twenty_first::prelude::XFieldElement; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | fn main() { 7 | let xfe: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 8 | let good_xfe: Result = Ok(xfe); 9 | 10 | match good_xfe { 11 | Ok(xfe_again) => { 12 | assert!(xfe == xfe_again); 13 | tasm::tasmlib_io_write_to_stdout___xfe(xfe_again); 14 | } 15 | Err(_) => { 16 | panic!(); 17 | } 18 | }; 19 | match good_xfe { 20 | Ok(xfe_again) => { 21 | assert!(xfe == xfe_again); 22 | tasm::tasmlib_io_write_to_stdout___xfe(xfe_again); 23 | } 24 | _ => { 25 | panic!(); 26 | } 27 | }; 28 | 29 | let bad_xfe: Result = Err(()); 30 | match bad_xfe { 31 | Ok(_xfe) => { 32 | panic!(); 33 | } 34 | Err(_) => { 35 | tasm::tasmlib_io_write_to_stdout___xfe(xfe + XFieldElement::one()); 36 | } 37 | }; 38 | 39 | match bad_xfe { 40 | Ok(_xfe) => { 41 | panic!(); 42 | } 43 | _ => { 44 | tasm::tasmlib_io_write_to_stdout___xfe(xfe + XFieldElement::one()); 45 | } 46 | }; 47 | 48 | return; 49 | } 50 | 51 | mod test { 52 | use std::default::Default; 53 | 54 | use rand::random; 55 | use tasm_lib::triton_vm::prelude::*; 56 | 57 | use super::*; 58 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 59 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 60 | use crate::tests_and_benchmarks::ozk::rust_shadows; 61 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 62 | 63 | #[test] 64 | fn prelude_match_test() { 65 | let stdin = vec![random(), random(), random()]; 66 | let non_determinism = NonDeterminism::default(); 67 | let native_output = 68 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 69 | let entrypoint_location = EntrypointLocation::disk("result_types", "prelude_match", "main"); 70 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 71 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 72 | &test_program, 73 | vec![], 74 | stdin, 75 | NonDeterminism::default(), 76 | 0, 77 | ) 78 | .unwrap(); 79 | assert_eq!(native_output, vm_output.public_output); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/result_types/simple_unwrap.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | #[allow(clippy::unnecessary_literal_unwrap)] 6 | fn main() { 7 | let bfe: BFieldElement = BFieldElement::new(500u64); 8 | let result_bfe: Result = Ok(bfe); 9 | let bfe_again: BFieldElement = result_bfe.unwrap(); 10 | assert!(bfe == bfe_again); 11 | 12 | let xfe: XFieldElement = tasm::tasmlib_io_read_stdin___xfe(); 13 | let result_xfe: Result = Ok(xfe); 14 | let xfe_again: XFieldElement = result_xfe.unwrap(); 15 | assert!(xfe == xfe_again); 16 | 17 | let digest: Digest = tasm::tasmlib_io_read_stdin___digest(); 18 | let result_digest: Result = Ok(digest); 19 | let digest_again: Digest = result_digest.unwrap(); 20 | assert!(digest == digest_again); 21 | 22 | return; 23 | } 24 | 25 | mod test { 26 | use std::default::Default; 27 | 28 | use itertools::Itertools; 29 | use tasm_lib::twenty_first::math::other::random_elements; 30 | 31 | use super::*; 32 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 33 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 34 | use crate::tests_and_benchmarks::ozk::rust_shadows; 35 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 36 | 37 | #[test] 38 | fn simple_unwrap_test() { 39 | let stdin = random_elements(8); 40 | let non_determinism = NonDeterminism::default(); 41 | let native_output = 42 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 43 | let entrypoint_location = EntrypointLocation::disk("result_types", "simple_unwrap", "main"); 44 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 45 | let expected_stack_diff = 0; 46 | println!("test_program:\n{}", test_program.iter().join("\n")); 47 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 48 | &test_program, 49 | vec![], 50 | stdin, 51 | NonDeterminism::default(), 52 | expected_stack_diff, 53 | ) 54 | .unwrap(); 55 | assert_eq!(native_output, vm_output.public_output); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/result_types/unwrap_crash.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | #[allow(clippy::unnecessary_literal_unwrap)] 4 | fn _crash_on_unwrap() { 5 | let result_bfe: Result = Err(()); 6 | let _a: BFieldElement = result_bfe.unwrap(); 7 | 8 | return; 9 | } 10 | 11 | #[allow(clippy::needless_question_mark)] 12 | fn _crash_on_try() { 13 | fn inner(input: Result) -> Result { 14 | return Ok(input?); 15 | } 16 | 17 | let _result_bfe: Result = inner(Err(())); 18 | 19 | return; 20 | } 21 | 22 | mod test { 23 | use std::default::Default; 24 | 25 | use tasm_lib::triton_vm::prelude::*; 26 | 27 | use crate::tests_and_benchmarks::ozk::ozk_parsing::compile_for_test; 28 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 29 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 30 | 31 | #[test] 32 | fn unwrap_crash_test() { 33 | let entrypoint_location = 34 | EntrypointLocation::disk("result_types", "unwrap_crash", "_crash_on_unwrap"); 35 | let execution_result = execute_compiled_with_stack_and_ins_for_test( 36 | &compile_for_test(&entrypoint_location), 37 | vec![], 38 | vec![], 39 | NonDeterminism::default(), 40 | 0, 41 | ); 42 | assert!(execution_result.is_err()); 43 | 44 | let entrypoint_location = 45 | EntrypointLocation::disk("result_types", "unwrap_crash", "_crash_on_try"); 46 | let execution_result = execute_compiled_with_stack_and_ins_for_test( 47 | &compile_for_test(&entrypoint_location), 48 | vec![], 49 | vec![], 50 | NonDeterminism::default(), 51 | 0, 52 | ); 53 | assert!(execution_result.is_err()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/sponge_hasher.rs: -------------------------------------------------------------------------------- 1 | mod absorb_once_squeeze_once; 2 | mod init; 3 | mod pad_and_absorb_all; 4 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/sponge_hasher/absorb_once_squeeze_once.rs: -------------------------------------------------------------------------------- 1 | use num::Zero; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | use crate::tests_and_benchmarks::ozk::rust_shadows::Tip5WithState; 5 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 6 | use crate::triton_vm::prelude::*; 7 | 8 | fn absorb_and_squeeze() { 9 | Tip5WithState::init(); 10 | let mut preimage: [BFieldElement; 10] = [BFieldElement::zero(); 10]; 11 | { 12 | let mut i: usize = 0; 13 | while i < 10 { 14 | preimage[i] = tasm::tasmlib_io_read_stdin___bfe(); 15 | i += 1; 16 | } 17 | } 18 | 19 | Tip5WithState::absorb(preimage); 20 | let squeezed: [BFieldElement; 10] = Tip5WithState::squeeze(); 21 | { 22 | let mut i: usize = 0; 23 | while i < 10 { 24 | tasm::tasmlib_io_write_to_stdout___bfe(squeezed[i]); 25 | i += 1; 26 | } 27 | } 28 | 29 | return; 30 | } 31 | 32 | #[cfg(test)] 33 | mod tests { 34 | use itertools::Itertools; 35 | use tasm_lib::triton_vm::prelude::NonDeterminism; 36 | use tasm_lib::twenty_first::math::other::random_elements; 37 | 38 | use super::*; 39 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 40 | use crate::tests_and_benchmarks::ozk::rust_shadows::wrap_main_with_io; 41 | 42 | #[test] 43 | fn absorb_and_squeeze_test() { 44 | let std_in = random_elements(10); 45 | let native_output = 46 | wrap_main_with_io(&absorb_and_squeeze)(std_in.clone(), NonDeterminism::default()); 47 | let entrypoint = EntrypointLocation::disk( 48 | "sponge_hasher", 49 | "absorb_once_squeeze_once", 50 | "absorb_and_squeeze", 51 | ); 52 | let code = TritonVMTestCase::new(entrypoint.clone()).compile(); 53 | println!("code:\n{}", code.iter().join("\n")); 54 | let vm_output = TritonVMTestCase::new(entrypoint) 55 | .with_std_in(std_in) 56 | .execute() 57 | .unwrap(); 58 | assert_eq!(native_output, vm_output.public_output); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/sponge_hasher/init.rs: -------------------------------------------------------------------------------- 1 | use num::Zero; 2 | use tasm_lib::twenty_first::math::other::random_elements; 3 | 4 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 5 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 6 | use crate::tests_and_benchmarks::ozk::rust_shadows::wrap_main_with_io; 7 | use crate::tests_and_benchmarks::ozk::rust_shadows::Tip5WithState; 8 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 9 | use crate::triton_vm::prelude::*; 10 | 11 | fn _main() { 12 | Tip5WithState::init(); 13 | return; 14 | } 15 | 16 | fn initialized_sponge_behaves_correctly_on_small_stack() { 17 | let b: u64 = 100; 18 | Tip5WithState::init(); 19 | let a: u64 = 400; 20 | tasm::tasmlib_io_write_to_stdout___u64(b); 21 | tasm::tasmlib_io_write_to_stdout___u64(a); 22 | return; 23 | } 24 | 25 | fn initialized_sponge_behaves_correctly_deep_in_stack() { 26 | let a: u128 = 100; 27 | let b: u128 = 200; 28 | Tip5WithState::init(); 29 | let mut preimage: [BFieldElement; 10] = [BFieldElement::zero(); 10]; 30 | { 31 | let mut i: usize = 0; 32 | while i < 10 { 33 | preimage[i] = tasm::tasmlib_io_read_stdin___bfe(); 34 | i += 1; 35 | } 36 | } 37 | 38 | let _c: u128 = 300; 39 | let _d: u128 = 400; 40 | let _e: u128 = 500; 41 | let _f: u128 = 600; 42 | let _g: u128 = 700; 43 | let _h: u128 = 800; 44 | let _i: u128 = 900; 45 | let _j: u128 = 1000; 46 | tasm::tasmlib_io_write_to_stdout___u128(b); 47 | tasm::tasmlib_io_write_to_stdout___u128(a); 48 | Tip5WithState::absorb(preimage); 49 | 50 | return; 51 | } 52 | 53 | #[cfg(test)] 54 | mod tests { 55 | use super::*; 56 | 57 | #[test] 58 | fn can_compile_call_to_init() { 59 | let entrypoint = EntrypointLocation::disk("sponge_hasher", "init", "_main"); 60 | TritonVMTestCase::new(entrypoint.clone()).compile(); 61 | } 62 | 63 | #[test] 64 | fn initialized_sponge_behaves_correctly_on_small_stack_test() { 65 | let native_output = wrap_main_with_io(&initialized_sponge_behaves_correctly_on_small_stack)( 66 | Vec::default(), 67 | NonDeterminism::default(), 68 | ); 69 | let entrypoint = EntrypointLocation::disk( 70 | "sponge_hasher", 71 | "init", 72 | "initialized_sponge_behaves_correctly_on_small_stack", 73 | ); 74 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 75 | assert_eq!(native_output, vm_output.public_output); 76 | } 77 | 78 | #[test] 79 | fn initialized_sponge_behaves_correctly_deep_in_stack_test() { 80 | let std_in = random_elements(10); 81 | let native_output = wrap_main_with_io(&initialized_sponge_behaves_correctly_deep_in_stack)( 82 | std_in.clone(), 83 | NonDeterminism::default(), 84 | ); 85 | let entrypoint = EntrypointLocation::disk( 86 | "sponge_hasher", 87 | "init", 88 | "initialized_sponge_behaves_correctly_deep_in_stack", 89 | ); 90 | let vm_output = TritonVMTestCase::new(entrypoint) 91 | .with_std_in(std_in) 92 | .execute() 93 | .unwrap(); 94 | assert_eq!(native_output, vm_output.public_output); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/sponge_hasher/pad_and_absorb_all.rs: -------------------------------------------------------------------------------- 1 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 2 | use crate::tests_and_benchmarks::ozk::rust_shadows::Tip5WithState; 3 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 4 | use crate::triton_vm::prelude::*; 5 | 6 | fn pad_and_absorb_all() { 7 | Tip5WithState::init(); 8 | let input_length: u32 = tasm::tasmlib_io_read_stdin___u32(); 9 | let mut preimage: Vec = Vec::::default(); 10 | { 11 | let mut i: usize = 0; 12 | while i < input_length as usize { 13 | preimage.push(tasm::tasmlib_io_read_stdin___bfe()); 14 | i += 1; 15 | } 16 | } 17 | 18 | Tip5WithState::pad_and_absorb_all(&preimage); 19 | let produce: [BFieldElement; 10] = Tip5WithState::squeeze(); 20 | { 21 | let mut i: usize = 0; 22 | while i < 10 { 23 | tasm::tasmlib_io_write_to_stdout___bfe(produce[i]); 24 | i += 1; 25 | } 26 | } 27 | 28 | return; 29 | } 30 | 31 | #[cfg(test)] 32 | mod tests { 33 | use rand::Rng; 34 | use tasm_lib::triton_vm::prelude::NonDeterminism; 35 | use tasm_lib::twenty_first::math::other::random_elements; 36 | 37 | use super::*; 38 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 39 | use crate::tests_and_benchmarks::ozk::rust_shadows::wrap_main_with_io; 40 | 41 | #[test] 42 | fn pad_and_absorb_all_test() { 43 | let random_length: u32 = rand::rng().random_range(0..200); 44 | let std_in = [ 45 | vec![BFieldElement::new(random_length as u64)], 46 | random_elements(random_length as usize), 47 | ] 48 | .concat(); 49 | let native_output = 50 | wrap_main_with_io(&pad_and_absorb_all)(std_in.clone(), NonDeterminism::default()); 51 | let entrypoint = 52 | EntrypointLocation::disk("sponge_hasher", "pad_and_absorb_all", "pad_and_absorb_all"); 53 | let vm_output = TritonVMTestCase::new(entrypoint) 54 | .with_std_in(std_in) 55 | .execute() 56 | .unwrap(); 57 | assert_eq!(native_output, vm_output.public_output); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/structs.rs: -------------------------------------------------------------------------------- 1 | mod declaration_on_stack_with_list; 2 | mod exceed_allowed_field_size; 3 | mod nested_structs; 4 | mod simple_declaration_on_stack; 5 | mod simple_declaration_on_stack_spilled; 6 | mod simple_nested_struct; 7 | mod simple_struct; 8 | mod struct_with_array; 9 | mod struct_with_methods; 10 | mod struct_with_simple_methods; 11 | mod struct_with_two_vecs_to_stack; 12 | mod struct_with_vecs; 13 | mod struct_with_xfe_and_xfes_to_stack; 14 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/structs/simple_declaration_on_stack.rs: -------------------------------------------------------------------------------- 1 | use num::One; 2 | use tasm_lib::prelude::TasmObject; 3 | use tasm_lib::triton_vm::prelude::*; 4 | 5 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 6 | 7 | #[derive(TasmObject, BFieldCodec)] 8 | struct TestStruct { 9 | a: BFieldElement, 10 | b: BFieldElement, 11 | c: XFieldElement, 12 | d: Digest, 13 | e: bool, 14 | f: u32, 15 | g: u64, 16 | } 17 | 18 | fn main() { 19 | let mut test_struct: TestStruct = TestStruct { 20 | a: BFieldElement::new(14u64 << 40), 21 | b: BFieldElement::new(48u64 << 41), 22 | c: XFieldElement::one(), 23 | d: Digest::new([ 24 | BFieldElement::new(2u64), 25 | BFieldElement::new(4u64), 26 | BFieldElement::new(8u64), 27 | BFieldElement::new(16u64), 28 | BFieldElement::new(32u64), 29 | ]), 30 | e: false, 31 | f: 1 << 22, 32 | g: 1 << 44, 33 | }; 34 | let a: BFieldElement = test_struct.a; 35 | tasm::tasmlib_io_write_to_stdout___bfe(test_struct.a); 36 | tasm::tasmlib_io_write_to_stdout___bfe(a); 37 | tasm::tasmlib_io_write_to_stdout___bfe(test_struct.b); 38 | tasm::tasmlib_io_write_to_stdout___digest(test_struct.d); 39 | 40 | // Change a field value in the struct 41 | test_struct.a = BFieldElement::one(); 42 | tasm::tasmlib_io_write_to_stdout___bfe(test_struct.a); 43 | 44 | return; 45 | } 46 | 47 | #[cfg(test)] 48 | mod test { 49 | use tasm_lib::triton_vm::prelude::*; 50 | 51 | use super::*; 52 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 53 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 54 | use crate::tests_and_benchmarks::ozk::rust_shadows; 55 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 56 | 57 | #[test] 58 | fn simple_struct_declaration_on_stack_test() { 59 | // Test function on host machine 60 | let expected_output = [ 61 | vec![BFieldElement::new(14u64 << 40)], 62 | vec![BFieldElement::new(14u64 << 40)], 63 | vec![BFieldElement::new(48u64 << 41)], 64 | vec![ 65 | BFieldElement::new(2u64), 66 | BFieldElement::new(4u64), 67 | BFieldElement::new(8u64), 68 | BFieldElement::new(16u64), 69 | BFieldElement::new(32u64), 70 | ], 71 | vec![BFieldElement::one()], 72 | ] 73 | .concat(); 74 | let stdin = vec![]; 75 | let non_determinism = NonDeterminism::default(); 76 | 77 | // Run on host machine 78 | let native_output = 79 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 80 | assert_eq!(native_output, expected_output); 81 | 82 | // Run on Triton-VM 83 | let entrypoint_location = 84 | EntrypointLocation::disk("structs", "simple_declaration_on_stack", "main"); 85 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 86 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 87 | &test_program, 88 | vec![], 89 | stdin, 90 | non_determinism, 91 | 0, 92 | ) 93 | .unwrap(); 94 | assert_eq!(expected_output, vm_output.public_output); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/structs/simple_nested_struct.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::prelude::TasmObject; 2 | use tasm_lib::triton_vm::prelude::*; 3 | use tasm_lib::twenty_first::prelude::BFieldCodec; 4 | 5 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 6 | 7 | #[derive(TasmObject, BFieldCodec)] 8 | struct InnerStruct { 9 | b: u32, 10 | } 11 | 12 | #[derive(TasmObject, BFieldCodec)] 13 | struct NestedStruct { 14 | a: InnerStruct, 15 | } 16 | 17 | fn main() { 18 | let test_struct: Box = 19 | NestedStruct::decode(&tasm::load_from_memory(BFieldElement::new(300))).unwrap(); 20 | tasm::tasmlib_io_write_to_stdout___u32(test_struct.a.b); 21 | 22 | return; 23 | } 24 | 25 | #[cfg(test)] 26 | mod test { 27 | use itertools::Itertools; 28 | 29 | use super::*; 30 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 31 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 32 | use crate::tests_and_benchmarks::ozk::rust_shadows; 33 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 34 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 35 | 36 | impl NestedStruct { 37 | fn new(inner_val: u32) -> NestedStruct { 38 | NestedStruct { 39 | a: InnerStruct { b: inner_val }, 40 | } 41 | } 42 | } 43 | 44 | #[test] 45 | fn simple_nested_structs_test() { 46 | let ts = NestedStruct::new(2023); 47 | let non_determinism = init_memory_from(&ts, BFieldElement::new(300)); 48 | 49 | let expected_output = vec![BFieldElement::new(2023)]; 50 | let stdin = vec![]; 51 | let native_output = 52 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 53 | assert_eq!(expected_output, native_output); 54 | 55 | let entrypoint_location = 56 | EntrypointLocation::disk("structs", "simple_nested_struct", "main"); 57 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 58 | println!("executing:\n{}", test_program.iter().join("\n")); 59 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 60 | &test_program, 61 | vec![], 62 | stdin, 63 | non_determinism, 64 | 0, 65 | ) 66 | .unwrap(); 67 | 68 | assert_eq!(expected_output, vm_output.public_output); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/structs/struct_with_simple_methods.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::prelude::TasmObject; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | const SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS: u64 = 2; 7 | 8 | #[derive(TasmObject, BFieldCodec)] 9 | struct TestStruct { 10 | a: BFieldElement, 11 | b: BFieldElement, 12 | c: u32, 13 | d: u64, 14 | } 15 | 16 | impl TestStruct { 17 | fn ab_sum(&self) -> BFieldElement { 18 | return self.a + self.b; 19 | } 20 | 21 | fn cd_sum(&self, other_value: u64) -> u128 { 22 | return self.c as u128 + self.d as u128 + other_value as u128; 23 | } 24 | } 25 | 26 | fn main() { 27 | let test_struct: Box = 28 | TestStruct::decode(&tasm::load_from_memory(BFieldElement::new(2))).unwrap(); 29 | let other_value: u64 = 2023; 30 | tasm::tasmlib_io_write_to_stdout___bfe(test_struct.ab_sum()); 31 | tasm::tasmlib_io_write_to_stdout___u128(test_struct.cd_sum(other_value)); 32 | return; 33 | } 34 | 35 | #[cfg(test)] 36 | mod test { 37 | use rand::random; 38 | use tasm_lib::triton_vm::prelude::*; 39 | 40 | use super::*; 41 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 42 | use crate::tests_and_benchmarks::ozk::rust_shadows; 43 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 44 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 45 | 46 | #[test] 47 | fn basic_struct_method_test() { 48 | let ts = TestStruct { 49 | a: random(), 50 | b: random(), 51 | c: random(), 52 | d: random(), 53 | }; 54 | let non_determinism = init_memory_from( 55 | &ts, 56 | BFieldElement::new(SIMPLE_STRUCTS_BFIELD_CODEC_START_ADDRESS), 57 | ); 58 | let stdin = vec![]; 59 | let native_output = 60 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 61 | 62 | let expected_output = [ts.ab_sum().encode(), ts.cd_sum(2023).encode()].concat(); 63 | assert_eq!(native_output, expected_output); 64 | 65 | let entrypoint = EntrypointLocation::disk("structs", "struct_with_simple_methods", "main"); 66 | let vm_output = TritonVMTestCase::new(entrypoint) 67 | .with_non_determinism(non_determinism) 68 | .execute() 69 | .unwrap(); 70 | 71 | assert_eq!(expected_output, vm_output.public_output); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/structs/struct_with_two_vecs_to_stack.rs: -------------------------------------------------------------------------------- 1 | use arbitrary::Arbitrary; 2 | use tasm_lib::triton_vm::prelude::*; 3 | 4 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 5 | 6 | #[derive(Arbitrary, BFieldCodec, Clone, Debug)] 7 | struct NotCopyStruct { 8 | digests: Vec, 9 | xfes: Vec, 10 | } 11 | 12 | fn main() { 13 | let boxed_enum_type: Box = 14 | NotCopyStruct::decode(&tasm::load_from_memory(BFieldElement::new(84))).unwrap(); 15 | 16 | let on_stack: NotCopyStruct = *boxed_enum_type; 17 | 18 | tasm::tasmlib_io_write_to_stdout___u32(on_stack.digests.len() as u32); 19 | tasm::tasmlib_io_write_to_stdout___u32(on_stack.xfes.len() as u32); 20 | 21 | return; 22 | } 23 | 24 | #[cfg(test)] 25 | mod test { 26 | use arbitrary::Unstructured; 27 | use itertools::Itertools; 28 | use rand::random; 29 | 30 | use super::*; 31 | use crate::tests_and_benchmarks::ozk::ozk_parsing; 32 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 33 | use crate::tests_and_benchmarks::ozk::rust_shadows; 34 | use crate::tests_and_benchmarks::test_helpers::shared_test::execute_compiled_with_stack_and_ins_for_test; 35 | use crate::tests_and_benchmarks::test_helpers::shared_test::init_memory_from; 36 | 37 | #[test] 38 | fn struct_with_two_vecs_to_stack_test() { 39 | for _ in 0..2 { 40 | let rand: [u8; 100] = random(); 41 | let sv = NotCopyStruct::arbitrary(&mut Unstructured::new(&rand)).unwrap(); 42 | let non_determinism = init_memory_from(&sv, BFieldElement::new(84)); 43 | let stdin = vec![]; 44 | 45 | // Run program on host machine 46 | let native_output = 47 | rust_shadows::wrap_main_with_io(&main)(stdin.clone(), non_determinism.clone()); 48 | 49 | // Run test on Triton-VM 50 | let entrypoint_location = 51 | EntrypointLocation::disk("structs", "struct_with_two_vecs_to_stack", "main"); 52 | let test_program = ozk_parsing::compile_for_test(&entrypoint_location); 53 | let vm_output = execute_compiled_with_stack_and_ins_for_test( 54 | &test_program, 55 | vec![], 56 | stdin, 57 | non_determinism.clone(), 58 | 0, 59 | ) 60 | .unwrap(); 61 | if native_output != vm_output.public_output { 62 | { 63 | let mut ram: Vec<(BFieldElement, BFieldElement)> = 64 | non_determinism.ram.clone().into_iter().collect(); 65 | ram.sort_unstable_by_key(|(p, _v)| p.value()); 66 | println!( 67 | "{}", 68 | ram.iter().map(|(p, v)| format!("{p} => {v}")).join(", ") 69 | ); 70 | } 71 | panic!( 72 | "native_output:\n{}\nVM output:\n{}. Code was:\n{}\nrand was {}\ninput was: {sv:#?}", 73 | native_output.iter().join(", "), 74 | vm_output.public_output.iter().join(", "), 75 | test_program.iter().join("\n"), 76 | rand.iter().join(",") 77 | ); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/type_forcing.rs: -------------------------------------------------------------------------------- 1 | mod bfield_element; 2 | mod nested_struct; 3 | mod simple_struct; 4 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/type_forcing/bfield_element.rs: -------------------------------------------------------------------------------- 1 | use tasm_lib::triton_vm::prelude::*; 2 | 3 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 4 | 5 | fn acess_boxed_bfe_value() { 6 | let a: BFieldElement = tasm::tasmlib_io_read_stdin___bfe(); 7 | let a_value: u64 = a.value(); 8 | let boxed: Box = Box::::new(a); 9 | let boxed_value: u64 = boxed.value(); 10 | 11 | assert!(a_value == boxed_value); 12 | 13 | return; 14 | } 15 | 16 | #[cfg(test)] 17 | mod test { 18 | use super::*; 19 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 20 | use crate::tests_and_benchmarks::ozk::rust_shadows; 21 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 22 | 23 | #[test] 24 | fn method_on_boxed_bfe_gets_right_value() { 25 | let std_in = vec![BFieldElement::new(100)]; 26 | let native_output = rust_shadows::wrap_main_with_io(&acess_boxed_bfe_value)( 27 | std_in.clone(), 28 | NonDeterminism::default(), 29 | ); 30 | let entrypoint = 31 | EntrypointLocation::disk("type_forcing", "bfield_element", "acess_boxed_bfe_value"); 32 | let vm_output = TritonVMTestCase::new(entrypoint) 33 | .with_std_in(std_in) 34 | .execute() 35 | .unwrap(); 36 | assert_eq!(native_output, vm_output.public_output); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/type_forcing/nested_struct.rs: -------------------------------------------------------------------------------- 1 | use super::simple_struct::*; 2 | 3 | struct NestedStruct { 4 | my_struct: SimpleStruct, 5 | } 6 | 7 | impl NestedStruct { 8 | fn nested_test_struct() -> NestedStruct { 9 | let my_struct: SimpleStruct = SimpleStruct::test_struct(); 10 | let nested_struct: NestedStruct = NestedStruct { my_struct }; 11 | return nested_struct; 12 | } 13 | } 14 | 15 | fn access_nested_struct_list_len() { 16 | let my_struct: NestedStruct = NestedStruct::nested_test_struct(); 17 | let len: usize = my_struct.my_struct.my_list.len(); 18 | assert!(1 == len); 19 | return; 20 | } 21 | 22 | fn access_boxed_nested_struct_list_len() { 23 | let my_struct: NestedStruct = NestedStruct::nested_test_struct(); 24 | let boxed_struct: Box = Box::::new(my_struct); 25 | let len: usize = boxed_struct.my_struct.my_list.len(); 26 | assert!(1 == len); 27 | return; 28 | } 29 | 30 | #[cfg(test)] 31 | mod tests { 32 | use super::*; 33 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 34 | use crate::tests_and_benchmarks::ozk::rust_shadows; 35 | use crate::tests_and_benchmarks::test_helpers::shared_test::TritonVMTestCase; 36 | use crate::triton_vm::prelude::*; 37 | 38 | #[test] 39 | fn accessing_list_element_on_a_nested_struct_produces_expected_value() { 40 | let native_output = rust_shadows::wrap_main_with_io(&access_nested_struct_list_len)( 41 | vec![], 42 | NonDeterminism::default(), 43 | ); 44 | 45 | let entrypoint = EntrypointLocation::disk( 46 | "type_forcing", 47 | "nested_struct", 48 | "access_nested_struct_list_len", 49 | ); 50 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 51 | assert_eq!(native_output, vm_output.public_output); 52 | } 53 | 54 | #[test] 55 | fn accessing_list_element_on_a_boxed_nested_struct_produces_expected_value() { 56 | let native_output = rust_shadows::wrap_main_with_io(&access_boxed_nested_struct_list_len)( 57 | vec![], 58 | NonDeterminism::default(), 59 | ); 60 | 61 | let entrypoint = EntrypointLocation::disk( 62 | "type_forcing", 63 | "nested_struct", 64 | "access_boxed_nested_struct_list_len", 65 | ); 66 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 67 | assert_eq!(native_output, vm_output.public_output); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/vectors.rs: -------------------------------------------------------------------------------- 1 | mod clone_from_many; 2 | mod clone_from_simple; 3 | mod clone_from_very_simple; 4 | mod split_off; 5 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/vectors/clone_from_many.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test { 3 | use tasm_lib::triton_vm::prelude::*; 4 | 5 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 6 | use crate::tests_and_benchmarks::ozk::rust_shadows; 7 | use crate::tests_and_benchmarks::ozk::rust_shadows as tasm; 8 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 9 | 10 | fn main() { 11 | let mut a: Vec = Vec::::default(); 12 | a.push(BFieldElement::new(100)); 13 | a.push(BFieldElement::new(101)); 14 | 15 | let mut b: Vec = Vec::::default(); 16 | b.clone_from(&a); 17 | b.push(BFieldElement::new(102)); 18 | 19 | let mut c: Vec = Vec::::default(); 20 | c.clone_from(&b); 21 | c.push(BFieldElement::new(103)); 22 | 23 | assert!(2 == a.len()); 24 | assert!(3 == b.len()); 25 | assert!(4 == c.len()); 26 | 27 | tasm::tasmlib_io_write_to_stdout___bfe(a[0]); 28 | tasm::tasmlib_io_write_to_stdout___bfe(a[1]); 29 | 30 | tasm::tasmlib_io_write_to_stdout___bfe(b[0]); 31 | tasm::tasmlib_io_write_to_stdout___bfe(b[1]); 32 | tasm::tasmlib_io_write_to_stdout___bfe(b[2]); 33 | 34 | tasm::tasmlib_io_write_to_stdout___bfe(c[0]); 35 | tasm::tasmlib_io_write_to_stdout___bfe(c[1]); 36 | tasm::tasmlib_io_write_to_stdout___bfe(c[2]); 37 | tasm::tasmlib_io_write_to_stdout___bfe(c[3]); 38 | 39 | a.push(BFieldElement::new(104)); 40 | a.push(BFieldElement::new(105)); 41 | a.push(BFieldElement::new(106)); 42 | 43 | return; 44 | } 45 | 46 | #[test] 47 | fn clone_from_vector_many() { 48 | let native_output = 49 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 50 | let entrypoint = EntrypointLocation::disk("vectors", "clone_from_many", "test::main"); 51 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 52 | assert_eq!(native_output, vm_output.public_output); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/vectors/clone_from_simple.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test { 3 | use tasm_lib::triton_vm::prelude::*; 4 | 5 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 6 | use crate::tests_and_benchmarks::ozk::rust_shadows; 7 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 8 | 9 | #[allow(clippy::vec_init_then_push)] 10 | fn main() { 11 | let mut a: Vec = Vec::::default(); 12 | a.push(BFieldElement::new(102)); 13 | let mut b: Vec = Vec::::default(); 14 | b.clone_from(&a); 15 | assert!(1 == b.len()); 16 | assert!(b[0] == a[0]); 17 | 18 | // Mutating `a` does not mutate b 19 | a[0] = BFieldElement::new(204); 20 | assert!(b[0] != a[0]); 21 | assert!(204 == a[0].value()); 22 | assert!(102 == b[0].value()); 23 | 24 | // Mutating `b` does not mutate a 25 | b.push(BFieldElement::new(103)); 26 | assert!(102 == b[0].value()); 27 | assert!(103 == b[1].value()); 28 | assert!(2 == b.len()); 29 | 30 | return; 31 | } 32 | 33 | #[test] 34 | fn clone_from_vector_simple() { 35 | let native_output = 36 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 37 | let entrypoint = EntrypointLocation::disk("vectors", "clone_from_simple", "test::main"); 38 | let vm_output = TritonVMTestCase::new(entrypoint).execute().unwrap(); 39 | assert_eq!(native_output, vm_output.public_output); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/ozk/programs/vectors/clone_from_very_simple.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod test { 3 | use tasm_lib::triton_vm::prelude::*; 4 | 5 | use crate::tests_and_benchmarks::ozk::ozk_parsing::EntrypointLocation; 6 | use crate::tests_and_benchmarks::ozk::rust_shadows; 7 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 8 | 9 | #[allow(clippy::vec_init_then_push)] 10 | fn main() { 11 | let mut a: Vec = Vec::::default(); 12 | a.push(BFieldElement::new(102)); 13 | let mut b: Vec = Vec::::default(); 14 | b.clone_from(&a); 15 | assert!(1 == b.len()); 16 | 17 | return; 18 | } 19 | 20 | #[test] 21 | fn clone_from_very_simple() { 22 | rust_shadows::wrap_main_with_io(&main)(vec![], NonDeterminism::default()); 23 | let entrypoint = 24 | EntrypointLocation::disk("vectors", "clone_from_very_simple", "test::main"); 25 | TritonVMTestCase::new(entrypoint).execute().unwrap(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/programs.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod arithmetic; 2 | pub(crate) mod bfield_codec; 3 | pub(crate) mod hashing; 4 | pub(crate) mod io; 5 | pub(crate) mod local_functions; 6 | pub(crate) mod mmr; 7 | pub(crate) mod other; 8 | pub(crate) mod spill_to_memory; 9 | pub(crate) mod vectors; 10 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/programs/arithmetic.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod bfe; 2 | pub(crate) mod bool; 3 | pub(crate) mod mixed; 4 | pub(crate) mod u128; 5 | pub(crate) mod u32; 6 | pub(crate) mod u64; 7 | pub(crate) mod xfe; 8 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/programs/arithmetic/mixed.rs: -------------------------------------------------------------------------------- 1 | use syn::parse_quote; 2 | 3 | #[cfg(test)] 4 | mod run_tests { 5 | use super::*; 6 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 7 | 8 | #[test] 9 | fn powers_of_two_with_bit_shifting_test() { 10 | compare_prop_with_stack_safe_lists( 11 | &powers_of_two_with_bit_shifting(), 12 | vec![], 13 | vec![u64_lit((1u64 << 40) + (1u64 << 60))], 14 | ); 15 | 16 | fn powers_of_two_with_bit_shifting() -> syn::ItemFn { 17 | item_fn(parse_quote! { 18 | fn powers_of_two_with_bit_shifting() -> u64 { 19 | let a: u64 = 1 << 40; 20 | let b: u64 = 1 << 60; 21 | let c: u32 = 1000; 22 | let d: u32 = 2000; 23 | let e: (u32, u64) = (2300u32, 4000u64); 24 | return a + b; 25 | } 26 | }) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/programs/vectors.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod basic; 2 | pub(crate) mod map; 3 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/programs/vectors/map.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | use syn::parse_quote; 4 | 5 | use crate::tests_and_benchmarks::test_helpers::shared_test::item_fn; 6 | 7 | fn simple_map_mul_by_2() -> syn::ItemFn { 8 | item_fn(parse_quote! { 9 | fn foo(values: Vec) -> Vec { 10 | fn local_function(input: u64) -> u64 { 11 | return input * 2; 12 | } 13 | let return_values: Vec = values.into_iter().map(local_function).collect_vec(); 14 | 15 | return return_values; 16 | } 17 | }) 18 | } 19 | 20 | mod run_tests { 21 | use std::collections::HashMap; 22 | 23 | use itertools::Itertools; 24 | use tasm_lib::rust_shadowing_helper_functions::list::list_insert; 25 | use tasm_lib::triton_vm::prelude::*; 26 | use tasm_lib::twenty_first::math::other::random_elements; 27 | 28 | use super::*; 29 | use crate::tests_and_benchmarks::test_helpers::shared_test::*; 30 | 31 | #[test] 32 | fn simple_map_mul_by_2_test() { 33 | let mut init_memory = HashMap::default(); 34 | let init_list_u32s: Vec = random_elements(1); 35 | let init_list_u64s: Vec = 36 | init_list_u32s.into_iter().map(|x| x as u64).collect_vec(); 37 | let input_list_pointer = BFieldElement::new(10000); 38 | list_insert(input_list_pointer, init_list_u64s.clone(), &mut init_memory); 39 | 40 | let std_in = vec![]; 41 | let non_determinism = NonDeterminism::default().with_ram(init_memory); 42 | let exec_result = execute_with_stack_and_ins_safe_lists( 43 | &simple_map_mul_by_2(), 44 | vec![bfe_lit(input_list_pointer)], 45 | std_in, 46 | non_determinism, 47 | 0, 48 | ) 49 | .unwrap(); 50 | let list_pointer = exec_result.op_stack.stack.last().unwrap(); 51 | let expected_list = init_list_u64s 52 | .into_iter() 53 | .map(|x| u64_lit(x * 2)) 54 | .collect_vec(); 55 | assert_list_equal(expected_list, *list_pointer, &exec_result.ram); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/tests_and_benchmarks/test_helpers.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod shared_test; 2 | -------------------------------------------------------------------------------- /test_program.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | fn foo(a: BFieldElement, b: BFieldElement) -> BFieldElement { 3 | return a + 2 * b; 4 | } 5 | 6 | let c: BFieldElement = foo(BFieldElement::new(21), BFieldElement::new(10)); 7 | tasm::tasmlib_io_write_to_stdout___bfe(c); 8 | 9 | return; 10 | } 11 | --------------------------------------------------------------------------------