{"id":47217730,"url":"https://github.com/zksecurity/evm-asm","last_synced_at":"2026-03-13T16:35:33.171Z","repository":{"id":339498119,"uuid":"1151747720","full_name":"zksecurity/evm-asm","owner":"zksecurity","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-11T04:59:46.000Z","size":936,"stargazers_count":4,"open_issues_count":6,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-11T10:54:48.960Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Lean","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zksecurity.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,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-06T21:10:38.000Z","updated_at":"2026-03-11T06:44:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zksecurity/evm-asm","commit_stats":null,"previous_names":["zksecurity/evm-asm"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zksecurity/evm-asm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zksecurity%2Fevm-asm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zksecurity%2Fevm-asm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zksecurity%2Fevm-asm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zksecurity%2Fevm-asm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zksecurity","download_url":"https://codeload.github.com/zksecurity/evm-asm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zksecurity%2Fevm-asm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30471103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T11:00:43.441Z","status":"ssl_error","status_checked_at":"2026-03-13T11:00:23.173Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":"2026-03-13T16:35:32.191Z","updated_at":"2026-03-13T16:35:33.148Z","avatar_url":"https://github.com/zksecurity.png","language":"Lean","funding_links":[],"categories":[],"sub_categories":[],"readme":"# evm.asm: A Verified Macro Assembler for building zkEVM in Lean 4 (early experiment)\n\nA prototype implementation of a verified macro assembler targeting the zkEVM,\nbuilt on RISC-V backends (RV64IM primary, RV32IM secondary), inspired by:\n\n\u003e Andrew Kennedy, Nick Benton, Jonas B. Jensen, Pierre-Evariste Dagand.\n\u003e **\"Coq: The world's best macro assembler?\"**\n\u003e *Proceedings of the 15th International Symposium on Principles and Practice\n\u003e of Declarative Programming (PPDP 2013)*, September 2013, ACM.\n\u003e https://www.microsoft.com/en-us/research/publication/coq-worlds-best-macro-assembler/\n\n## ⚠️ Warning: Experimental Prototype Only\n\n**DO NOT USE THIS PROJECT FOR ANYTHING OF VALUE.**\n\nThis is an experimental research prototype with significant limitations:\n\n- **No RISC-V spec compliance**: The instruction semantics are vibe-generated and\n  have NOT been validated against the official RISC-V specification. There may\n  be subtle (or not-so-subtle) deviations from actual RISC-V behavior.\n- **No EVM spec compliance**: The specs for examples are also vibe-generated and\n  have NOT been validated against the EVM specification.\n- **No conformance testing**: No systematic testing has been performed to verify\n  that this implementation matches real RISC-V processors or simulators. No testing has been performed against EVM either.\n- **Prototype quality**: This code is for educational and research purposes to\n  explore verified macro assembly techniques, not for production use.\n\n## Motivation: Eliminating Compiler Trust in zkEVM\n\nThe usual way to use zkVMs is to compile high-level programs to RISC-V\nassembly, then prove correctness of the execution trace using a zero-knowledge\nproof system. The proof covers the *execution trace*, but it cannot cover the\n*compiler*. If the compiler is buggy or malicious, the proof might not\nmatch the developer's (or the receiver's) intent, even though the ZK proof is valid, and even if the\nsource code is correct.\n\n**evm.asm** explores an alternative: write programs directly as RISC-V code,\nand *prove* their correctness in Lean 4 before the ZK proof is ever\ngenerated. The goal is that a developer (or a receiver of a ZK proof) never has to trust a compiler\nfor the guest program.\n\nMore specifically, evm.asm aims at building the guest part of the **zkEVM**. Reducing trusted computing base matters for this usage.\n\n## Key Idea\n\nLean 4 serves simultaneously as:\n\n1. **An assembler**: Instructions are an inductive type; programs are lists of\n   instructions with sequential composition (`;;`).\n2. **A macro language**: Lean functions that produce programs act as macros,\n   using all of Lean's facilities (recursion, pattern matching, conditionals).\n3. **A specification language**: Hoare triples with separation logic assertions\n   express correctness properties of EVM opcodes and macro compositions.\n4. **A proof assistant**: Lean's kernel verifies that macros meet their\n   specifications, with no external oracle required.\n\n## The `add_mulc` Macro\n\nThe simplest example is `add_mulc` (inspired by \"Coq: The world's best macro assembler?\" cited above), a macro that multiplies a register by a\ncompile-time constant using the shift-and-add algorithm:\n\n```lean\ndef add_mulc (nbits : Nat) (rd rs : Reg) (m : Nat) : Program :=\n  match nbits with\n  | 0 =\u003e prog_skip\n  | nbits' + 1 =\u003e\n    if m % 2 == 1 then\n      ADD rd rd rs ;;\n      SLLI rs rs 1 ;;\n      add_mulc nbits' rd rs (m / 2)\n    else\n      SLLI rs rs 1 ;;\n      add_mulc nbits' rd rs (m / 2)\n```\n\nThe specification uses separating conjunction:\n\n```lean\ntheorem add_mulc_spec (m nbits : Nat) (hm : m \u003c 2 ^ nbits)\n    (rd rs : Reg) (hrd : rd ≠ .x0) (hrs : rs ≠ .x0)\n    (v w : Word) :\n    ⦃(rd ↦ᵣ v) ** (rs ↦ᵣ w)⦄\n    add_mulc nbits rd rs m\n    ⦃fun s =\u003e s.getReg rd = v + w * BitVec.ofNat 32 m⦄\n```\n\n## Project Structure\n\n```\nEvmAsm/\n  Rv64/                       -- RV64IM backend (primary)\n    Basic.lean                --   Machine state: registers (64-bit), memory, PC\n    Instructions.lean         --   RV64IM instruction set and semantics\n    Program.lean              --   Programs as instruction lists, sequential composition\n    Execution.lean            --   Branch-aware execution, code memory, step/stepN\n    SepLogic.lean             --   Separation logic assertions and combinators\n    CPSSpec.lean              --   CPS-style Hoare triples, branch specs, structural rules\n    ControlFlow.lean          --   if_eq macro, symbolic proofs, pcIndep\n    GenericSpecs.lean         --   Generic specs parameterized over instructions\n    InstructionSpecs.lean     --   Per-instruction CPS specs\n    SyscallSpecs.lean         --   Syscall specs: HALT, WRITE, HINT_READ\n    Tactics/\n      XPerm.lean              --   xperm tactic: AC-permutation of sepConj chains\n      XSimp.lean              --   xperm_hyp/xsimp tactics: assertion implication\n      XCancel.lean            --   xcancel tactic: cancellation with frame extraction\n      SeqFrame.lean           --   seqFrame tactic: auto frame+compose cpsTriple specs\n      LiftSpec.lean           --   liftSpec tactic: lift instruction specs\n      RunBlock.lean           --   runBlock tactic: block execution automation\n      SpecDb.lean             --   Spec database for tactic lookup\n  Rv32/                       -- RV32IM backend (secondary, parallel structure)\n    Basic.lean ... Tactics/   --   Same modules as Rv64, 32-bit word size\n    MulMacro.lean             --   The add_mulc macro with correctness proofs\n  Evm64/                      -- EVM opcodes on RV64IM (primary, 4×64-bit limbs, 18 files)\n    Basic.lean                --   EvmWord (BitVec 256), getLimb64, fromLimbs64\n    Stack.lean                --   evmWordIs, evmStackIs, pcFree lemmas\n    StackOps.lean             --   POP, PUSH0, DUP1, SWAP1, generic DUPn/SWAPn\n    Bitwise.lean              --   AND/OR/XOR/NOT programs + per-limb specs\n    And.lean                  --   Full 256-bit AND spec\n    Or.lean                   --   Full 256-bit OR spec\n    Xor.lean                  --   Full 256-bit XOR spec\n    Not.lean                  --   Full 256-bit NOT spec\n    Arithmetic.lean           --   ADD/SUB programs + per-limb specs\n    Add.lean                  --   Full 256-bit ADD spec\n    Sub.lean                  --   Full 256-bit SUB spec\n    Comparison.lean           --   LT/GT/EQ/ISZERO programs + per-limb specs\n    Lt.lean                   --   Full 256-bit LT spec\n    Gt.lean                   --   Full 256-bit GT spec\n    Eq.lean                   --   Full 256-bit EQ spec\n    IsZero.lean               --   Full 256-bit ISZERO spec\n    Shift.lean                --   SHR program + per-limb specs\n    ShiftSpec.lean            --   Full 256-bit SHR spec\n    zkvm-standards/           --   Submodule: zkVM RISC-V target standards\n  Evm32/                      -- EVM opcodes on RV32IM (secondary, 8×32-bit limbs, 15 files)\n    Basic.lean ... StackOps.lean  -- Same opcodes as Evm64, 32-bit limbs\n    Shift.lean                --   SHR program + per-limb specs\n    ShiftSpec.lean            --   Full 256-bit SHR spec\n    ShiftComposition.lean     --   SHR shift composition (1 sorry)\n  Examples/                   -- 12 example files\n    Swap.lean                 --   Register swap macro\n    Zero.lean                 --   Zero-register macro\n    Multiply.lean             --   Multiply-by-constant examples\n    LoadModifyStore.lean      --   Load-modify-store pattern\n    Combining.lean            --   Combining multiple macros\n    Halting.lean              --   HALT/ECALL termination examples\n    Commit.lean               --   COMMIT syscall example\n    Write.lean                --   WRITE syscall example\n    FullPipeline.lean         --   End-to-end pipeline example\n    HelloWorld.lean           --   Hello world program\n    HelloWorldSpec.lean       --   Hello world correctness proof\n    Echo.lean                 --   Echo program with CPS spec\nEvmAsm.lean                  -- Top-level module hub\nEvmAsm/Rv64.lean             -- Rv64 module hub\nEvmAsm/Rv32.lean             -- Rv32 module hub\nEvmAsm/Examples.lean         -- Examples module hub\nexecution-specs/              -- Submodule: Ethereum execution specs (uninitialized)\n```\n\n## Lean Toolchain\n\n```\nleanprover/lean4:v4.29.0-rc1\n```\n\n## Building\n\n```bash\n# Install elan (Lean version manager) if not already installed\ncurl -sSf https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh | sh\n\n# download Mathlib cache (optional, recommended)\nlake exec cache get\n\n# Build the project\nlake build\n```\n\n## Status\n\nThis is a **prototype** demonstrating the approach. Current state:\n\n- **Infrastructure**: Two complete RISC-V backends (RV64IM, RV32IM) with\n  separation logic, CPS-style Hoare triples, and automated tactics\n  (`xperm`, `xcancel`, `seqFrame`, `liftSpec`, `runBlock`).\n- **Evm64 (primary, 0 sorry)** — targets `riscv64im_zicclsm-unknown-none-elf`,\n  4×64-bit limbs, 15 fully-proved opcodes:\n  AND, OR, XOR, NOT, ADD, SUB, LT, GT, EQ, ISZERO, SHR,\n  POP, PUSH0, DUP1, SWAP1 (+ generic DUPn/SWAPn for 1 ≤ n ≤ 16)\n- **Evm32 (secondary, 1 sorry)** — 8×32-bit limbs, same 15 opcodes;\n  one sorry remains in `ShiftComposition.lean`.\n- **Proved (examples)**: `add_mulc`, register swap, hello world, echo,\n  HALT/COMMIT termination, load-modify-store, full pipeline.\n- **TODO**: More opcodes (MUL, DIV, MOD, SHL, SAR, MLOAD, MSTORE),\n  interpreter loop, state transition function, connect to sail-riscv-lean\n  for RISC-V spec compliance, connect to EVM specs in Lean, testing.\n\n## References\n\n- Kennedy, A., Benton, N., Jensen, J.B., Dagand, P.-E. (2013).\n  \"Coq: The world's best macro assembler?\" PPDP 2013.\n  https://www.microsoft.com/en-us/research/publication/coq-worlds-best-macro-assembler/\n- **SPlean** (Separation Logic Proofs in Lean), Verse Lab.\n  https://github.com/verse-lab/splean\n  The `xperm` / `xperm_hyp` / `xsimp` tactics in `Tactics/` are inspired by\n  SPlean's `xsimpl` tactic.\n- Charguéraud, A. (2020). \"Separation Logic for Sequential Programs\n  (Functional Pearl).\" *Proc. ACM Program. Lang.* 4, ICFP, Article 116.\n  https://doi.org/10.1145/3408998\n- **bedrock2**: https://github.com/mit-plv/bedrock2\n  The frame automation tactics (`xcancel`, `seqFrame`) in `Tactics/XCancel.lean`\n  and `Tactics/SeqFrame.lean` are inspired by bedrock2's separation logic\n  automation. Specifically:\n  - The `wcancel` tactic in `bedrock2/src/bedrock2/SepLogAddrArith.v` (lines 127-134)\n    inspired the cancellation approach: matching atoms by tag+address, computing\n    the frame as the residual of unmatched hypothesis atoms.\n  - The frame rule infrastructure in `bedrock2/src/bedrock2/FrameRule.v` (lines 75-175)\n    inspired the automatic frame extraction pattern where specs include a universal\n    frame parameter and tactics instantiate it during composition.\n  - The instruction specs with explicit frame in `compiler/src/compiler/GoFlatToRiscv.v`\n    (lines 439-546) informed the design of composing instruction specs with\n    `cpsTriple_frame_left` + `cpsTriple_seq_with_perm`.\n- Knuth, D.E. (1997). *The Art of Computer Programming, Volume 2:\n  Seminumerical Algorithms* (3rd ed.), §4.3.1 \"The Classical Algorithms.\"\n  Addison-Wesley. Algorithm D is used for the DIV/MOD opcodes in `Evm64/DivMod.lean`.\n- SP1 zkVM: https://github.com/succinctlabs/sp1\n  The `ECALL`-based syscall mechanism follows SP1's conventions.\n- zkvm-standards: https://github.com/eth-act/zkvm-standards\n  Tentative standards for zkVM RISC-V target, I/O interface, and C-interface accelerators.\n- sail-riscv-lean: https://github.com/opencompl/sail-riscv-lean\n- RISC-V ISA specification: https://riscv.org/technical/specifications/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzksecurity%2Fevm-asm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzksecurity%2Fevm-asm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzksecurity%2Fevm-asm/lists"}