Zkay (pronounced as [zi: keɪ]
) is a programming language which enables automatic compilation of intuitive data privacy specifications to Ethereum smart contracts leveraging (homomorphic) encryption and non-interactive zero-knowledge (NIZK) proofs. This repository provides a toolchain for compiling, deploying and using zkay contracts.
In addition to the instructions below, we refer to the following resources:
- The original research paper (zkay), which introduces the core concepts of zkay.
- The follow-up research paper (ZeeStar), which discusses how homomorphic encryption is introduced in zkay v0.3.
- The online documentation, which provides a tutorial, language reference and API documentation.
Further, the following documents describe the implementation details of zkay:
- The implementation of zkay v0.2 is discussed in a technical report.
- The implementation of zkay v0.3 is described in these notes.
Zkay is a research project and its implementation should not be considered secure (e.g., it may contain bugs and has not undergone any security review)! Do not use zkay in a productive system or to process sensitive confidential data.
Zkay requires python version 3.8 or later (we recommend using a separate conda environment). In addition, install the following dependencies using your system's package manager:
sudo apt-get install default-jdk-headless git build-essential cmake libgmp-dev pkg-config libssl-dev libboost-dev libboost-program-options-dev
sudo pacman -S --needed jdk-openjdk cmake pkgconf openssl gmp boost
Install zkay in editable mode as follows.
git clone https://github.com/eth-sri/zkay.git
# first, install the babygiant library (see zkay/babygiant-lib/README.md for troubleshooting)
cd zkay/babygiant-lib
bash ./install.sh
cd ..
# then, install zkay
pip install -e .
Alternatively, you can run zkay in a docker container using the provided Dockerfile in the install
subdirectory:
make -C ./install run
To run all unit tests, use:
python -m unittest discover --verbose zkay
The documentation is hosted here. To build it locally, use the following commands (requires sphinx, sphinx-rtd-theme, and sphinx-autoapi):
cd docs
make html
The above commands create a tree of HTML files in _build/html
. Developers with sufficient access rights can publish the documentation on GitHub Pages using the script publish_gh_pages.sh
.
See the online documentation for a tutorial on how to use zkay. Below, we only show a summary of available commands.
Note: zkay supports tab completion in Bash shells via the argcomplete package. To enable this feature, argcomplete must be installed and activated on your system (see instructions).
To type-check a zkay file test.zkay
without compiling it, run:
zkay check test.zkay
To strip zkay-specific features from test.zkay
and output the resulting (location preserving) Solidity code, run:
zkay solify test.zkay
The transformed code is printed to stdout.
Zkay requires a backend-dependent external public key infrastructure (PKI) contract and, depending on the proving scheme, additional library contracts to be deployed. These contracts can be compiled and deployed using the commands:
zkay deploy-pki <account>
zkay deploy-crypto-libs <account>
The account
parameter specifies the wallet address from which the deployment transaction should be issued.
Note: The groth16
proving scheme (enabled by default) does not require additional libraries, in which case zkay deploy-crypto-libs
is not required.
Note: The default eth-tester
blockchain backend does not require manually deploying the PKI or library contracts.
To compile a zkay file test.zkay
, run:
zkay compile [-o "<output_dir>"] test.zkay
This performs the following steps:
- Type checking (equivalent to
zkay check
) - Compilation to Solidity
- NIZK proof circuit compilation and key generation
- Generation of the contract interface
contract.py
, which can be used to transparently interact with a deployed zkay contract
To package a zkay contract that was previously compiled with output directory <compilation_output>
, run:
zkay export [-o "<output_filename>"] "<compilation_output>"
This creates an archive containing the zkay code, the NIZK prover and verifier keys, and manifest file. The recommended file extension for the archive is *.zkp
. This archive can be distributed to users of the contract.
To unpack and compile a contract package contract.zkp
:
zkay import [-o "<unpack_directory>"] contract.zkp
Assume you have compiled a file test.zkay
using zkay compile -o "output_dir"
(or imported an archive contract.zkp
using zkay import -o "output_dir" contract.zkp
), you can open an interactive shell for deploying and interacting with the contract as follows:
zkay run output_dir
>>> ...
The python shell provides the following commands:
help()
: Get a list of all contract functions and their argumentsuser1, user2, ..., userN = create_dummy_accounts(N)
: Get addresses of pre-funded test accounts for experimentation (only supported ineth-tester
andganache
backends)handle = deploy(*constructor_args, user: str)
: Issue a deployment transaction for the contract from the accountuser
(address literal).handle = connect(contract_addr: str, user: str)
: Create a handle to interact with the deployed contract at addresscontract_addr
from accountuser
. Fails if remote contract does not match local files.handle.address
: Get the address of the deployed contract corresponding to this handlehandle.some_func(*args[, value: int])
: The account which created handle issues a zkay transaction which calls the zkay contract functionsome_func
with the given arguments. Encryption, transaction transformation and proof generation happen automatically. If the function is payable, the additional argumentwei_amount
can be used to set the wei amount to be transferred.handle.state.get_raw('varname', *indices)
: Retrieve the current raw value of state variablename[indices[0]][indices[1]][...]
.handle.state.get_plain('varname', *indices)
: Retrieve the current plaintext value (decrypted with @me key if necessary) of state variablename[indices[0]][indices[1]][...]
.
To download and install the latest compatible version of solc (requires internet connection):
zkay update-solc
Zkay is based on various third-party source code and libraries:
- zkay-libsnark (fork of libsnark): Downloaded and built during setup of zkay.
- zkay-jsnark (fork of jsnark): Bundled in
zkay/jsnark_interface/JsnarkCircuitBuilder.jar
. - pygments-lexer-solidity: See
docs/custom_highlighting/zkay_lexer.py
. - solidity-BN256G2: See
zkay/compiler/privacy/bn256g2.sol
. - solidity alt_bn128 pairing library: See
zkay/compiler/privacy/library_contracts.py
. - solidity-antlr4: See
zkay/solidity_parser/Solidity.g4
. - Bouncy Castle Crypto APIs for Java: Bundled in
zkay/jsnark_interface/bcprov-jdk15on-1.64.jar
. - sapling_jubjub: See
zkay/transaction/crypto/babyjubjub.py
. - arkworks rust libraries: Dependencies of
babygiant-lib
.
See LICENSE-3RD-PARTIES for license information on third-party source code and libraries.
The contracts evaluated in the CCS 2019 paper can be found in the folder eval-ccs2019
. The scenarios have been adapted to use zkay's new frontend. The original artifact (zkay version 0.1) evaluated in the CCS 2019 paper can be found under the tag ccs2019.
The artifact evaluated in the S&P 2022 paper (ZeeStar) can be found under the tag sp2022. The example contracts and instructions on how to reproduce the results can be found in the folder eval-sp2022
.
You are encouraged to cite the following research paper if you use zkay for academic research.
@inproceedings{steffen2019zkay,
author = {Steffen, Samuel and Bichsel, Benjamin and Gersbach, Mario and Melchior, Noa and Tsankov, Petar and Vechev, Martin},
title = {Zkay: Specifying and Enforcing Data Privacy in Smart Contracts},
year = {2019},
isbn = {9781450367479},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
url = {https://doi.org/10.1145/3319535.3363222},
doi = {10.1145/3319535.3363222},
booktitle = {Proceedings of the 2019 ACM SIGSAC Conference on Computer and Communications Security},
pages = {1759–1776},
numpages = {18},
location = {London, United Kingdom},
series = {CCS ’19}
}
The following research paper presents how zkay is extended by homomorphic encryption (implemented in version 0.3 of zkay).
@inproceedings{steffen2022zeestar
author = {Steffen, Samuel and Bichsel, Benjamin and Baumgartner, Roger and Vechev, Martin},
title = {ZeeStar: Private Smart Contracts by Homomorphic Encryption and Zero-knowledge Proofs},
year = {2022},
booktitle={2022 IEEE Symposium on Security and Privacy (SP)},
}
The following technical report describes version 0.2 of zkay, which introduces many vital features such as real encryption.
@techreport{baumann2020zkay,
title={zkay v0.2: Practical Data Privacy for Smart Contracts},
author={Nick Baumann and Samuel Steffen and Benjamin Bichsel and Petar Tsankov and Martin Vechev},
year={2020},
eprint={2009.01020},
url={https://arxiv.org/abs/2009.01020}
}