{"id":13526006,"url":"https://github.com/flyq/jolt_verifier_canister","last_synced_at":"2025-07-20T15:35:49.658Z","repository":{"id":232932271,"uuid":"785554276","full_name":"flyq/jolt_verifier_canister","owner":"flyq","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-14T02:23:14.000Z","size":202,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-14T04:04:14.732Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flyq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-12T05:52:47.000Z","updated_at":"2024-04-15T11:18:43.677Z","dependencies_parsed_at":"2024-04-15T11:18:39.732Z","dependency_job_id":null,"html_url":"https://github.com/flyq/jolt_verifier_canister","commit_stats":null,"previous_names":["flyq/jolt_verifier_canister"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/flyq/jolt_verifier_canister","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyq%2Fjolt_verifier_canister","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyq%2Fjolt_verifier_canister/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyq%2Fjolt_verifier_canister/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyq%2Fjolt_verifier_canister/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flyq","download_url":"https://codeload.github.com/flyq/jolt_verifier_canister/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyq%2Fjolt_verifier_canister/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259426959,"owners_count":22855552,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T06:01:24.269Z","updated_at":"2025-06-12T08:06:04.081Z","avatar_url":"https://github.com/flyq.png","language":"Rust","funding_links":[],"categories":["ZK"],"sub_categories":["TON"],"readme":"# jolt_verifier_canister\n\n## background\n\nA zero-knowledge proof is a way of proving the validity of a statement without revealing the statement itself. The ‘prover’ is the party trying to prove a claim, while the ‘verifier’ is responsible for validating the claim. It provides core technical support in use cases such as private transactions, verifiable computing (Off-chain scaling solutions, aka Layer2).\n\nThanks to the needs arising in the blockchain field, such as zkRollup, private transactions, etc., the theory and engineering in the ZKP field have developed rapidly in recent years. To use the power brought by ZKP, on-chain verifier are almost indispensable. For example, all Ethereum zkRollups has a Verifier implemented using Solidity running on Ethereum Layer1, and when withdrawing Tornado cash, you also need to verify the merkle proof you generated in the Tornado smart contract.\n\nOn April 9th, the A16z crypto team released the fastest zkVM for prover: Jolt(Just One Lookup Table), including [code](https://github.com/a16z/jolt), [examples](https://github.com/a16z/jolt/tree/main/examples), [documents](https://jolt.a16zcrypto.com/), [blogs](https://a16zcrypto.com/posts/tags/lasso-jolt), and papers([Lasso](https://eprint.iacr.org/2023/1216.pdf) and [Jolt](https://eprint.iacr.org/2023/1217.pdf)).\n\n\u003e Jolt is a zkVM (zero knowledge virtual machine) – a SNARK that lets the prover prove that it correctly ran a specified computer program, where the program is written in the assembly language of some simple CPU. zkVMs offer a fantastic developer experience: They make SNARKs usable by anyone who can write a computer program, eliminating the need for in-depth cryptographic knowledge. But usability comes at a steep price. Today’s zkVMs are remarkably complicated and offer terrible performance for the prover. Today, *proving* a computer program was run correctly is millions of times slower than simply *running* the program.\n\u003e \n\u003e from [A new era in SNARK design: Releasing Jolt](https://a16zcrypto.com/posts/article/a-new-era-in-snark-design-releasing-jolt)\n\nAnd the Jolt development team encourages the implementation of [on-chain Verifier](https://github.com/a16z/jolt/issues/209).\n\n[IC(Internet Computer)](https://internetcomputer.org/) is the most powerful smart contract platform I have ever seen. One of its smart contracts can run a complete EVM, including json rpc, processing signatures, and EVM execution and output. Or being able to run a database, a sequencer of Bitcoin inscriptions, etc.\n\nPutting zk's verifier on an IC can bring some benefits:\n1. IC is powerful enough and not so picky about the Verifier program. In fact, there is a balance between the prover and the verifier. Some SNARKs can obtain the smallest proof size and fast verification algorithm, but they are very unfriendly to the prover. Some SNARKs may have a larger proof size and a more complicated verification algorithm. But the performance of the proof program has been greatly improved. Due to the performance limitations of smart contracts, Ethereum can often only verify the former type of SNARK. But Sumcheck-based Jolt falls into the latter category.\n2. IC's smart contract has the most complete support for Rust and can use std, so it can directly reuse the implementation of ZK Library. and reduce potential implementation errors.\n3. IC's chain key ECDSA can directly call platforms such as Ethereum/BTC, and the verification results can also be used to notify Ethereum, etc.\n\nFor code implementation details, refer [here](https://hackmd.io/@liquan/S1dybGcl0).\n\nThe canister is already running on the chain: https://p6xvw-7iaaa-aaaap-aaana-cai.raw.ic0.app/\n\n## How\n\nFor specific programs, Jolt generates their circuits as well as proofs. The circuit is contained in the huge `JoltPreprocessing`, which is about 48MB, and Proof is 500kb-10MB depending on the size of the program. We need to upload `JoltPreprocessing` and `Proof` in parts first, then assemble them in Canister, and then call verifier to verify them.\n\nFor example, for the Fibonacci function, its `JoltPreprocessing` is certain, so when verifying `fib(10)` and `fib(50)`, use the same `JoltPreprocessing` and different `Proof`s to verify.\n\n## Requirement\n\n[ic-wasm](https://github.com/dfinity/ic-wasm)\n```sh\ncargo install ic-wasm -f\n```\n\n## Build\n\n```sh\ngit clone https://github.com/flyq/jolt_verifier_canister\n\ncd jolt_verifier_canister\n\ncargo run --features \"export-api\" \u003e build/jolt_verifier_canister.did\n\ncargo build --target wasm32-unknown-unknown --release --features \"export-api\"\n\nic-wasm target/wasm32-unknown-unknown/release/jolt_verifier_canister.wasm -o build/jolt_verifier_canister.wasm shrink\n```\n\n## Deploy\nteminal 1:\n```sh\ndfx start --clean\n```\n\nteminal 2:\n```sh\ndfx canister create --no-wallet jolt_verifier_canister\n\ndfx build jolt_verifier_canister\n\ndfx canister install jolt_verifier_canister --argument \"record { owner=principal \\\"$(dfx identity get-principal)\\\";}\"\n\n# dfx canister install jolt_verifier_canister --argument \"record { owner=principal \\\"yhy6j-huy54-mkzda-m26hc-yklb3-dzz4l-i2ykq-kr7tx-dhxyf-v2c2g-tae\\\"; ecdsa_env=variant {TestKeyLocalDevelopment}}\" --upgrade-unchanged -m=upgrade \n\ndfx canister call jolt_verifier_canister get_owner\n```\n\n## Test\n\ngenenrate proof: \n\nterminal 2:\n```sh\ncd ..\n\ngit clone https://github.com/flyq/jolt\n\ncd jolt\n\ncargo run --release -p fibonacci\n\ncargo run --release -p sha2-chain\n\ncargo run --release -p sha2-ex\n\ncargo run --release -p sha3-chain\n\ncargo run --release -p sha3-ex\n```\n\nand we can get the proof files: fib10 and so on.\ncopy the file to `./data/fib`, `./data/sha2`, `data/sha2_chain`, `data/sha3`, `data/sha3_chain`.\n\nalso we get the risc-v compiled result under `ls /tmp/jolt-guest-*`.\n\n\ngenerate the data according proof:\n\n```sh\ncargo run --release -p helper generate_preprocess guest fib\ncargo run --release -p helper generate_preprocess sha2-chain-guest sha2_chain\ncargo run --release -p helper generate_preprocess sha2-guest sha2\ncargo run --release -p helper generate_preprocess sha3-chain-guest sha3_chain\ncargo run --release -p helper generate_preprocess sha3-guest sha3\n\ncargo run --release -p helper check_split\n\n```\n\nupload data\n```sh\ncargo run --release -p helper upload_preprocess\n\ndfx canister call jolt_verifier_canister get_buffer '(24:nat32)'\n\n# fibonacci(0), sha2_chain(1), sha2_ex(2), sha3_chain(3), sha3_ex(4)\ndfx canister call jolt_verifier_canister preprocessing '(24:nat32, 0:nat32)'\n\ndfx canister call jolt_verifier_canister get_buffer '(24:nat32)'\n\n# modify helper/src/main.rs's upload_preprocess to `let name = format!(\"data/sha2/p{}.bin\", i);`\ncargo run --release -p helper upload_preprocess\n\ndfx canister call jolt_verifier_canister get_buffer '(24:nat32)'\n\n# sha2_ex(2)\ndfx canister call jolt_verifier_canister preprocessing '(24:nat32, 2:nat32)'\n\ndfx canister call jolt_verifier_canister get_buffer '(24:nat32)'\n\n# modify helper/src/main.rs's upload_preprocess to `let name = format!(\"data/sha2_chain/p{}.bin\", i);`\ncargo run --release -p helper upload_preprocess\n\n# sha2_chain(1)\ndfx canister call jolt_verifier_canister preprocessing '(24:nat32, 1:nat32)'\n\n# modify helper/src/main.rs's upload_preprocess to `let name = format!(\"data/sha3_chain/p{}.bin\", i);`\ncargo run --release -p helper upload_preprocess\n\n# sha3_chain(3)\ndfx canister call jolt_verifier_canister preprocessing '(24:nat32, 3:nat32)'\n\n# modify helper/src/main.rs's upload_preprocess to `let name = format!(\"data/sha3/p{}.bin\", i);`\ncargo run --release -p helper upload_preprocess\n\n# sha3(4)\ndfx canister call jolt_verifier_canister preprocessing '(24:nat32, 4:nat32)'\n\n\n\n# let name = format!(\"data/fib/fib10.bin\");\ncargo run --release -p helper upload_proof\n\n# fibonacci(0), sha2_chain(1), sha2_ex(2), sha3_chain(3), sha3_ex(4)\ndfx canister call jolt_verifier_canister update_proof '(0:nat32, 0:nat32)'\n# (variant { Ok = 0 : nat32 })\n\n# let name = format!(\"data/fib/fib50.bin\");\ncargo run --release -p helper upload_proof\n\n# fibonacci(0), sha2_chain(1), sha2_ex(2), sha3_chain(3), sha3_ex(4)\ndfx canister call jolt_verifier_canister update_proof '(0:nat32, 0:nat32)'\n# (variant { Ok = 1 : nat32 })\n\n# let name = format!(\"data/sha2/sha2.bin\");\ncargo run --release -p helper upload_proof\n\n# fibonacci(0), sha2_chain(1), sha2_ex(2), sha3_chain(3), sha3_ex(4)\ndfx canister call jolt_verifier_canister update_proof '(0:nat32, 2:nat32)'\n# (variant { Ok = 0 : nat32 })\n\n# let name = format!(\"data/sha3/sha3.bin\");\ncargo run --release -p helper upload_proof\n\n# fibonacci(0), sha2_chain(1), sha2_ex(2), sha3_chain(3), sha3_ex(4)\ndfx canister call jolt_verifier_canister update_proof '(0:nat32, 4:nat32)'\n# (variant { Ok = 0 : nat32 })\n\n# fib(10)\ndfx canister call jolt_verifier_canister verify_jolt_proof '(0:nat32, 0:nat32)'\n(variant { Ok = true })\n\n# fib(50)\ndfx canister call jolt_verifier_canister verify_jolt_proof '(0:nat32, 1:nat32)'\n\n# sha2\ndfx canister call jolt_verifier_canister verify_jolt_proof '(2:nat32, 0:nat32)'\n\nError: Failed update call.\nCaused by: Failed update call.\n  The replica returned a rejection error: reject code CanisterError, reject message Canister bnz7o-iuaaa-aaaaa-qaaaa-cai exceeded the instruction limit for single message execution., error code None\n\n# sha3\ndfx canister call jolt_verifier_canister verify_jolt_proof '(4:nat32, 0:nat32)'\n\nError: Failed update call.\nCaused by: Failed update call.\n  The replica returned a rejection error: reject code CanisterError, reject message Canister bnz7o-iuaaa-aaaaa-qaaaa-cai exceeded the instruction limit for single message execution., error code None\n```\n\nIt can be seen that the verification of sha2 and sha3 does need to wait for [the optimization of Verifier](https://github.com/a16z/jolt/issues/216)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflyq%2Fjolt_verifier_canister","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflyq%2Fjolt_verifier_canister","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflyq%2Fjolt_verifier_canister/lists"}