From d5ce90d8584d9e84b276b153d5709af18108d2b5 Mon Sep 17 00:00:00 2001 From: tranduy1dol Date: Mon, 12 Aug 2024 10:44:33 +0000 Subject: [PATCH 1/4] refactor code --- .github/actions/setup_aptos_cli/action.yml | 50 + .github/aptos_cli/config.yml | 7 + .github/aptos_test.yaml | 24 + .github/dependabot.yaml | 6 + Move.toml | 6 +- README.md | 6 +- gas-profiling/kzg-verify_kzg_proof/index.html | 896 +++++++++--------- scripts/verify_kzg_proof.json | 6 +- sources/blob_submission.move | 14 +- sources/components/fact_registry.move | 18 +- .../onchain_data_fact_tree_encoded.move | 35 +- sources/kzg/kzg_helper.move | 25 +- sources/kzg/kzg_verify.move | 57 +- sources/kzg/pre_compile.move | 55 +- sources/kzg/trusted_setup.move | 24 - sources/libs/bytes.move | 32 +- sources/libs/named_storage.move | 51 - sources/starknet_sovereign.move | 55 +- sources/starknet_state.move | 14 +- sources/starknet_storage.move | 33 +- sources/starknet_validity.move | 285 +++--- 21 files changed, 842 insertions(+), 857 deletions(-) create mode 100644 .github/actions/setup_aptos_cli/action.yml create mode 100644 .github/aptos_cli/config.yml create mode 100644 .github/aptos_test.yaml create mode 100644 .github/dependabot.yaml delete mode 100644 sources/kzg/trusted_setup.move delete mode 100644 sources/libs/named_storage.move diff --git a/.github/actions/setup_aptos_cli/action.yml b/.github/actions/setup_aptos_cli/action.yml new file mode 100644 index 0000000..3996604 --- /dev/null +++ b/.github/actions/setup_aptos_cli/action.yml @@ -0,0 +1,50 @@ +name: Setup Aptos CLI +inputs: + version: + require: true + private-key: + require: false + default: "" + public-key: + require: false + default: "" + address: + require: false + default: "" + rpc-url: + require: false + default: "https://fullnode.testnet.aptoslabs.com" + +runs: + using: "composite" + steps: + - name: Download Aptos CLI + uses: robinraju/release-downloader@v1.7 + with: + repository: "aptos-labs/aptos-core" + tag: aptos-cli-v${{ inputs.version }} + fileName: aptos-cli-${{ inputs.version }}-Ubuntu-x86_64.zip + - name: Setup Aptos CLI + shell: bash + run: | + unzip aptos-cli-${{ inputs.version }}-Ubuntu-x86_64.zip + mv ./aptos /usr/local/bin + chmod +x /usr/local/bin/aptos + + - name: Setup Aptos Client + shell: bash + if: ${{ inputs.private-key != '' && inputs.public-key != '' && inputs.address != '' }} + run: | + set -e -o pipefail + + APTOS_CONFIG_DIR="./.aptos/" + mkdir -p "${APTOS_CONFIG_DIR}" + + export APTOS_CONFIG_PATH="${APTOS_CONFIG_DIR}/config.yaml" + + export APTOS_REST_URL="${{ inputs.rpc-url }}" + export APTOS_PRIVATE_KEY="${{ inputs.private-key }}" + export APTOS_PUBLIC_KEY="${{ inputs.public-key }}" + export APTOS_ACCOUNT_ADDRESS="${{ inputs.address }}" + + envsubst < .github/aptos_cli/config.yaml > ${APTOS_CONFIG_PATH} diff --git a/.github/aptos_cli/config.yml b/.github/aptos_cli/config.yml new file mode 100644 index 0000000..a2b424a --- /dev/null +++ b/.github/aptos_cli/config.yml @@ -0,0 +1,7 @@ +--- +profiles: + default: + private_key: "${APTOS_PRIVATE_KEY}" + public_key: "${APTOS_PUBLIC_KEY}" + account: "${APTOS_ACCOUNT_ADDRESS}" + rest_url: "${APTOS_REST_URL}" diff --git a/.github/aptos_test.yaml b/.github/aptos_test.yaml new file mode 100644 index 0000000..90e17ea --- /dev/null +++ b/.github/aptos_test.yaml @@ -0,0 +1,24 @@ +name: Aptos Test + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + # cancel redundant builds on PRs (only on PR, not on branches) + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + aptos_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/setup_aptos_cli + with: + version: 1.0.11 + - name: Test + working-directory: sources + run: aptos move test diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..db66450 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "gitsubmodule" + directory: "/" + schedule: + interval: "daily" diff --git a/Move.toml b/Move.toml index 5ec1d95..defdece 100644 --- a/Move.toml +++ b/Move.toml @@ -4,17 +4,13 @@ version = "1.0.0" authors = [] [addresses] -#local starknet_addr = "0xb50b1b8157ebf7315813c1f745a1e1c68c73111afe2b6761975223d317569b69" -#testnet -#starknet_addr = "0x373904556c31ee071c1853fea9dc2d57383073eb4df55af10bd395471b947bcf" - [dev-addresses] [dependencies.AptosFramework] git = "https://github.com/aptos-labs/aptos-core.git" -rev = "release-v.1.14" +rev = "aptos-release-v1.17" subdir = "aptos-move/framework/aptos-framework" [dev-dependencies] diff --git a/README.md b/README.md index 0ec7c21..ddef798 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ sudo sh get-docker.sh [Reference](https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script) - ## Testing ### Unit @@ -53,7 +52,7 @@ aptos move publish --profile --network local To test the verify_kzg_proof function, run this command: ```bash -aptos move run --json-file .\scripts\verify_kzg_proof.json +aptos move run --json-file .\scripts\verify_kzg_proof.json ## StarkNet Consensus Protocol Contracts @@ -65,4 +64,5 @@ PoC solidity implementation of the following Starknet Decentralized Protocol pro - [IV - Proofs in the Protocol](https://community.starknet.io/t/starknet-decentralized-protocol-iv-proofs-in-the-protocol/6030) - [V - Checkpoints for Fast Finality](https://community.starknet.io/t/starknet-decentralized-protocol-v-checkpoints-for-fast-finality/6032) - [VI - The Buffer Problem](https://community.starknet.io/t/starknet-decentralized-protocol-vi-the-buffer-problem/7098) -- [VII - Chained Proof Protocols & Braiding](https://community.starknet.io/t/starknet-decentralized-protocol-vii-chained-proof-protocols-braiding/18831) \ No newline at end of file +- [VII - Chained Proof Protocols & Braiding](https://community.starknet.io/t/starknet-decentralized-protocol-vii-chained-proof-protocols-braiding/18831) +``` diff --git a/gas-profiling/kzg-verify_kzg_proof/index.html b/gas-profiling/kzg-verify_kzg_proof/index.html index b0d171d..3fb9cb4 100644 --- a/gas-profiling/kzg-verify_kzg_proof/index.html +++ b/gas-profiling/kzg-verify_kzg_proof/index.html @@ -1,462 +1,491 @@ - + - - - - + + + Gas Report - 0x2447-kzg-verify_kzg_proof - + - +
-

Gas Report - 0x2447-kzg-verify_kzg_proof

+

Gas Report - 0x2447-kzg-verify_kzg_proof

-

Flamegraphs

- +

Flamegraphs

+ - (No storage graph to show.) + (No storage graph to show.)
-

Cost Break-down

- The Aptos network charges a transaction in two parts: (1) execution and IO, and (2) storage. - -

Execution & IO

- The execution & IO costs cover the transient resources used for executing the transaction - and are quantified in gas units, meaning that the final fee incurred will be subject to the gas unit - price established by the gas fee market. This allows one to benefit from low transaction fees when - the network is not at capacity. +

Cost Break-down

+ The Aptos network charges a transaction in two parts: (1) execution and + IO, and (2) storage. -

Intrinsic Cost

- 2.76 gas units - , 1.53% of the total cost for execution & IO. +

Execution & IO

+ The execution & IO costs cover the transient resources used for executing + the transaction and are quantified in gas units, meaning that the final + fee incurred will be subject to the gas unit price established by the gas + fee market. This allows one to benefit from low transaction fees when the + network is not at capacity. +

Intrinsic Cost

+ 2.76 gas units , 1.53% of the total cost for execution & IO. -

Dependencies

- - - - - - - - - - - - - - - - - - - - - - - - - -
NameSize in BytesCost in Gas UnitsPercentage
0x2447..::trusted_setup69950.368250.20%
0x2447..::starknet_err21780.1659360.09%
0x2447..::kzg11120.1211640.07%
-

Execution

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperationNumber of HitsCost in Gas UnitsPercentage
0x1::crypto_algebra::pairing_internal<0x1::bls12381_algebra::G1,0x1::bls12381_algebra::G2,0x1::bls12381_algebra::Gt>2110.88368461.38%
0x1::crypto_algebra::scalar_mul_internal<0x1::bls12381_algebra::G2,0x1::bls12381_algebra::Fr>127.66744315.31%
0x1::crypto_algebra::deserialize_internal<0x1::bls12381_algebra::G2,0x1::bls12381_algebra::FormatG2Compr>215.1456188.38%
0x1::crypto_algebra::deserialize_internal<0x1::bls12381_algebra::G1,0x1::bls12381_algebra::FormatG1Compr>311.3544156.28%
0x1::crypto_algebra::scalar_mul_internal<0x1::bls12381_algebra::G1,0x1::bls12381_algebra::Fr>19.2764635.13%
create_ty5010.35640.20%
call_generic650.3299560.18%
ld_const490.2812850.16%
call590.2704660.15%
0x1::crypto_algebra::sub_internal<0x1::bls12381_algebra::G2>10.1208260.07%
move_loc1780.0784980.04%
st_loc1020.0449820.02%
copy_loc490.0418460.02%
0x1::crypto_algebra::sub_internal<0x1::bls12381_algebra::G1>10.0409760.02%
read_ref280.036260.02%
br_false600.026460.01%
imm_borrow_global140.0257320.01%
0x1::event::write_module_event_to_store<0x244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::KZGProofVerification>10.0248860.01%
ret1100.02420.01%
neq140.0208180.01%
vec_len250.02020.01%
pack210.0200550.01%
vec_imm_borrow140.0169820.01%
eq110.0163570.01%
imm_borrow_field_generic210.0154350.01%
vec_pack70.0154350.01%
branch460.0135240.01%
exists_generic140.0128660.01%
imm_borrow_field140.010290.01%
vec_push_back70.0097720.01%
bit_and140.0082320.00%
div140.0082320.00%
lt140.0082320.00%
mod140.0082320.00%
shl140.0082320.00%
ld_u64350.00770.00%
vec_pop_back70.0066850.00%
cast_u8140.0061740.00%
ld_u8280.006160.00%
0x1::crypto_algebra::deserialize_internal<0x1::bls12381_algebra::Fr,0x1::bls12381_algebra::FormatFrLsb>20.0055280.00%
imm_borrow_loc250.00550.00%
mut_borrow_field_generic70.0051450.00%
not70.0041160.00%
mut_borrow_loc140.003080.00%
0x1::crypto_algebra::eq_internal<0x1::bls12381_algebra::Gt>10.0026680.00%
freeze_ref70.0002520.00%
-

State Reads

- - - - - - - - - - - - - -
Resource NameNumber of HitsCost in Gas UnitsPercentage
0x1::features::Features10.9208810.51%
-

Ledger Writes

-
Transaction Itself
- - - - - - - - - -
Cost in Gas UnitsPercentage
0.0257210.01%
-
Events
- - - - - - - - - - - - - -
Event TypeNumber of HitsCost in Gas UnitsPercentage
0x244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::KZGProofVerification10.005340.00%
-
State Write Ops
- (No writes to show.) -

Storage

- The storage fees cover the extended-term storage of states and events and are assessed at a fixed price in APT. +

Dependencies

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameSize in BytesCost in Gas UnitsPercentage
0x2447..::trusted_setup69950.368250.20%
0x2447..::starknet_err21780.1659360.09%
0x2447..::kzg11120.1211640.07%
+

Execution

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperationNumber of HitsCost in Gas UnitsPercentage
+ 0x1::crypto_algebra::pairing_internal<0x1::bls12381_algebra::G1,0x1::bls12381_algebra::G2,0x1::bls12381_algebra::Gt> + 2110.88368461.38%
+ 0x1::crypto_algebra::scalar_mul_internal<0x1::bls12381_algebra::G2,0x1::bls12381_algebra::Fr> + 127.66744315.31%
+ 0x1::crypto_algebra::deserialize_internal<0x1::bls12381_algebra::G2,0x1::bls12381_algebra::FormatG2Compr> + 215.1456188.38%
+ 0x1::crypto_algebra::deserialize_internal<0x1::bls12381_algebra::G1,0x1::bls12381_algebra::FormatG1Compr> + 311.3544156.28%
+ 0x1::crypto_algebra::scalar_mul_internal<0x1::bls12381_algebra::G1,0x1::bls12381_algebra::Fr> + 19.2764635.13%
create_ty5010.35640.20%
call_generic650.3299560.18%
ld_const490.2812850.16%
call590.2704660.15%
+ 0x1::crypto_algebra::sub_internal<0x1::bls12381_algebra::G2> + 10.1208260.07%
move_loc1780.0784980.04%
st_loc1020.0449820.02%
copy_loc490.0418460.02%
+ 0x1::crypto_algebra::sub_internal<0x1::bls12381_algebra::G1> + 10.0409760.02%
read_ref280.036260.02%
br_false600.026460.01%
imm_borrow_global140.0257320.01%
+ 0x1::event::write_module_event_to_store<0x244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::KZGProofVerification> + 10.0248860.01%
ret1100.02420.01%
neq140.0208180.01%
vec_len250.02020.01%
pack210.0200550.01%
vec_imm_borrow140.0169820.01%
eq110.0163570.01%
imm_borrow_field_generic210.0154350.01%
vec_pack70.0154350.01%
branch460.0135240.01%
exists_generic140.0128660.01%
imm_borrow_field140.010290.01%
vec_push_back70.0097720.01%
bit_and140.0082320.00%
div140.0082320.00%
lt140.0082320.00%
mod140.0082320.00%
shl140.0082320.00%
ld_u64350.00770.00%
vec_pop_back70.0066850.00%
cast_u8140.0061740.00%
ld_u8280.006160.00%
+ 0x1::crypto_algebra::deserialize_internal<0x1::bls12381_algebra::Fr,0x1::bls12381_algebra::FormatFrLsb> + 20.0055280.00%
imm_borrow_loc250.00550.00%
mut_borrow_field_generic70.0051450.00%
not70.0041160.00%
mut_borrow_loc140.003080.00%
+ 0x1::crypto_algebra::eq_internal<0x1::bls12381_algebra::Gt> + 10.0026680.00%
freeze_ref70.0002520.00%
+

State Reads

+ + + + + + + + + + + + + +
Resource NameNumber of HitsCost in Gas UnitsPercentage
0x1::features::Features10.9208810.51%
+

Ledger Writes

+
Transaction Itself
+ + + + + + + + + +
Cost in Gas UnitsPercentage
0.0257210.01%
+
Events
+ + + + + + + + + + + + + +
Event TypeNumber of HitsCost in Gas UnitsPercentage
+ 0x244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::KZGProofVerification + 10.005340.00%
+
State Write Ops
+ (No writes to show.) +

Storage

+ The storage fees cover the extended-term storage of states and events and + are assessed at a fixed price in APT. -

Transaction

- 0 APT -

States

- (No state changes to show.) -

Events

- - - - - - - - - - - -
NameCost in APTPercentage
0x244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::KZGProofVerification0/
- +

Transaction

+ 0 APT +

States

+ (No state changes to show.) +

Events

+ + + + + + + + + + + +
NameCost in APTPercentage
+ 0x244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::KZGProofVerification + 0/
-

Full Execution Trace

-
-
execution & IO (gas unit, full trace)                                                                                                                 180.66359     100.00%
+      

Full Execution Trace

+
+
execution & IO (gas unit, full trace)                                                                                                                 180.66359     100.00%
     intrinsic                                                                                                                                         2.76          1.53%
     keyless                                                                                                                                                         
     dependencies                                                                                                                                      0.65535       0.36%
@@ -2264,12 +2293,11 @@ 

Full Execution Trace

0x244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::KZGProofVerification 0.00534 0.00% state write ops
-
+
-

Generated by the Aptos Gas Profiler

+

Generated by the Aptos Gas Profiler

- - - \ No newline at end of file + + diff --git a/scripts/verify_kzg_proof.json b/scripts/verify_kzg_proof.json index 74a57bf..bcd134b 100644 --- a/scripts/verify_kzg_proof.json +++ b/scripts/verify_kzg_proof.json @@ -1,8 +1,6 @@ - { "function_id": "244701fb94617a6c5c59ebf7b0315ebed25cd070819c777a5d437447499afcb8::kzg::verify_kzg_proof", - "type_args": [ - ], + "type_args": [], "args": [ { "type": "hex", @@ -21,4 +19,4 @@ "value": "85d5c5ddc49c8b44bace634bed4dd1c2f3ddc5982b459f702a7756e8896b8f29ae5db9c933ccbb9241af9c01587f3896" } ] -} \ No newline at end of file +} diff --git a/sources/blob_submission.move b/sources/blob_submission.move index 96df279..4f8107a 100644 --- a/sources/blob_submission.move +++ b/sources/blob_submission.move @@ -1,12 +1,15 @@ module starknet_addr::blob_submission { - struct Sidecar has copy, drop, store { sidecar_blob: vector>, sidecar_commitment: vector>, sidecar_proof: vector>, } - public fun new(sidecar_blob: vector>, sidecar_commitment: vector>, sidecar_proof: vector>): Sidecar { + public fun new( + sidecar_blob: vector>, + sidecar_commitment: vector>, + sidecar_proof: vector> + ): Sidecar { return Sidecar { sidecar_blob, sidecar_commitment, @@ -41,11 +44,4 @@ module starknet_addr::blob_submission { public fun default(): Sidecar { return new(vector[x"00"], vector[x"00"], vector[x"00"]) } - - public fun update_sidecar(current_sidecar: &mut Sidecar, new_sidecar: Sidecar) { - // TODO: Improve error handle and verify DA submission handle - current_sidecar.sidecar_blob = new_sidecar.sidecar_blob; - current_sidecar.sidecar_commitment = new_sidecar.sidecar_commitment; - current_sidecar.sidecar_proof = new_sidecar.sidecar_proof; - } } \ No newline at end of file diff --git a/sources/components/fact_registry.move b/sources/components/fact_registry.move index d76a6eb..a902ca2 100644 --- a/sources/components/fact_registry.move +++ b/sources/components/fact_registry.move @@ -1,6 +1,5 @@ // TODO: Add Navori as a dependency module starknet_addr::fact_registry { - use aptos_std::smart_table; use aptos_std::smart_table::{ SmartTable, borrow, upsert, new }; @@ -9,7 +8,7 @@ module starknet_addr::fact_registry { any_fact_registered: bool } - fun init_fact_registry(s: &signer) { + public entry fun init_fact_registry(s: &signer) { move_to(s, VerifierFact { verified_fact: new, bool>(), any_fact_registered: false @@ -23,23 +22,12 @@ module starknet_addr::fact_registry { } #[view] - public fun fast_check(fact: vector): bool acquires VerifierFact { + public fun fact_check(fact: vector): bool acquires VerifierFact { *borrow(&borrow_global(@starknet_addr).verified_fact, fact) } - public entry fun register_fact(signer: &signer, fact_hash: vector) acquires VerifierFact { - if (exists(@starknet_addr) == false) { - init_fact_registry(signer); - }; + public entry fun register_fact(fact_hash: vector) acquires VerifierFact { let verifier_fact = borrow_global_mut(@starknet_addr); upsert(&mut verifier_fact.verified_fact, fact_hash, true); - - if (verifier_fact.any_fact_registered == false) { - verifier_fact.any_fact_registered = true; - } - } - - fun has_registered_fact(): bool acquires VerifierFact { - borrow_global(@starknet_addr).any_fact_registered } } \ No newline at end of file diff --git a/sources/components/onchain_data_fact_tree_encoded.move b/sources/components/onchain_data_fact_tree_encoded.move index aeb20e2..6379114 100644 --- a/sources/components/onchain_data_fact_tree_encoded.move +++ b/sources/components/onchain_data_fact_tree_encoded.move @@ -1,46 +1,45 @@ module starknet_addr::onchain_data_fact_tree_encoded { - + use std::bcs::to_bytes; use std::vector; use aptos_std::aptos_hash::keccak256; use starknet_addr::bytes; - const ONCHAIN_DATA_FACT_ADDITIONAL_WORDS: u64 = 2; - struct DataAvailabilityFact has store, drop { onchain_data_hash: u256, onchain_data_size: u256 } public fun encode_fact_with_onchain_data( - program_output: vector, + program_output: &vector, fact_data: DataAvailabilityFact ): vector { - let main_public_input_length: u256 = (vector::length(&program_output) as u256); - let main_public_input_hash: vector = keccak256(bytes::vec_to_bytes_be(&program_output)); - let buffer = vector::empty(); - vector::append(&mut buffer, main_public_input_hash); - vector::append(&mut buffer, bytes::num_to_bytes_be(&main_public_input_length)); - vector::append(&mut buffer, bytes::num_to_bytes_be(&fact_data.onchain_data_hash)); - vector::append(&mut buffer, bytes::num_to_bytes_be(&(main_public_input_length + fact_data.onchain_data_size))); - let hash_result: vector = keccak256(buffer); + let main_public_input_length: u256 = (vector::length(program_output) as u256); + let main_public_input_hash: vector = keccak256(bytes::vec_to_bytes_be(program_output)); + vector::reverse_append(&mut main_public_input_hash, to_bytes(&main_public_input_length)); + vector::append(&mut main_public_input_hash, bytes::num_to_bytes_be(&fact_data.onchain_data_hash)); + vector::append( + &mut main_public_input_hash, + bytes::num_to_bytes_be(&(main_public_input_length + fact_data.onchain_data_size)) + ); + let hash_result: vector = keccak256(main_public_input_hash); let result = bytes::num_to_bytes_be(&(bytes::u256_from_bytes_be(&hash_result) + 1)); return result } - public fun init_fact_data(onchain_data_hash: u256, onchain_data_size: u256): DataAvailabilityFact { + public fun new(onchain_data_hash: u256, onchain_data_size: u256): DataAvailabilityFact { let fact_data = DataAvailabilityFact { onchain_data_hash, onchain_data_size }; fact_data } #[test] fun test_encode_fact_with_onchain_data() { - let fact_data = init_fact_data( - 4643044994485936859054407373370718990191010183076115682089501129170, - 17360712499668091053135558285859368683200285152058604480060410253312987758592, + let fact_data = new( + 4643044994485936859054407373370718990191010183076115682089501129170u256, + 17360712499668091053135558285859368683200285152058604480060410253312987758592u256, ); - let program_output = vector[ + let program_output: vector = vector[ 1970272326382990453316397420342340810466901058626735958618873840050980391150, 3458474516901043875685413386881507261498565942069144376940366111442758962633, 608891, @@ -51,7 +50,7 @@ module starknet_addr::onchain_data_fact_tree_encoded { 0 ]; - let state_transition_fact = encode_fact_with_onchain_data(program_output, fact_data); + let state_transition_fact = encode_fact_with_onchain_data(&program_output, fact_data); assert!( state_transition_fact == x"9cf790b74003cb773e64dac3fb45f3669c766972eb601d47e331c5ad25fd8e20", 1 diff --git a/sources/kzg/kzg_helper.move b/sources/kzg/kzg_helper.move index 4c28d44..8fb9ac5 100644 --- a/sources/kzg/kzg_helper.move +++ b/sources/kzg/kzg_helper.move @@ -1,32 +1,23 @@ module starknet_addr::kzg_helper { + use std::hash; + use std::vector; + // This line is used for generating constants DO NOT REMOVE! - // 52435875175126190479447740508185965837690552500527637822603658699938581184513 - const BLS_MODULUS: u256 = 52435875175126190479447740508185965837690552500527637822603658699938581184513; - // 0x50005 + // 327685 const EINVALID_KZG_COMMITMENT: u64 = 0x50005; - // b2157d3a40131b14c4c675335465dffde802f0ce5218ad012284d7f275d1b37c - const POINT_EVALUATION_PRECOMPILE_OUTPUT: vector = x"b2157d3a40131b14c4c675335465dffde802f0ce5218ad012284d7f275d1b37c"; // 01 - const VERSIONED_HASH_VERSION_KZG: vector = x"01"; + const VERSIONED_HASH_VERSION_KZG: u8 = 0x1; // End of generating constants! - - use std::hash; - use std::vector; - public fun kzg_to_versioned_hash(commitment: &vector): vector { assert!( vector::length(commitment) == 48, EINVALID_KZG_COMMITMENT ); - let versioned_hash_version_kzg = VERSIONED_HASH_VERSION_KZG; - let hash_commitment = hash::sha2_256(*commitment); - let hash_commitment_silce = vector::slice(&hash_commitment, 1, vector::length(&hash_commitment)); - let result = vector::empty(); - vector::append(&mut result, versioned_hash_version_kzg); - vector::append(&mut result, hash_commitment_silce); + let hash_commitment = hash::sha2_256(*commitment); + *vector::borrow_mut(&mut hash_commitment, 0) = VERSIONED_HASH_VERSION_KZG; - return result + return hash_commitment } } \ No newline at end of file diff --git a/sources/kzg/kzg_verify.move b/sources/kzg/kzg_verify.move index 66db021..7ef49d2 100644 --- a/sources/kzg/kzg_verify.move +++ b/sources/kzg/kzg_verify.move @@ -6,40 +6,27 @@ module starknet_addr::kzg_verify { const BYTES_PER_FIELD_ELEMENT: u64 = 0x20; // 48 const BYTES_PER_PROOF: u64 = 0x30; - // 0x50005 - const EINVALID_KZG_COMMITMENT: u64 = 0x50005; - // 0x50003 + // 327687 + const EINVALID_KZG_COMMITMENT_SIZE: u64 = 0x50007; + // 327683 const EINVALID_KZG_PROOF_SIZE: u64 = 0x50003; - // 0x50006 + // 327686 const EINVALID_Y_VALUE: u64 = 0x50006; - // 0x50007 - const EINVALID_Z_VALUE: u64 = 0x50007; + // 327688 + const EINVALID_Z_VALUE: u64 = 0x50008; + // G1 Generator + const G1_GENERATOR: vector = x"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"; + // G2 secret + const G2S_SETUP: vector = x"b5bfd7dd8cdeb128843bc287230af38926187075cbfbefa81009a2ce615ac53d2914e5870cb452d2afaaab24f3499f72185cbfee53492714734429b7b38608e23926c911cceceac9a36851477ba4c60b087041de621000edc98edada20c1def2"; + // G2 generator + const G2_GENERATOR: vector = x"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"; // End of generating constants! use std::vector; - use aptos_std::bls12381_algebra::{FormatFrLsb, FormatG1Compr, Fr, G1, G2, Gt}; + use aptos_std::bls12381_algebra::{FormatFrLsb, FormatG1Compr, Fr, G1, G2, Gt, FormatG2Compr}; use aptos_std::crypto_algebra::{deserialize, eq, pairing, scalar_mul, sub}; - use aptos_framework::event::emit; - use starknet_addr::trusted_setup; - - #[event] - struct KZGProofVerification has store, drop { - success: bool, - } - - public entry fun verify_kzg_proof( - commitment_bytes: vector, - z: vector, - y: vector, - proof_bytes: vector, - ) { - emit(KZGProofVerification { - success: verify_kzg_proof_impl(commitment_bytes, z, y, proof_bytes) - }); - } - - public fun verify_kzg_proof_impl( + public fun verify_kzg_proof( commitment_bytes: vector, z: vector, y: vector, @@ -47,19 +34,17 @@ module starknet_addr::kzg_verify { ): bool { assert!( vector::length(&commitment_bytes) == BYTES_PER_COMMITMENT, - EINVALID_KZG_COMMITMENT + EINVALID_KZG_COMMITMENT_SIZE ); assert!( vector::length(&proof_bytes) == BYTES_PER_PROOF, EINVALID_KZG_PROOF_SIZE ); assert!( - // Return error invalid field element vector::length(&z) == BYTES_PER_FIELD_ELEMENT, EINVALID_Y_VALUE ); assert!( - // Return error invalid field element vector::length(&y) == BYTES_PER_FIELD_ELEMENT, EINVALID_Z_VALUE ); @@ -69,10 +54,12 @@ module starknet_addr::kzg_verify { let field_commitment = std::option::extract(&mut deserialize(&commitment_bytes)); let field_proof = std::option::extract(&mut deserialize(&proof_bytes)); - let g2s = trusted_setup::get_g2s(); - let g2 = trusted_setup::get_g2(); + let g2s = std::option::extract(&mut deserialize(&G2S_SETUP)); + let g2 = std::option::extract(&mut deserialize(&G2_GENERATOR)); + let g1 = std::option::extract(&mut deserialize(&G1_GENERATOR)); + let a = sub(&g2s, &scalar_mul(&g2, &field_z)); - let b = sub(&field_commitment, &scalar_mul(&trusted_setup::get_g1_generator(), &field_y)); + let b = sub(&field_commitment, &scalar_mul(&g1, &field_y)); let lhs = pairing(&field_proof, &a); let rhs = pairing(&b, &g2); @@ -88,7 +75,7 @@ module starknet_addr::kzg_verify { let proof = x"85d5c5ddc49c8b44bace634bed4dd1c2f3ddc5982b459f702a7756e8896b8f29ae5db9c933ccbb9241af9c01587f3896"; assert!( - !verify_kzg_proof_impl(comitment, z_bytes, y_bytes, proof), + !verify_kzg_proof(comitment, z_bytes, y_bytes, proof), 1 ); } @@ -100,7 +87,7 @@ module starknet_addr::kzg_verify { let z = x"29ef6432c157829fd5a402d6fd6909a502ea73181df1dca79cfd71f42014c505"; let y = x"a5e1b0055dddd20d976ae79ffb584c472911787e3427fa8934991403a516691b"; assert!( - verify_kzg_proof_impl(commitment, z, y, proof), + verify_kzg_proof(commitment, z, y, proof), 1 ); } diff --git a/sources/kzg/pre_compile.move b/sources/kzg/pre_compile.move index d8b792b..311f2a5 100644 --- a/sources/kzg/pre_compile.move +++ b/sources/kzg/pre_compile.move @@ -1,12 +1,21 @@ module starknet_addr::pre_compile { + use std::vector; + + use starknet_addr::bytes; + use starknet_addr::kzg_helper; + use starknet_addr::kzg_verify; + + #[test_only] + use aptos_std::aptos_hash::keccak256; + // This line is used for generating constants DO NOT REMOVE! // 52435875175126190479447740508185965837690552500527637822603658699938581184513 const BLS_MODULUS: u256 = 52435875175126190479447740508185965837690552500527637822603658699938581184513; - // 0x50005 + // 327685 const EINVALID_KZG_COMMITMENT: u64 = 0x50005; - // 0x50004 + // 327684 const EINVALID_PRE_COMPILE_INPUT_SIZE: u64 = 0x50004; - // 0x70002 + // 458754 const EUNEXPECTED_VERSION_HASH: u64 = 0x70002; // 4096 const FIELD_ELEMENTS_PER_BLOB: u256 = 0x1000; @@ -14,29 +23,17 @@ module starknet_addr::pre_compile { const POINT_EVALUATION_PRECOMPILE_OUTPUT: vector = x"b2157d3a40131b14c4c675335465dffde802f0ce5218ad012284d7f275d1b37c"; // End of generating constants! - use std::vector; - - use starknet_addr::bytes; - use starknet_addr::kzg_helper; - use starknet_addr::kzg_verify; - - #[test_only] - use aptos_std::aptos_hash::keccak256; - - public fun point_evaluation_precompile(bytes: vector): (vector, bool) { + public fun point_evaluation_precompile(bytes: vector): vector { assert!( vector::length(&bytes) == 192, EINVALID_PRE_COMPILE_INPUT_SIZE ); - let versioned_hash = vector::slice(&bytes, (0u64), (32u64)); - let z = vector::slice(&bytes, (32u64), (64u64)); - let y = vector::slice(&bytes, (64u64), (96u64)); - let commitment = vector::slice(&bytes, (96u64), (144u64)); - let proof = vector::slice(&bytes, (144u64), (192u64)); - - vector::reverse(&mut z); - vector::reverse(&mut y); + let proof = vector::trim(&mut bytes, 144); + let commitment = vector::trim(&mut bytes, 96); + let y = vector::trim_reverse(&mut bytes, 64); + let z = vector::trim_reverse(&mut bytes, 32); + let versioned_hash = bytes; // Verify commitment matches versioned_hash assert!( @@ -45,25 +42,19 @@ module starknet_addr::pre_compile { ); // Verify KZG proof with z and y in big-endian format (LSB format in Aptos) assert!( - kzg_verify::verify_kzg_proof_impl(commitment, z, y, proof), + kzg_verify::verify_kzg_proof(commitment, z, y, proof), EINVALID_KZG_COMMITMENT ); - let bls_modulus = BLS_MODULUS; - let output = vector::empty(); - vector::append(&mut output, bytes::num_to_bytes_be(&FIELD_ELEMENTS_PER_BLOB)); - vector::append(&mut output, bytes::num_to_bytes_be(&bls_modulus)); - return (output, true) + let output = bytes::num_to_bytes_be(&FIELD_ELEMENTS_PER_BLOB); + vector::append(&mut output, bytes::num_to_bytes_be(&BLS_MODULUS)); + return output } #[test] fun test_point_evaluation_precompile() { let input = x"010b37b597b57e4c7d3df9c81ceb00130e2cca57679e6ddae2144503c5f751a105c51420f471fd9ca7dcf11d1873ea02a50969fdd602a4d59f8257c13264ef291b6916a50314993489fa27347e781129474c58fb9fe76a970dd2dd5d05b0e1a5996396e6cd13b33a9cc52ebd69e0aadca543794a449dd39de01d0cb2c09747709afe0e5a38dc2222185dbf7eba5f50888664b3057bc3aefaf110db484fdc0c422c58209c7f8a331a4c5f853a9e37d0de5f02ec0289d7d0634e49ef813fb8e84d"; - let (output, result) = point_evaluation_precompile(input); - assert!( - result, - 1 - ); + let output = point_evaluation_precompile(input); assert!( keccak256(output) == POINT_EVALUATION_PRECOMPILE_OUTPUT, 2 diff --git a/sources/kzg/trusted_setup.move b/sources/kzg/trusted_setup.move deleted file mode 100644 index 9498c53..0000000 --- a/sources/kzg/trusted_setup.move +++ /dev/null @@ -1,24 +0,0 @@ -module starknet_addr::trusted_setup { - // This is the trusted setup for the KZG commitment. It is not generated from the Aptos core - // but is loaded from an external source. The logic of the trusted setup is referenced from the following repo: - // https://github.com/sota-zk-labs/zkp-implementation/tree/main/kzg - - use aptos_std::bls12381_algebra::{FormatG1Compr, FormatG2Compr, G1, G2}; - use aptos_std::crypto_algebra::{deserialize, Element}; - - const G2_SETUP: vector = x"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"; - const G2S_SETUP: vector = x"b5bfd7dd8cdeb128843bc287230af38926187075cbfbefa81009a2ce615ac53d2914e5870cb452d2afaaab24f3499f72185cbfee53492714734429b7b38608e23926c911cceceac9a36851477ba4c60b087041de621000edc98edada20c1def2"; - const G1_GENERATOR: vector = x"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"; - - public fun get_g2s(): Element { - std::option::extract(&mut deserialize(&G2S_SETUP)) - } - - public fun get_g2(): Element { - std::option::extract(&mut deserialize(&G2_SETUP)) - } - - public fun get_g1_generator(): Element { - std::option::extract(&mut deserialize(&G1_GENERATOR)) - } -} \ No newline at end of file diff --git a/sources/libs/bytes.move b/sources/libs/bytes.move index a64528f..a325a52 100644 --- a/sources/libs/bytes.move +++ b/sources/libs/bytes.move @@ -2,23 +2,9 @@ module starknet_addr::bytes { use std::bcs::to_bytes; use std::vector; - use std::vector::{append, for_each_ref}; + use std::vector::{append, for_each_ref, reverse, trim_reverse}; use aptos_std::from_bcs::to_u256; - public fun reverse(x: vector): vector { - let result = vector::empty(); - let length = vector::length(&x); - let i = 0; - - while (i < length) { - let byte = vector::borrow(&x, length - 1 - i); - vector::push_back(&mut result, *byte); - i = i + 1; - }; - - return result - } - public fun vec_to_bytes_be(v: &vector): vector { let bytes: vector = vector[]; for_each_ref(v, |e| { @@ -30,20 +16,22 @@ module starknet_addr::bytes { } public fun num_to_bytes_be(v: &Element): vector { - reverse(to_bytes(v)) + let tmp = to_bytes(v); + vector::reverse(&mut tmp); + tmp } public fun u256_from_bytes_be(bytes: &vector): u256 { - to_u256(reverse(*bytes)) + let vec = *bytes; + reverse(&mut vec); + to_u256(vec) } public fun to_bytes_24_be(bytes: &vector): vector { let vec = *bytes; - while (vector::length(&vec) > 24) { - vector::pop_back(&mut vec); - }; - assert!(vector::length(&vec) == 24, 1); - reverse(vec) + trim_reverse(&mut vec, 24); + reverse(&mut vec); + vec } } diff --git a/sources/libs/named_storage.move b/sources/libs/named_storage.move deleted file mode 100644 index 3c4beb5..0000000 --- a/sources/libs/named_storage.move +++ /dev/null @@ -1,51 +0,0 @@ -module starknet_addr::named_storage { - // This line is used for generating constants DO NOT REMOVE! - // 0x30001 - const ENAMED_STORAGE_ALREADY_SET: u64 = 0x30001; - // End of generating constants! - - use aptos_std::smart_table; - use aptos_std::smart_table::SmartTable; - - struct Table_Storage has store, key { - bytes_to_u256: SmartTable, u256>, - bytes_to_addr: SmartTable, address>, - u256_to_addr: SmartTable, - addr_to_bool: SmartTable, - } - - struct Storage has store, key { - handle: SmartTable, T>, - } - - public fun init_table_storage(s: &signer) { - move_to(s, Table_Storage { - bytes_to_u256: smart_table::new, u256>(), - bytes_to_addr: smart_table::new, address>(), - u256_to_addr: smart_table::new(), - addr_to_bool: smart_table::new(), - }); - } - - public fun init_storage(s: &signer) { - move_to>(s, Storage { - handle: smart_table::new, T>(), - }) - } - - public fun get_value(tag: vector): T acquires Storage { - let storage = borrow_global_mut>(@starknet_addr); - *smart_table::borrow(&storage.handle, tag) - } - - public fun set_value(tag: vector, value: T) acquires Storage { - let storage = borrow_global_mut>(@starknet_addr); - smart_table::upsert(&mut storage.handle, tag, value); - } - - public fun set_exclusive_value(tag: vector, value: T) acquires Storage { - let storage = borrow_global_mut>(@starknet_addr); - assert!(smart_table::contains(&mut storage.handle, tag), ENAMED_STORAGE_ALREADY_SET); - smart_table::add(&mut storage.handle, tag, value); - } -} \ No newline at end of file diff --git a/sources/starknet_sovereign.move b/sources/starknet_sovereign.move index eaf9ce9..5ea9d5c 100644 --- a/sources/starknet_sovereign.move +++ b/sources/starknet_sovereign.move @@ -2,28 +2,28 @@ module starknet_addr::starknet { // This line is used for generating constants DO NOT REMOVE! // 4 const CONFIG_HASH_OFFSET: u64 = 0x4; - // The hash of the StarkNet config - const CONFIG_HASH_TAG: vector = b"STARKNET_1.0_STARKNET_CONFIG_HASH"; - // 0x20003 + // 131075 const EINVALID_CONFIG_HASH: u64 = 0x20003; - // 0x40007 + // 262151 const EINVALID_FINAL_BLOCK_NUMBER: u64 = 0x40007; - // 0x40001 + // 262145 const EINVALID_MESSAGE_SEGMENT_SIZE: u64 = 0x40001; - // 0x40005 + // 262149 const EINVALID_MESSAGE_TO_CONSUME: u64 = 0x40005; - // 0x40003 + // 262147 const EINVALID_PAYLOAD_LENGTH: u64 = 0x40003; - // 0x40002 + // 262146 const EMESSAGE_TOO_SHORT: u64 = 0x40002; - // 0x40006 + // 262150 const ESTARKNET_OUTPUT_TOO_LONG: u64 = 0x40006; - // 0x40008 + // 262152 const ESTARKNET_OUTPUT_TOO_SHORT: u64 = 0x40008; - // 0x40004 + // 262148 const ETRUNCATED_MESSAGE_PAYLOAD: u64 = 0x40004; // 6 const HEADER_SIZE: u64 = 0x6; + // 2 ^ 30 + const MAX_PAYLOAD_LENGTH: u64 = 0x40000000; // 0 const MESSAGE_TO_L1_FROM_ADDRESS_OFFSET: u64 = 0x0; // 2 @@ -44,20 +44,11 @@ module starknet_addr::starknet { const MESSAGE_TO_L2_SELECTOR_OFFSET: u64 = 0x3; // 1 const MESSAGE_TO_L2_TO_ADDRESS_OFFSET: u64 = 0x1; - // Random storage slot tags - const PROGRAM_HASH_TAG: vector = b"STARKNET_1.0_INIT_PROGRAM_HASH_UINT"; - // STARKNET_1.0_INIT_STARKNET_STATE_STRUCT - const STATE_STRUCT_TAG: vector = b"STARKNET_1.0_INIT_STARKNET_STATE_STRUCT"; - // STARKNET_1.0_INIT_VERIFIER_ADDRESS - const VERIFIER_ADDRESS_TAG: vector = b"STARKNET_1.0_INIT_VERIFIER_ADDRESS"; // End of generating constants! - use std::bcs; use std::vector; use aptos_std::aptos_hash::keccak256; - use aptos_std::debug::print; - use aptos_std::math64::pow; use aptos_std::smart_table; use aptos_std::smart_table::SmartTable; use aptos_framework::event; @@ -210,13 +201,12 @@ module starknet_addr::starknet { } fun process_messages(is_L2_to_L1: bool, program_output: vector): u64 acquires MessageStorage { - print(&program_output); let msg_storage = borrow_global_mut(@starknet_addr); let l1_to_l2_messages = &mut msg_storage.l1_to_l2_messages; let l2_to_l1_messages = &mut msg_storage.l2_to_l1_messages; let message_segment_size = (*vector::borrow(&program_output, 0) as u64); - assert!(message_segment_size < pow(2, 30), EINVALID_MESSAGE_SEGMENT_SIZE); + assert!(message_segment_size < MAX_PAYLOAD_LENGTH, EINVALID_MESSAGE_SEGMENT_SIZE); let offset = 1u64; let message_segment_end = offset + message_segment_size; @@ -235,12 +225,8 @@ module starknet_addr::starknet { EMESSAGE_TOO_SHORT ); - print(&payload_length_offset); - print(&(*vector::borrow(&program_output, payload_length_offset))); - print(&(*vector::borrow(&program_output, payload_length_offset) as u64)); - let payload_length = (*vector::borrow(&program_output, payload_length_offset) as u64); - assert!(payload_length < pow(2, 30), EINVALID_PAYLOAD_LENGTH); + assert!(payload_length < MAX_PAYLOAD_LENGTH, EINVALID_PAYLOAD_LENGTH); let end_offset = payload_length_offset + payload_length; assert!( @@ -248,12 +234,12 @@ module starknet_addr::starknet { ETRUNCATED_MESSAGE_PAYLOAD ); - if (is_L2_to_L1) { - let msg_hash = keccak256( - bcs::to_bytes( - &vector::slice(&program_output, offset, end_offset - ))); + let msg_hash = keccak256( + bcs::to_bytes( + &vector::slice(&program_output, offset, end_offset + ))); + if (is_L2_to_L1) { event::emit(LogMessageToL1 { from_address: *vector::borrow( &program_output, @@ -272,11 +258,6 @@ module starknet_addr::starknet { let msg = smart_table::borrow_mut_with_default(l2_to_l1_messages, msg_hash, 0); *msg = *msg + 1; } else { - let msg_hash = keccak256( - bcs::to_bytes( - &vector::slice(&program_output, offset, end_offset - ))); - let msg_fee_plus_one = smart_table::borrow_mut(l1_to_l2_messages, msg_hash); assert!(*msg_fee_plus_one > 0, EINVALID_MESSAGE_TO_CONSUME); total_mgs_fees = total_mgs_fees + *msg_fee_plus_one - 1; diff --git a/sources/starknet_state.move b/sources/starknet_state.move index 16dfd44..58b675f 100644 --- a/sources/starknet_state.move +++ b/sources/starknet_state.move @@ -4,9 +4,9 @@ module starknet_addr::starknet_state { const BLOCK_HASH_OFFSET: u64 = 0x3; // 2 const BLOCK_NUMBER_OFFSET: u64 = 0x2; - // 0x20001 + // 131073 const EINVALID_BLOCK_NUMBER: u64 = 0x20001; - // 0x20002 + // 131074 const EINVALID_PREVIOUS_ROOT: u64 = 0x20002; // 0 const MERKLE_UPDATE_OFFSET: u64 = 0x0; @@ -28,15 +28,15 @@ module starknet_addr::starknet_state { } } - public fun set_global_root(state: &mut State, global_root: u256) { + public(friend) fun set_global_root(state: &mut State, global_root: u256) { state.global_root = global_root; } - public fun set_block_number(state: &mut State, block_number: u256) { + public(friend) fun set_block_number(state: &mut State, block_number: u256) { state.block_number = block_number; } - public fun set_block_hash(state: &mut State, block_hash: u256) { + public(friend) fun set_block_hash(state: &mut State, block_hash: u256) { state.block_hash = block_hash; } @@ -63,10 +63,10 @@ module starknet_addr::starknet_state { let commitment_tree_update = vector::slice(&starknet_output, MERKLE_UPDATE_OFFSET, MERKLE_UPDATE_OFFSET + 2); assert!( - state.global_root == *vector::borrow(&commitment_tree_update, 0), + state.global_root == *vector::borrow(&commitment_tree_update, MERKLE_UPDATE_OFFSET), EINVALID_PREVIOUS_ROOT ); - state.global_root = *vector::borrow(&commitment_tree_update, 1); + state.global_root = *vector::borrow(&commitment_tree_update, MERKLE_UPDATE_OFFSET + 1); } #[test] diff --git a/sources/starknet_storage.move b/sources/starknet_storage.move index 84abe79..218d30a 100644 --- a/sources/starknet_storage.move +++ b/sources/starknet_storage.move @@ -1,10 +1,14 @@ module starknet_addr::starknet_storage { - use starknet_addr::blob_submission; use starknet_addr::blob_submission::{ Sidecar, default }; use starknet_addr::starknet_state; use starknet_addr::starknet_state::State; + // This line is used for generating constants DO NOT REMOVE! + // 589825 + const EINVALID_STORAGE: u64 = 0x90001; + // End of generating constants! + struct Storage has copy, drop, store, key { program_hash: u256, config_hash: u256, @@ -14,8 +18,9 @@ module starknet_addr::starknet_storage { } public fun initialize(s: &signer, program_hash: u256, verifier: address, config_hash: u256, state: State) { - let sidecar: Sidecar = default(); + assert!(!is_initialized(verifier), EINVALID_STORAGE); + let sidecar: Sidecar = default(); move_to(s, Storage { program_hash, config_hash, @@ -31,35 +36,43 @@ module starknet_addr::starknet_storage { public fun update_sidecar(addr: address, new_sidecar: Sidecar) acquires Storage { let sidecar = &mut borrow_global_mut(addr).sidecar; - blob_submission::update_sidecar(sidecar, new_sidecar); + + let blob = blob_submission::get_sidecar_blob(new_sidecar); + blob_submission::set_sidecar_blob(sidecar, blob); + + let commitment = blob_submission::get_sidecar_commitment(new_sidecar); + blob_submission::set_sidecar_commitment(sidecar, commitment); + + let proof = blob_submission::get_sidecar_proof(new_sidecar); + blob_submission::set_sidecar_proof(sidecar, proof); } public fun get_sidecar(addr: address): Sidecar acquires Storage { borrow_global(addr).sidecar } - public fun set_program_hash(storage: &mut Storage, new_program_hash: u256) { + public(friend) fun set_program_hash(storage: &mut Storage, new_program_hash: u256) { storage.program_hash = new_program_hash; } public fun get_program_hash(addr: address): u256 acquires Storage { - borrow_global_mut(addr).program_hash + borrow_global(addr).program_hash } - public fun set_config_hash(storage: &mut Storage, new_config_hash: u256) { + public(friend) fun set_config_hash(storage: &mut Storage, new_config_hash: u256) { storage.config_hash = new_config_hash; } public fun get_config_hash(addr: address): u256 acquires Storage { - borrow_global_mut(addr).config_hash + borrow_global(addr).config_hash } - public fun set_verifier(storage: &mut Storage, addr: address) { + public(friend) fun set_verifier(storage: &mut Storage, addr: address) { storage.verifier = addr; } public fun get_verifier(addr: address): address acquires Storage { - borrow_global_mut(addr).verifier + borrow_global(addr).verifier } public fun update_state(addr: address, starknet_output: vector) acquires Storage { @@ -68,6 +81,6 @@ module starknet_addr::starknet_storage { } public fun get_state(addr: address): State acquires Storage { - borrow_global_mut(addr).state + borrow_global(addr).state } } \ No newline at end of file diff --git a/sources/starknet_validity.move b/sources/starknet_validity.move index 0d4cee6..bbb48c4 100644 --- a/sources/starknet_validity.move +++ b/sources/starknet_validity.move @@ -1,30 +1,43 @@ module starknet_addr::starknet_validity { + use std::bcs; + use std::vector; + use aptos_std::aptos_hash::keccak256; + use aptos_framework::account::new_event_handle; + use aptos_framework::event; + use aptos_framework::event::emit_event; + + use starknet_addr::blob_submission::new; + use starknet_addr::bytes::{num_to_bytes_be, to_bytes_24_be, vec_to_bytes_be}; + use starknet_addr::fact_registry; + use starknet_addr::fact_registry::init_fact_registry; + use starknet_addr::kzg_helper::kzg_to_versioned_hash; + use starknet_addr::onchain_data_fact_tree_encoded as onchain_data_fact; + use starknet_addr::pre_compile; + use starknet_addr::starknet_state; + use starknet_addr::starknet_storage; + // This line is used for generating constants DO NOT REMOVE! // 4 const CONFIG_HASH_OFFSET: u64 = 0x4; - // The hash of the StarkNet config - const CONFIG_HASH_TAG: vector = b"STARKNET_1.0_STARKNET_CONFIG_HASH"; - // 0x20003 + // 131075 const EINVALID_CONFIG_HASH: u64 = 0x20003; - // 0x40007 + // 262151 const EINVALID_FINAL_BLOCK_NUMBER: u64 = 0x40007; - // 0x50005 + // 327685 const EINVALID_KZG_COMMITMENT: u64 = 0x50005; - // 0x50003 + // 327683 const EINVALID_KZG_PROOF_SIZE: u64 = 0x50003; - // 0x50002 + // 327682 const EINVALID_KZG_SEGMENT_SIZE: u64 = 0x50002; - // 0x50006 + // 327686 const EINVALID_Y_VALUE: u64 = 0x50006; - // 0x60001 + // 393217 const ENO_STATE_TRANSITION_PROOF: u64 = 0x60001; - // 0x8001 - const EPOINT_EVALUATION_PRECOMPILE_CALL_FAILED: u64 = 0x8001; - // 0x40008 + // 262152 const ESTARKNET_OUTPUT_TOO_SHORT: u64 = 0x40008; - // 0x50001 + // 327681 const EUNEXPECTED_KZG_DA_FLAG: u64 = 0x50001; - // 0x80002 + // 524290 const EUNEXPECTED_POINT_EVALUATION_PRECOMPILE_OUTPUT: u64 = 0x80002; // 6 const HEADER_SIZE: u64 = 0x6; @@ -36,33 +49,12 @@ module starknet_addr::starknet_validity { const MAX_UINT192: u256 = 6277101735386680763835789423207666416102355444464034512895; // b2157d3a40131b14c4c675335465dffde802f0ce5218ad012284d7f275d1b37c const POINT_EVALUATION_PRECOMPILE_OUTPUT: vector = x"b2157d3a40131b14c4c675335465dffde802f0ce5218ad012284d7f275d1b37c"; - // Random storage slot tags - const PROGRAM_HASH_TAG: vector = b"STARKNET_1.0_INIT_PROGRAM_HASH_UINT"; // 48 const PROOF_BYTES_LENGTH: u256 = 0x30; - // STARKNET_1.0_INIT_STARKNET_STATE_STRUCT - const STATE_STRUCT_TAG: vector = b"STARKNET_1.0_INIT_STARKNET_STATE_STRUCT"; // 5 const USE_KZG_DA_OFFSET: u64 = 0x5; - // STARKNET_1.0_INIT_VERIFIER_ADDRESS - const VERIFIER_ADDRESS_TAG: vector = b"STARKNET_1.0_INIT_VERIFIER_ADDRESS"; // End of generating constants! - - use std::bcs; - use std::vector; - use aptos_std::aptos_hash::keccak256; - use aptos_framework::event; - use starknet_addr::kzg_helper::kzg_to_versioned_hash; - - use starknet_addr::blob_submission::new; - use starknet_addr::bytes::{num_to_bytes_be, to_bytes_24_be, vec_to_bytes_be}; - use starknet_addr::fact_registry; - use starknet_addr::onchain_data_fact_tree_encoded as onchain_data_fact; - use starknet_addr::pre_compile; - use starknet_addr::starknet_state; - use starknet_addr::starknet_storage; - #[event] struct ConfigHashChanged { changed_by: address, @@ -98,49 +90,24 @@ module starknet_addr::starknet_validity { block_number: u256, block_hash: u256 ) { - starknet_storage::initialize(s, program_hash, verifier, config_hash, starknet_state::new( - global_root, - block_number, - block_hash - )); - } - - #[view] - public fun state_root(): u256 { - starknet_state::get_global_root(starknet_storage::get_state(@starknet_addr)) - } - - #[view] - public fun state_block_hash(): u256 { - starknet_state::get_block_hash(starknet_storage::get_state(@starknet_addr)) - } - - #[view] - public fun is_initialized(addr: address): bool { - starknet_storage::is_initialized(addr) - } - - #[view] - public fun get_config_hash(): u256 { - starknet_storage::get_config_hash(@starknet_addr) - } - - #[view] - public fun get_program_hash(): u256 { - starknet_storage::get_program_hash(@starknet_addr) - } - - #[view] - public fun state_block_number(): u256 { - starknet_state::get_block_number(starknet_storage::get_state(@starknet_addr)) + starknet_storage::initialize( + s, + program_hash, + verifier, + config_hash, + starknet_state::new( + global_root, + block_number, + block_hash + )); } public entry fun update_state( + s: &signer, program_output: vector, onchain_data_hash: u256, onchain_data_size: u256, ) { - // Reentrancy protection: read the block number at the beginning let initial_block_number = state_block_number(); // Validate program output @@ -155,58 +122,21 @@ module starknet_addr::starknet_validity { EUNEXPECTED_KZG_DA_FLAG ); - let fact_data = onchain_data_fact::init_fact_data(onchain_data_hash, onchain_data_size); + let fact_data = onchain_data_fact::new(onchain_data_hash, onchain_data_size); let state_transition_fact = onchain_data_fact::encode_fact_with_onchain_data( - program_output, + &program_output, fact_data ); - update_state_internal(&program_output, state_transition_fact); + update_internal_state(s, &program_output, state_transition_fact); - // Reentrancy protection: validate final block number assert!( state_block_number() == initial_block_number + 1, EINVALID_FINAL_BLOCK_NUMBER ); } - public fun update_state_internal( - program_output: &vector, - state_transition_fact: vector, - ) { - // Validate config hash. - assert!( - *vector::borrow(program_output, CONFIG_HASH_OFFSET) == get_config_hash(), - EINVALID_CONFIG_HASH - ); - - let program_hash: vector = num_to_bytes_be(&get_program_hash()); - let buffer: vector = vector::empty(); - vector::append(&mut buffer, program_hash); - vector::append(&mut buffer, state_transition_fact); - let sharp_fact = keccak256(buffer); - assert!( - fact_registry::is_valid(sharp_fact), - ENO_STATE_TRANSITION_PROOF - ); - - event::emit(LogStateTransitionFact { - state_transition_fact - }); - - // Perform state update. - starknet_storage::update_state(@starknet_addr, *program_output); - - // TODO: process message - - let state = starknet_storage::get_state(@starknet_addr); - event::emit(LogStateUpdate { - global_root: starknet_state::get_global_root(state), - block_number: starknet_state::get_block_number(state), - block_hash: starknet_state::get_block_hash(state) - }) - } - public entry fun update_state_kzg_da( + s: &signer, program_output: vector, kzg_proof: vector ) { @@ -230,7 +160,7 @@ module starknet_addr::starknet_validity { verify_kzg_proof(&kzg_segment, &kzg_proof); let state_transition_fact = keccak256(vec_to_bytes_be(&program_output)); - update_state_internal(&program_output, state_transition_fact); + update_internal_state(s, &program_output, state_transition_fact); // Re-entrancy protection: validate final block number assert!( @@ -239,7 +169,55 @@ module starknet_addr::starknet_validity { ); } - public fun verify_kzg_proof( + public entry fun blob_submission( + blob: vector>, + commitment: vector>, + proof: vector> + ) { + // TODO: process blob + let sidecar = new(blob, commitment, proof); + starknet_storage::update_sidecar(@starknet_addr, sidecar); + } + + public(friend) fun update_internal_state( + s: &signer, + program_output: &vector, + state_transition_fact: vector, + ) { + // Validate config hash. + assert!( + *vector::borrow(program_output, CONFIG_HASH_OFFSET) == get_config_hash(), + EINVALID_CONFIG_HASH + ); + + let program_hash: vector = num_to_bytes_be(&get_program_hash()); + vector::append(&mut program_hash, state_transition_fact); + let sharp_fact = keccak256(program_hash); + assert!( + fact_registry::is_valid(sharp_fact), + ENO_STATE_TRANSITION_PROOF + ); + + event::emit(LogStateTransitionFact { + state_transition_fact + }); + + // Perform state update. + starknet_storage::update_state(@starknet_addr, *program_output); + + // TODO: process message + + let state = starknet_storage::get_state(@starknet_addr); + let event_handle = new_event_handle(s); + emit_event(&mut event_handle, LogStateUpdate { + global_root: starknet_state::get_global_root(state), + block_number: starknet_state::get_block_number(state), + block_hash: starknet_state::get_block_hash(state) + }); + event::destroy_handle(event_handle); + } + + public(friend) fun verify_kzg_proof( kzg_segment: &vector, kzg_proof: &vector ) { @@ -251,7 +229,7 @@ module starknet_addr::starknet_validity { (vector::length(kzg_proof) as u256) == PROOF_BYTES_LENGTH, EINVALID_KZG_PROOF_SIZE ); - + let y; let kzg_commitment; { @@ -276,8 +254,7 @@ module starknet_addr::starknet_validity { EINVALID_Y_VALUE ); - kzg_commitment = vector::empty(); - vector::append(&mut kzg_commitment, to_bytes_24_be(&bcs::to_bytes(&kzg_commitment_high))); + kzg_commitment = to_bytes_24_be(&bcs::to_bytes(&kzg_commitment_high)); vector::append(&mut kzg_commitment, to_bytes_24_be(&bcs::to_bytes(&kzg_commitment_low))); y = num_to_bytes_be(&((y_high << 128) + y_low)); @@ -287,15 +264,12 @@ module starknet_addr::starknet_validity { let z = *vector::borrow(kzg_segment, 2); - let precompile_input: vector = vector::empty(); - vector::append(&mut precompile_input, blob_hash); - vector::append(&mut precompile_input, num_to_bytes_be(&z)); - vector::append(&mut precompile_input, y); - vector::append(&mut precompile_input, kzg_commitment); - vector::append(&mut precompile_input, *kzg_proof); + vector::append(&mut blob_hash, num_to_bytes_be(&z)); + vector::append(&mut blob_hash, y); + vector::append(&mut blob_hash, kzg_commitment); + vector::append(&mut blob_hash, *kzg_proof); - let (precompile_output, ok) = pre_compile::point_evaluation_precompile(precompile_input); - assert!(ok, EPOINT_EVALUATION_PRECOMPILE_CALL_FAILED); + let precompile_output = pre_compile::point_evaluation_precompile(blob_hash); assert!( keccak256(precompile_output) == POINT_EVALUATION_PRECOMPILE_OUTPUT, @@ -303,15 +277,57 @@ module starknet_addr::starknet_validity { ); } - public entry fun blob_submission(blob: vector>, commitment: vector>, proof: vector>) { - let sidecar = new(blob, commitment, proof); - starknet_storage::update_sidecar(@starknet_addr, sidecar); + fun init_module(s: &signer) { + let state = starknet_state::new( + 0, + 0, + 0 + ); + starknet_storage::initialize( + s, + 0, + @starknet_addr, + 0, + state + ); + init_fact_registry(s); } public fun get_blob_hash(commitment: &vector): vector { + // TODO: Check blob registration kzg_to_versioned_hash(commitment) } + #[view] + public fun state_root(): u256 { + starknet_state::get_global_root(starknet_storage::get_state(@starknet_addr)) + } + + #[view] + public fun state_block_hash(): u256 { + starknet_state::get_block_hash(starknet_storage::get_state(@starknet_addr)) + } + + #[view] + public fun is_initialized(addr: address): bool { + starknet_storage::is_initialized(addr) + } + + #[view] + public fun get_config_hash(): u256 { + starknet_storage::get_config_hash(@starknet_addr) + } + + #[view] + public inline fun get_program_hash(): u256 { + starknet_storage::get_program_hash(@starknet_addr) + } + + #[view] + public fun state_block_number(): u256 { + starknet_state::get_block_number(starknet_storage::get_state(@starknet_addr)) + } + #[test(s = @starknet_addr)] fun test_submiss_blob(s: &signer) { let state = starknet_state::new( @@ -377,11 +393,11 @@ module starknet_addr::starknet_validity { // This test depends on the value of `fact`, which is precomputed and registered before updating the state. // All test data is taken from transaction 0xe76c6accacbcedb7f66d5dc3f1a3e189d4e4d194ea88c19ee29955adbc902362. - fact_registry::register_fact(s, x"af6d61465fa108b0e7d4d9bef635dec868bcfa8e9fa14c5486c6017cd552fd4c"); + fact_registry::init_fact_registry(s); + fact_registry::register_fact(x"af6d61465fa108b0e7d4d9bef635dec868bcfa8e9fa14c5486c6017cd552fd4c"); let kzg_proof: vector = x"8664b3057bc3aefaf110db484fdc0c422c58209c7f8a331a4c5f853a9e37d0de5f02ec0289d7d0634e49ef813fb8e84d"; - - update_state_kzg_da(program_output, kzg_proof); + update_state_kzg_da(s, program_output, kzg_proof); } #[test(s = @starknet_addr)] @@ -400,7 +416,7 @@ module starknet_addr::starknet_validity { state ); - let program_output = vector[ + let program_output: vector = vector[ 1970272326382990453316397420342340810466901058626735958618873840050980391150, 3458474516901043875685413386881507261498565942069144376940366111442758962633, 608891, @@ -418,7 +434,8 @@ module starknet_addr::starknet_validity { // All test data is taken from transaction 0xd7cfa525566850a190eec7937da2f8e43c8e87873747e5a41c74adb404210472. // The expected `onchain_data_hash` and `onchain_data_size` may change when simulating the transaction. - fact_registry::register_fact(s, x"b7fae2e2b20a6e0c96d4899cbd47f0af865f53afe75a1482ab5d637a89d8aca4"); - update_state(program_output, onchain_data_hash, onchain_data_size); + fact_registry::init_fact_registry(s); + fact_registry::register_fact(x"b7fae2e2b20a6e0c96d4899cbd47f0af865f53afe75a1482ab5d637a89d8aca4"); + update_state(s, program_output, onchain_data_hash, onchain_data_size); } } \ No newline at end of file From 3e6e11907959f031d423b877a054f10d785646a6 Mon Sep 17 00:00:00 2001 From: Tranduy1dol Date: Tue, 20 Aug 2024 07:30:53 +0000 Subject: [PATCH 2/4] feat: add github action --- .github/{aptos_test.yaml => workflows/aptos_test.yml} | 2 +- sources/starknet_validity.move | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/{aptos_test.yaml => workflows/aptos_test.yml} (94%) diff --git a/.github/aptos_test.yaml b/.github/workflows/aptos_test.yml similarity index 94% rename from .github/aptos_test.yaml rename to .github/workflows/aptos_test.yml index 90e17ea..190b3c6 100644 --- a/.github/aptos_test.yaml +++ b/.github/workflows/aptos_test.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - uses: ./.github/actions/setup_aptos_cli with: - version: 1.0.11 + version: 4.0.0 - name: Test working-directory: sources run: aptos move test diff --git a/sources/starknet_validity.move b/sources/starknet_validity.move index bbb48c4..da24f04 100644 --- a/sources/starknet_validity.move +++ b/sources/starknet_validity.move @@ -319,7 +319,7 @@ module starknet_addr::starknet_validity { } #[view] - public inline fun get_program_hash(): u256 { + public fun get_program_hash(): u256 { starknet_storage::get_program_hash(@starknet_addr) } From b4b9244a780e6d9f602c898b6f033a76ddb42480 Mon Sep 17 00:00:00 2001 From: draply Date: Thu, 12 Sep 2024 10:17:23 +0700 Subject: [PATCH 3/4] fix(test): fix error when use event_handle --- sources/starknet_validity.move | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sources/starknet_validity.move b/sources/starknet_validity.move index da24f04..679c5e3 100644 --- a/sources/starknet_validity.move +++ b/sources/starknet_validity.move @@ -16,6 +16,9 @@ module starknet_addr::starknet_validity { use starknet_addr::starknet_state; use starknet_addr::starknet_storage; + #[test_only] + use aptos_framework::account::create_account_for_test; + // This line is used for generating constants DO NOT REMOVE! // 4 const CONFIG_HASH_OFFSET: u64 = 0x4; @@ -352,6 +355,7 @@ module starknet_addr::starknet_validity { #[test(s = @starknet_addr)] fun test_update_state_kzg_da(s: &signer) { + create_account_for_test(@starknet_addr); let state = starknet_state::new( 1140305933455702090030976682007678821560814182066058788699329257003131568320, 663730, @@ -402,6 +406,7 @@ module starknet_addr::starknet_validity { #[test(s = @starknet_addr)] fun test_update_state(s: &signer) { + create_account_for_test(@starknet_addr); let state = starknet_state::new( 1970272326382990453316397420342340810466901058626735958618873840050980391150, 608890, From a7661d7bcbedf1160bd946b3656344c2376d2127 Mon Sep 17 00:00:00 2001 From: hduoc2003 Date: Tue, 3 Dec 2024 11:07:12 +0000 Subject: [PATCH 4/4] add navori libs --- Move.toml | 10 ++- sources/components/fact_registry.move | 34 ++++---- .../onchain_data_fact_tree_encoded.move | 19 +++-- sources/kzg/pre_compile.move | 18 ++--- sources/libs/bytes.move | 72 ----------------- sources/starknet_validity.move | 79 +++++++++++-------- 6 files changed, 90 insertions(+), 142 deletions(-) delete mode 100644 sources/libs/bytes.move diff --git a/Move.toml b/Move.toml index defdece..ab3a3af 100644 --- a/Move.toml +++ b/Move.toml @@ -4,13 +4,17 @@ version = "1.0.0" authors = [] [addresses] -starknet_addr = "0xb50b1b8157ebf7315813c1f745a1e1c68c73111afe2b6761975223d317569b69" +starknet_addr = "_" +lib_addr = "_" [dev-addresses] +starknet_addr = "0xb50b1b8157ebf7315813c1f745a1e1c68c73111afe2b6761975223d317569b69" +lib_addr = "54ba5979fbdf5fa56c4f4b5147fa33068148d08f6f191c23bca865c21192dcaa" [dependencies.AptosFramework] git = "https://github.com/aptos-labs/aptos-core.git" -rev = "aptos-release-v1.17" +rev = "mainnet" subdir = "aptos-move/framework/aptos-framework" -[dev-dependencies] +[dependencies] +libs = { git = "https://github.com/sota-zk-labs/navori", rev = "layout6", subdir = "libs" } diff --git a/sources/components/fact_registry.move b/sources/components/fact_registry.move index a902ca2..224cb1e 100644 --- a/sources/components/fact_registry.move +++ b/sources/components/fact_registry.move @@ -1,33 +1,39 @@ -// TODO: Add Navori as a dependency module starknet_addr::fact_registry { + use std::signer::address_of; use aptos_std::smart_table; - use aptos_std::smart_table::{ SmartTable, borrow, upsert, new }; + use aptos_std::smart_table::SmartTable; + use aptos_framework::event; + + #[event] + struct FactRegistered has store, drop { + fact_hash: u256 + } struct VerifierFact has key, store { - verified_fact: SmartTable, bool>, + verified_fact: SmartTable, any_fact_registered: bool } - public entry fun init_fact_registry(s: &signer) { + public fun init_fact_registry(s: &signer) { move_to(s, VerifierFact { - verified_fact: new, bool>(), + verified_fact: smart_table::new(), any_fact_registered: false }); } #[view] - public fun is_valid(fact: vector): bool acquires VerifierFact { - let verifier_fact = borrow_global(@starknet_addr); + public fun is_valid(address: address, fact: u256): bool acquires VerifierFact { + let verifier_fact = borrow_global(address); *smart_table::borrow_with_default(&verifier_fact.verified_fact, fact, &false) } - #[view] - public fun fact_check(fact: vector): bool acquires VerifierFact { - *borrow(&borrow_global(@starknet_addr).verified_fact, fact) - } + public fun register_fact(s: &signer, fact_hash: u256) acquires VerifierFact { + let verifier_fact = borrow_global_mut(address_of(s)); + smart_table::upsert(&mut verifier_fact.verified_fact, fact_hash, true); + event::emit(FactRegistered { fact_hash }); - public entry fun register_fact(fact_hash: vector) acquires VerifierFact { - let verifier_fact = borrow_global_mut(@starknet_addr); - upsert(&mut verifier_fact.verified_fact, fact_hash, true); + if (verifier_fact.any_fact_registered == false) { + verifier_fact.any_fact_registered = true; + } } } \ No newline at end of file diff --git a/sources/components/onchain_data_fact_tree_encoded.move b/sources/components/onchain_data_fact_tree_encoded.move index 6379114..498f768 100644 --- a/sources/components/onchain_data_fact_tree_encoded.move +++ b/sources/components/onchain_data_fact_tree_encoded.move @@ -1,9 +1,8 @@ module starknet_addr::onchain_data_fact_tree_encoded { use std::bcs::to_bytes; - use std::vector; + use std::vector::{length, reverse_append, append}; use aptos_std::aptos_hash::keccak256; - - use starknet_addr::bytes; + use lib_addr::bytes::{num_to_bytes_le, bytes32_to_u256, vec_to_bytes_le}; struct DataAvailabilityFact has store, drop { onchain_data_hash: u256, @@ -14,16 +13,16 @@ module starknet_addr::onchain_data_fact_tree_encoded { program_output: &vector, fact_data: DataAvailabilityFact ): vector { - let main_public_input_length: u256 = (vector::length(program_output) as u256); - let main_public_input_hash: vector = keccak256(bytes::vec_to_bytes_be(program_output)); - vector::reverse_append(&mut main_public_input_hash, to_bytes(&main_public_input_length)); - vector::append(&mut main_public_input_hash, bytes::num_to_bytes_be(&fact_data.onchain_data_hash)); - vector::append( + let main_public_input_length: u256 = (length(program_output) as u256); + let main_public_input_hash: vector = keccak256(vec_to_bytes_le(program_output)); + reverse_append(&mut main_public_input_hash, to_bytes(&main_public_input_length)); + append(&mut main_public_input_hash, num_to_bytes_le(&fact_data.onchain_data_hash)); + append( &mut main_public_input_hash, - bytes::num_to_bytes_be(&(main_public_input_length + fact_data.onchain_data_size)) + num_to_bytes_le(&(main_public_input_length + fact_data.onchain_data_size)) ); let hash_result: vector = keccak256(main_public_input_hash); - let result = bytes::num_to_bytes_be(&(bytes::u256_from_bytes_be(&hash_result) + 1)); + let result = num_to_bytes_le(&(bytes32_to_u256(hash_result) + 1)); return result } diff --git a/sources/kzg/pre_compile.move b/sources/kzg/pre_compile.move index 311f2a5..5bb7b98 100644 --- a/sources/kzg/pre_compile.move +++ b/sources/kzg/pre_compile.move @@ -1,7 +1,7 @@ module starknet_addr::pre_compile { - use std::vector; + use std::vector::{length, trim, trim_reverse, append}; + use lib_addr::bytes; - use starknet_addr::bytes; use starknet_addr::kzg_helper; use starknet_addr::kzg_verify; @@ -25,14 +25,14 @@ module starknet_addr::pre_compile { public fun point_evaluation_precompile(bytes: vector): vector { assert!( - vector::length(&bytes) == 192, + length(&bytes) == 192, EINVALID_PRE_COMPILE_INPUT_SIZE ); - let proof = vector::trim(&mut bytes, 144); - let commitment = vector::trim(&mut bytes, 96); - let y = vector::trim_reverse(&mut bytes, 64); - let z = vector::trim_reverse(&mut bytes, 32); + let proof = trim(&mut bytes, 144); + let commitment = trim(&mut bytes, 96); + let y = trim_reverse(&mut bytes, 64); + let z = trim_reverse(&mut bytes, 32); let versioned_hash = bytes; // Verify commitment matches versioned_hash @@ -46,8 +46,8 @@ module starknet_addr::pre_compile { EINVALID_KZG_COMMITMENT ); - let output = bytes::num_to_bytes_be(&FIELD_ELEMENTS_PER_BLOB); - vector::append(&mut output, bytes::num_to_bytes_be(&BLS_MODULUS)); + let output = bytes::num_to_bytes_le(&FIELD_ELEMENTS_PER_BLOB); + append(&mut output, bytes::num_to_bytes_le(&BLS_MODULUS)); return output } diff --git a/sources/libs/bytes.move b/sources/libs/bytes.move deleted file mode 100644 index a325a52..0000000 --- a/sources/libs/bytes.move +++ /dev/null @@ -1,72 +0,0 @@ -// TODO: Add Navori as a dependency -module starknet_addr::bytes { - use std::bcs::to_bytes; - use std::vector; - use std::vector::{append, for_each_ref, reverse, trim_reverse}; - use aptos_std::from_bcs::to_u256; - - public fun vec_to_bytes_be(v: &vector): vector { - let bytes: vector = vector[]; - for_each_ref(v, |e| { - let tmp = to_bytes(e); - vector::reverse(&mut tmp); - append(&mut bytes, tmp); - }); - bytes - } - - public fun num_to_bytes_be(v: &Element): vector { - let tmp = to_bytes(v); - vector::reverse(&mut tmp); - tmp - } - - public fun u256_from_bytes_be(bytes: &vector): u256 { - let vec = *bytes; - reverse(&mut vec); - to_u256(vec) - } - - public fun to_bytes_24_be(bytes: &vector): vector { - let vec = *bytes; - trim_reverse(&mut vec, 24); - reverse(&mut vec); - vec - } -} - -#[test_only] -module starknet_addr::bytes_test { - - use starknet_addr::bytes::{to_bytes_24_be, vec_to_bytes_be}; - - #[test] - fun test_vec_to_bytes_be() { - let bytes = vec_to_bytes_be(&vector[ - 1723587082856532763241173775465496577348305577532331450336061658809521876102u256, - 2479248348687909740970436565718726357572221543762678024250834744245756360726u256, - 587272u256, - 2177570517647428816133395681679456086343281988787809822104528418476218261377u256, - 2590421891839256512113614983194993186457498815986333310670788206383913888162u256, - 0u256, - 0u256 - ]); - assert!( - bytes == vector[3, 207, 132, 6, 22, 251, 16, 23, 61, 164, 114, 227, 144, 90, 144, 182, 125, 246, 14, 114, 141, 124, 226, 100, 55, 247, 9, 238, 226, 83, 44, 134, 5, 123, 52, 112, 61, 135, 118, 240, - 24, 28, 235, 230, 182, 104, 65, 168, 12, 194, 199, 51, 49, 197, 88, 205, 129, 152, 95, 217, 19, 67, 248, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - , 0, 0, 0, 0, 8, 246, 8, 4, 208, 118, 19, 147, 125, 138, 113, 9, 211, 33, 204, 68, 209, 67, 44, 185, 149, 186, 61, 135, 177, 85, 80, 221, 169, 41, 202, 199, 30, 31, 129, 5, 186, 32, - 120, 36, 15, 21, 133, 249, 100, 36, 194, 209, 238, 72, 33, 29, 163, 179, 249, 23, 123, 242, 185, 136, 11, 79, 201, 29, 89, 233, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - 1 - ); - } - - #[test] - fun test_to_bytes_24_be() { - let vec = x"7099b4741abe5b91d8f5f2bacfaf17de010e376b644e77a90000000000000000"; - assert!( - to_bytes_24_be(&vec) == x"a9774e646b370e01de17afcfbaf2f5d8915bbe1a74b49970", - 1 - ); - } -} \ No newline at end of file diff --git a/sources/starknet_validity.move b/sources/starknet_validity.move index 679c5e3..eab1da8 100644 --- a/sources/starknet_validity.move +++ b/sources/starknet_validity.move @@ -1,15 +1,15 @@ module starknet_addr::starknet_validity { use std::bcs; - use std::vector; + use std::signer::address_of; + use std::vector::{borrow, length, slice, append, trim_reverse, reverse}; use aptos_std::aptos_hash::keccak256; use aptos_framework::account::new_event_handle; use aptos_framework::event; use aptos_framework::event::emit_event; + use starknet_addr::fact_registry::{is_valid, init_fact_registry}; + use lib_addr::bytes::{num_to_bytes_le, bytes32_to_u256}; use starknet_addr::blob_submission::new; - use starknet_addr::bytes::{num_to_bytes_be, to_bytes_24_be, vec_to_bytes_be}; - use starknet_addr::fact_registry; - use starknet_addr::fact_registry::init_fact_registry; use starknet_addr::kzg_helper::kzg_to_versioned_hash; use starknet_addr::onchain_data_fact_tree_encoded as onchain_data_fact; use starknet_addr::pre_compile; @@ -18,6 +18,10 @@ module starknet_addr::starknet_validity { #[test_only] use aptos_framework::account::create_account_for_test; + #[test_only] + use starknet_addr::fact_registry; + #[test_only] + use starknet_addr::fact_registry::register_fact; // This line is used for generating constants DO NOT REMOVE! // 4 @@ -115,13 +119,13 @@ module starknet_addr::starknet_validity { // Validate program output assert!( - vector::length(&program_output) > HEADER_SIZE, + length(&program_output) > HEADER_SIZE, ESTARKNET_OUTPUT_TOO_SHORT ); // Validate KZG DA flag assert!( - *vector::borrow(&program_output, USE_KZG_DA_OFFSET) == 0, + *borrow(&program_output, USE_KZG_DA_OFFSET) == 0, EUNEXPECTED_KZG_DA_FLAG ); @@ -146,23 +150,23 @@ module starknet_addr::starknet_validity { let initial_block_number = state_block_number(); assert!( - vector::length(&program_output) > HEADER_SIZE + KZG_SEGMENT_SIZE, + length(&program_output) > HEADER_SIZE + KZG_SEGMENT_SIZE, ESTARKNET_OUTPUT_TOO_SHORT ); assert!( - *vector::borrow(&program_output, USE_KZG_DA_OFFSET) == 1, + *borrow(&program_output, USE_KZG_DA_OFFSET) == 1, EUNEXPECTED_KZG_DA_FLAG ); - let pre_kzg_segment = vector::slice( + let pre_kzg_segment = slice( &program_output, HEADER_SIZE, - vector::length(&program_output) + length(&program_output) ); - let kzg_segment = vector::slice(&pre_kzg_segment, 0u64, KZG_SEGMENT_SIZE); + let kzg_segment = slice(&pre_kzg_segment, 0u64, KZG_SEGMENT_SIZE); verify_kzg_proof(&kzg_segment, &kzg_proof); - let state_transition_fact = keccak256(vec_to_bytes_be(&program_output)); + let state_transition_fact = keccak256(num_to_bytes_le(&program_output)); update_internal_state(s, &program_output, state_transition_fact); // Re-entrancy protection: validate final block number @@ -189,15 +193,15 @@ module starknet_addr::starknet_validity { ) { // Validate config hash. assert!( - *vector::borrow(program_output, CONFIG_HASH_OFFSET) == get_config_hash(), + *borrow(program_output, CONFIG_HASH_OFFSET) == get_config_hash(), EINVALID_CONFIG_HASH ); - let program_hash: vector = num_to_bytes_be(&get_program_hash()); - vector::append(&mut program_hash, state_transition_fact); - let sharp_fact = keccak256(program_hash); + let program_hash: vector = num_to_bytes_le(&get_program_hash()); + append(&mut program_hash, state_transition_fact); + let sharp_fact = bytes32_to_u256(keccak256(program_hash)); assert!( - fact_registry::is_valid(sharp_fact), + is_valid(address_of(s), sharp_fact), ENO_STATE_TRANSITION_PROOF ); @@ -225,21 +229,21 @@ module starknet_addr::starknet_validity { kzg_proof: &vector ) { assert!( - vector::length(kzg_segment) == KZG_SEGMENT_SIZE, + length(kzg_segment) == KZG_SEGMENT_SIZE, EINVALID_KZG_SEGMENT_SIZE ); assert!( - (vector::length(kzg_proof) as u256) == PROOF_BYTES_LENGTH, + (length(kzg_proof) as u256) == PROOF_BYTES_LENGTH, EINVALID_KZG_PROOF_SIZE ); let y; let kzg_commitment; { - let kzg_commitment_low: u256 = *vector::borrow(kzg_segment, 0); - let kzg_commitment_high: u256 = *vector::borrow(kzg_segment, 1); - let y_low: u256 = *vector::borrow(kzg_segment, 3); - let y_high: u256 = *vector::borrow(kzg_segment, 4); + let kzg_commitment_low: u256 = *borrow(kzg_segment, 0); + let kzg_commitment_high: u256 = *borrow(kzg_segment, 1); + let y_low: u256 = *borrow(kzg_segment, 3); + let y_high: u256 = *borrow(kzg_segment, 4); assert!( kzg_commitment_low <= MAX_UINT192, EINVALID_KZG_COMMITMENT @@ -257,20 +261,20 @@ module starknet_addr::starknet_validity { EINVALID_Y_VALUE ); - kzg_commitment = to_bytes_24_be(&bcs::to_bytes(&kzg_commitment_high)); - vector::append(&mut kzg_commitment, to_bytes_24_be(&bcs::to_bytes(&kzg_commitment_low))); + kzg_commitment = to_bytes_24_be(bcs::to_bytes(&kzg_commitment_high)); + append(&mut kzg_commitment, to_bytes_24_be(bcs::to_bytes(&kzg_commitment_low))); - y = num_to_bytes_be(&((y_high << 128) + y_low)); + y = num_to_bytes_le(&((y_high << 128) + y_low)); }; let blob_hash = get_blob_hash(&kzg_commitment); - let z = *vector::borrow(kzg_segment, 2); + let z = *borrow(kzg_segment, 2); - vector::append(&mut blob_hash, num_to_bytes_be(&z)); - vector::append(&mut blob_hash, y); - vector::append(&mut blob_hash, kzg_commitment); - vector::append(&mut blob_hash, *kzg_proof); + append(&mut blob_hash, num_to_bytes_le(&z)); + append(&mut blob_hash, y); + append(&mut blob_hash, kzg_commitment); + append(&mut blob_hash, *kzg_proof); let precompile_output = pre_compile::point_evaluation_precompile(blob_hash); @@ -331,6 +335,13 @@ module starknet_addr::starknet_validity { starknet_state::get_block_number(starknet_storage::get_state(@starknet_addr)) } + #[view] + public fun to_bytes_24_be(bytes: vector): vector { + trim_reverse(&mut bytes, 24); + reverse(&mut bytes); + bytes + } + #[test(s = @starknet_addr)] fun test_submiss_blob(s: &signer) { let state = starknet_state::new( @@ -397,8 +408,8 @@ module starknet_addr::starknet_validity { // This test depends on the value of `fact`, which is precomputed and registered before updating the state. // All test data is taken from transaction 0xe76c6accacbcedb7f66d5dc3f1a3e189d4e4d194ea88c19ee29955adbc902362. - fact_registry::init_fact_registry(s); - fact_registry::register_fact(x"af6d61465fa108b0e7d4d9bef635dec868bcfa8e9fa14c5486c6017cd552fd4c"); + init_fact_registry(s); + register_fact(s, 0xaf6d61465fa108b0e7d4d9bef635dec868bcfa8e9fa14c5486c6017cd552fd4c); let kzg_proof: vector = x"8664b3057bc3aefaf110db484fdc0c422c58209c7f8a331a4c5f853a9e37d0de5f02ec0289d7d0634e49ef813fb8e84d"; update_state_kzg_da(s, program_output, kzg_proof); @@ -440,7 +451,7 @@ module starknet_addr::starknet_validity { // The expected `onchain_data_hash` and `onchain_data_size` may change when simulating the transaction. fact_registry::init_fact_registry(s); - fact_registry::register_fact(x"b7fae2e2b20a6e0c96d4899cbd47f0af865f53afe75a1482ab5d637a89d8aca4"); + fact_registry::register_fact(s,0xb7fae2e2b20a6e0c96d4899cbd47f0af865f53afe75a1482ab5d637a89d8aca4); update_state(s, program_output, onchain_data_hash, onchain_data_size); } } \ No newline at end of file