{"id":13681037,"url":"https://github.com/MarbleHE/HECO","last_synced_at":"2025-04-30T03:30:30.173Z","repository":{"id":37861745,"uuid":"226130489","full_name":"MarbleHE/HECO","owner":"MarbleHE","description":"Optimizing compiler for Fully Homomorphic Encryption (FHE)","archived":false,"fork":false,"pushed_at":"2024-07-24T20:40:15.000Z","size":19424,"stargazers_count":72,"open_issues_count":0,"forks_count":18,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-04-15T09:30:37.581Z","etag":null,"topics":["compiler","fhe","fhe-compiler","fully-homomorphic-encryption","homomorphic-encryption"],"latest_commit_sha":null,"homepage":"","language":"MLIR","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/MarbleHE.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":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-05T15:17:20.000Z","updated_at":"2025-04-02T04:09:30.000Z","dependencies_parsed_at":"2024-01-14T15:26:14.131Z","dependency_job_id":"52b4d3c0-861d-47ad-8549-399aaf8d52d6","html_url":"https://github.com/MarbleHE/HECO","commit_stats":{"total_commits":1576,"total_committers":11,"mean_commits":"143.27272727272728","dds":0.641497461928934,"last_synced_commit":"329a633275a2c5539cca5ac35ce863d7cb8cd2ce"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarbleHE%2FHECO","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarbleHE%2FHECO/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarbleHE%2FHECO/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MarbleHE%2FHECO/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MarbleHE","download_url":"https://codeload.github.com/MarbleHE/HECO/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251634991,"owners_count":21619122,"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":["compiler","fhe","fhe-compiler","fully-homomorphic-encryption","homomorphic-encryption"],"created_at":"2024-08-02T13:01:25.344Z","updated_at":"2025-04-30T03:30:29.320Z","avatar_url":"https://github.com/MarbleHE.png","language":"MLIR","funding_links":[],"categories":["Implementation"],"sub_categories":["Related work"],"readme":"\u003e **Note**\n\u003e Welcome to the Artifact Evaluation version of HECO!   \n\nHECO is an end-to-end compiler for FHE that takes high-level imperative programs and emits efficient and secure FHE implementations.\nCurrently, it supports Ring-LWE based schemes [B](https://eprint.iacr.org/2012/078)/[FV](https://eprint.iacr.org/2012/144), [BGV](https://eprint.iacr.org/2011/277) and [CKKS](https://eprint.iacr.org/2016/421) which offer powerful SIMD-like operations and can _batch_ many thousands of values into a single vector-like ciphertext.\n\n- [About HECO](#about-heco)\n- [Using HECO](#using-heco)\n  - [Modes](#modes)\n    - [Interactive Mode](#interactive-mode)\n    - [Transpiler Mode](#transpiler-mode)\n    - [Compiler Mode](#compiler-mode)\n- [Installation](#installation)\n  - [Prerequisites](#prerequisites)\n  - [Dependencies](#dependencies)\n  - [Building](#building)\n- [Development](#development)\n  - [Development Environemnt](#development-environemnt)\n  - [Repository's Structure](#repositorys-structure)\n  - [Development Tips for working with MLIR-based Projects](#development-tips-for-working-with-mlir-based-projects)\n    - [Working with TableGen](#working-with-tablegen)\n    - [Debugging MLIR](#debugging-mlir)\n\n\n# About HECO\nIn FHE (and other advanced cryptographic techniques such as MPC or ZKP), developers must express their applications as an (arithmetic/binary) circuit. Translating a function *f* so that the resulting circuit can be evaluated efficiently is highly non-trivial and doing so manually requires significant expert knowledge. This is where FHE compilers like HECO come in, by automating the transformation of high-level programs into lower-level representations that can be evaluated using FHE.\n\nHECO's design and novel optimizations are described in the accompanying [paper](https://arxiv.org/abs/2202.01649).\nIn contrast to previous compilers, HECO removes a significant burden from the developer by automating the task of translating a program to the restricted SIMD programming paradigm available in FHE. This can result in speeupds by over an order of magnitude (i.e., 10x or more) when compared to a naive baseline.\n\nHECO is built using the [MLIR](https://mlir.llvm.org/) compiler framework and follows a traditional front-, middle- and back-end architecture. It uses two Intermediate Representations (IRs) in the middle-end, High-level IR (HIR) to express programs containing control flow and an abstraction of FHE computing (`heco::fhe`). \nThis is then lowered to Scheme-specific IR (SIR), with operations corresponding to the FHE schemes' underlying operations (e.g., addition, multiplication, relineraization, etc.). Currently, HECO targets [Microsoft SEAL](https://github.com/Microsoft/SEAL) as its backend. In the future, HECO will be extended with Polynomial-level IR (PIR) and RNS IR (RIR) to directly target hardware (both CPUs and dedicated FHE accelerators).\n\n![Architecture Overview of the Dialects](docs/heco_architecture.jpg)\n\n# Using HECO\n\n## Python Frontend\n\n\u003e **Note**\n\u003e HECO's original Python Frontend has been deprecated in favour of using the upcoming [xDSL](https://github.com/xdslproject/xdsl) frontend system.\n\u003e We are working on extending the frontend with more functionality and completing the toolchain, such that frontend programs can be executed again.\n\n## Modes\nHECO can be used in three distinct modes, each of which target different user needs.\n\n### Transpiler Mode\nIn transpiler mode, HECO outputs a `*.cpp` source file that can be inspected or modified before compiling \u0026 linking against SEAL. HECO performs the usual high-level optimizations and lowers the program to the Scheme-specific Intermediate Representation (SIR). This is then lowered to the MLIR `emitC` Dialect, with FHE operations translated to function calls to a SEAL wrapper. The resulting IR is then translated into an actual `*.cpp` file.\n\nTranspiler mode is designed for advanced users that want to integrate the output into larger, existing software projects and/or modify the compiled code to better match their requirements.\n\n\u003e In order to use the transpiler mode, you need to modify the default compilation pipeline (assuming you are starting with an `*.mlir` file containing HIR, this would be `heco --full-pass [filename_in].mlir`) in two ways. \n\u003e  1. Specify the scheme (and some core parameters) to be used by adding, e.g., `--fhe2bfv=poly_mod_degree=1024` and the corresponding lowering to emitC, e.g., `--bfv2emitc`, each followed by `--canonicalize` and `--cse` to clean up redundant operations introduced by the lowering.\n\u003e  2. Translate to an actual `*.cpp` file by passing the output through  `emitc-translate` \n\u003e\n\u003e A full example might look like this:  `heco --hir-pass --fhe2bfv=poly_mod_degree=1024 --canonicalize --cse --bfv2emitc --canonicalize --cse [filename_in].mlir \u003e emitc-translate --mlir-to-cpp \u003e [filename_out].cpp`.\n\u003e\n\u003e In order to compile the file, you will need to include [`wrapper.cpp.inc`](test/IR/BFV/wrapper.cpp.inc) into the file and link it against SEAL (see [`CMakeLists.txt`](test/IR/BFV/CMakeLists.txt)).  Note that the current wrapper assumes (for slightly obscure reasons) that the generated code is inside a function  `seal::Ciphertext trace()`. If this was not the case for your input, you might need to adjust the wrapper. By default, it currently serializes the result of the function into a file `trace.ctxt`.\n\n### Interactive Mode\nIn  interactive mode, an interpreter consumes both the input data and the intermediate representation. HECO performs the usual high-level optimizations and lowers the program to \nthe Scheme-specific Intermediate Representation (SIR).\nThis is then executed by the interpreter by calling suitable functions in SEAL.\n\nThis mode is designed to be easy-to-use and to allow rapid prototyping. While there is a performance overhead due to the interpreted nature of this mode, it should be insignificant in the context of FHE computations.\n\n\u003e **Note**\n\u003e Interactive mode will become available when the new Python frontend is finished.\n\n### Compiler Mode\nIn compiler mode, HECO outputs an exectuable. In this mode, HECO performs the usual high-level optimizations and lowers the program to the Scheme-specific Intermediate Representation (SIR). This is then lowered to LLVM IR representing function calls to SEAL's C API, which is then compiled and linked against SEAL.\n\nCompiler mode assumes that the input to HECO is a complete program, e.g., has a valid `main()` function. As a result, any input/output behaviour must be realized through the `LoadCiphertext`/`SaveCiphertext` operations in the scheme-specific IR.\n\nCompiler mode is designed primarily for situations where HECO-compiled applications will be automatically deployed without developer interaction, such as in continous integration or other automated tooling.\n\n\u003e **Note**\n\u003e Compiler mode is not yet implemented. If you require an executable, please use Transpiler mode and subsequent manual compilation \u0026 linking for now.\n\n# Installation\nHECO uses CMake as its build system for its C++ components and follows MLIR/LLVM conventions.\n\n## Prerequisites\n\nInstall `cmake` and `clang`. In addition, you will need `lld` and `ninja` in order to compile the MLIR framework.\nOn Ubuntu, this can be done by running the following:\n\n```sh\nsudo apt-get install cmake clang lld ninja-build\n```\n\nIf the version of `cmake` provided by your package manager is too old (\u003c3.20), you might need to [manually install](https://askubuntu.com/a/976700) a newer version.\n\n\n## Dependencies\n\nHECO includes two dependencies (the [Microsoft SEAL](https://github.com/microsoft/seal) FHE library, and the [MLIR](https://mlir.llvm.org/) compiler framework) as git submodules, which you need to initialize after cloning:\n```sh\ngit submodule update --init --recursive --progress\n```\n\nFor normal use and evaluation, build MLIR and SEAL in Release Mode:  \n\u003cdetails\u003e\n\u003csummary\u003eUnfold this to see instructions for developer friendly installation instead!\u003c/summary\u003e\n\n\u003eThe following is a reasonable start for a \"Developer Friendly\" installation of MLIR.  \n\u003eNote that it uses [`ccache`](https://ccache.dev/) in order to speed up follow-up compilations, and it is highly recommended to install and set up [`ccache`](https://ccache.dev/) as it can save significant time when re-compiling.\n\u003eIt also uses the [`mold`](https://github.com/rui314/mold) linker instead of `lld` as the former provides a significant performance boost.\n\u003e```sh\n\u003emkdir dependencies/llvm-project/build\n\u003e\n\u003ecd dependencies/llvm-project/build\n\u003e\n\u003ecmake -G Ninja ../llvm \\\n\u003e  -DLLVM_ENABLE_PROJECTS=mlir \\\n\u003e  -DLLVM_BUILD_EXAMPLES=OFF \\\n\u003e  -DLLVM_TARGETS_TO_BUILD=X86 \\\n\u003e  -DCMAKE_BUILD_TYPE=Debug \\\n\u003e  -DLLVM_ENABLE_ASSERTIONS=ON \\\n\u003e  -DCMAKE_C_COMPILER=clang \\\n\u003e  -DCMAKE_CXX_COMPILER=clang++ \\\n\u003e  -DCMAKE_EXE_LINKER_FLAGS_INIT=\"-fuse-ld=mold\" \\\n\u003e  -DCMAKE_MODULE_LINKER_FLAGS_INIT=\"-fuse-ld=mold\" \\\n\u003e  -DCMAKE_SHARED_LINKER_FLAGS_INIT=\"-fuse-ld=mold\" \\\n\u003e  -DLLVM_CCACHE_BUILD=ON \\\n\u003e  -DLLVM_INSTALL_UTILS=ON \\\n\u003e  -DMLIR_INCLUDE_INTEGRATION_TESTS=ON\n\u003e\n\u003ecmake --build . --target check-mlir\n\u003e\n\u003ecd ../../SEAL\n\u003e\n\u003ecmake -S . -B build\n\u003ecmake --build build\n\u003esudo cmake --install build\n\u003e\n\u003e cd ../..\n\u003e```\n\u003c/details\u003e\n\n\n```sh\nmkdir dependencies/llvm-project/build\n\ncd dependencies/llvm-project/build \n\ncmake -G Ninja ../llvm \\\n-DLLVM_ENABLE_PROJECTS=mlir \\\n-DLLVM_BUILD_EXAMPLES=OFF \\\n-DLLVM_TARGETS_TO_BUILD=X86 \\\n-DCMAKE_BUILD_TYPE=Release \\\n-DLLVM_ENABLE_ASSERTIONS=OFF \\\n-DCMAKE_C_COMPILER=clang \\\n-DCMAKE_CXX_COMPILER=clang++ \\\n-DLLVM_ENABLE_LLD=ON \\\n-DLLVM_CCACHE_BUILD=OFF \\\n-DLLVM_INSTALL_UTILS=ON \\\n-DMLIR_INCLUDE_INTEGRATION_TESTS=OFF\n\ncmake --build . --target check-mlir \n\ncd ../../SEAL\n\ncmake -S . -B build\ncmake --build build\nsudo cmake --install build\n\ncd ../..\n```\n\n## Building\n\nThis setup assumes that you have built MLIR as described above. To build, run the following from the repository root:\n\u003cdetails\u003e\n\u003csummary\u003eUnfold this to see instructions for developer friendly build instead!\u003c/summary\u003e\n\n\u003e\n\u003eThis builds in Debug mode and uses [`ccache`](https://ccache.dev/) and [`mold`](https://github.com/rui314/mold) to speed up compilation.\n\u003e```sh\n\u003emkdir build\n\u003ecmake -S . -B build -DCMAKE_BUILD_TYPE=Debug \\\n\u003e    -DCMAKE_C_COMPILER=clang \\\n\u003e    -DCMAKE_CXX_COMPILER=clang++ \\\n\u003e    -DCMAKE_EXE_LINKER_FLAGS_INIT=\"-fuse-ld=mold\" \\\n\u003e    -DCMAKE_MODULE_LINKER_FLAGS_INIT=\"-fuse-ld=mold\" \\\n\u003e    -DCMAKE_SHARED_LINKER_FLAGS_INIT=\"-fuse-ld=mold\" \\\n\u003e    -DMLIR_DIR=dependencies/llvm-project/build/lib/cmake/mlir\n\u003ecmake --build build --target heco\n\u003e```\n\u003c/details\u003e\n\n```sh\nmkdir build\ncmake -S . -B build -DMLIR_DIR=dependencies/llvm-project/build/lib/cmake/mlir \ncmake --build build --target heco\n```\nTo build the documentation from the TableGen description of the dialect operations, run\n```sh\ncmake --build build --target mlir-doc\n```\nAlternatively, you can open this folder in vscode. You will want to build the `check-heco` target if you want to run the tests, or the `heco` target if you just want to build the command-line compiler.\n\u003e **Note**\n\u003e The `/test` folder is not currently maintained. Instead of running `check-heco`, please refer to `/evaluation`, which contains the tests/benchmarks for the USENIX Artifact Evaluation version of HECO!  \n\n# Development\n Please see MLIR's [Getting Started](https://mlir.llvm.org/getting_started/) for more details on MLIR/LLVM conventions.\n\n## Development Environemnt\n[Visual Studio Code](https://code.visualstudio.com/) is recommended. Remember to set the `-DMLIR_DIR=...` and `-DLLVM_EXTERNAL_LIT=..` options in \"Settings \u0026rarr; Workspace \u0026rarr; Cmake: Configure Args\".\nThe [MLIR](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-mlir) plugin provides syntax highlighting for `*.mlir` files, which are MLIR programs in textual representation and  `*.td` files, which are used to define Dialects, Types, Operations and Rewrite Rules.\n\n## Repository's Structure\n\nThe repository is organized as follow:\n\n```\ncmake           - configuration files for the CMake build system\ndependencies    - git submodules for SEAL and MLIR\ndocs            - additional files for Documentation\ninclude         – header (.h) and TableGen (.td) files\n └ IR             – contains the different dialect definitions\n └ Passes         – contains the definitions of the different transformations\nsrc             – source files (.cpp)\n └ IR             – implementations of additional dialect-specific functionality\n └ Passes         – implementations of the different transformations\n └ tools          – sources for the main commandline interface\ntest            – test \u0026 evaluation code\n```\n\n\n## Development Tips for working with MLIR-based Projects\n[MLIR](https://mlir.llvm.org/) is an incredibly powerful tool and makes developing optimizing compilers significantly easier. \nHowever, it is not necessarily an easy-to-pick-up tool, e.g., documentation for the rapdily evolving framework is not yet sufficient in many places.\nThis short section cannot replace a thorough familiarization with the [MLIR Guide](https://mlir.llvm.org/getting_started/).\nInstead, it provides high-level summarizes to provide context to the existing documentation. \nSee [test/readme.md](test/readme.md) for information on the MLIR/LLVM testing infrastructure.\n\n\n### Working with TableGen\nThis project uses the [Operation Definition Specification](https://mlir.llvm.org/docs/OpDefinitions/) and [Table-driven Declarative Rewrite Rules](https://mlir.llvm.org/docs/DeclarativeRewrites/)\nwhich use LLVM's [TableGen](https://llvm.org/docs/TableGen/index.html) language/tool.\nThis project specifies things in `*.td` files, which are parsed by TableGen and processed by the [mlir-tblgen](https://llvm.org/docs/CommandGuide/mlir-tblgen.html) backend.\nThe backend generates `C++` files (headers/sources, as appropriate),\nwhich are then included (using standard `#include`) into the headers/sources in this project.\nThese generation steps are triggered automatically during build through custom CMake commands.\n\nIn order to debug issues stemming from TableGen, it is important to realize that there are **four different types of TableGen failures**:\n* The TableGen parser throws an error like `error: expected ')' in dag init`. \n  This implies a syntax error in the `*.td` file, e.g., missing comma or parenthesis.\n  These errors are presented the same as the next kind, but can be recognized since they usually mention \"dag\", \"init\" and/or \"node\". \n* The MLIR TableGen backend throws an error like `error: cannot bind symbol twice`. These are semantic/logical errors in your `*.td` file, or hint at missing features in the backend.\n  Instead of stopping on an error, the backend might also crash with a stack dump. Scroll right to see if this is due to an assert being triggered.\n  This usually indicates a bug in the backend, rather than in your code (at the very least, that an `assert` should be replaced by a `llvm::PrintFatalError`).\n* The C++ compilation fails with an error in the generated `*.h.inc` or `*.cpp.inc` file. \n  This can be caused by either user error, e.g., when trying to do a rewrite that doesn't respect return types,\n  or it can also be a sign of a bug in the MLIR TableGen backend.\n* The project builds, but crashes during runtime. Again, this can be an indication of a backend bug or user error.\n\n### Debugging MLIR\n[//]: # (TODO Documentation: Write up how to get useful debug info out of passes)\n\nUseful command line options for `mlir-opt`/`heco` (see also [MLIR Debugging Tips](https://mlir.llvm.org/getting_started/Debugging/) and [IR Printing](https://mlir.llvm.org/docs/PassManagement/#ir-printing)):\n * `--mlir-print-ir-before-all` - Prints the IR before each pass\n * `--debug-only=dialect-conversion` - Prints some very useful information on passes and rules being applied\n * `--verify-each=0` - Turns off the verifier, allowing one to see what the (invalid) IR looks like\n * `--allow-unregistered-dialect` - Makes parser accept unknown operations (only works if they are in generic form!)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMarbleHE%2FHECO","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMarbleHE%2FHECO","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMarbleHE%2FHECO/lists"}