GithubHelp home page GithubHelp logo

clearmatics / zeth Goto Github PK

View Code? Open in Web Editor NEW
56.0 18.0 26.0 22.66 MB

Integration of Zerocash on Ethereum: https://arxiv.org/abs/1904.00905

Home Page: https://clearmatics.github.io/zeth/

License: GNU Lesser General Public License v3.0

CMake 2.70% JavaScript 0.18% Python 30.05% Shell 3.13% C++ 56.62% Makefile 0.12% Solidity 7.00% Sage 0.21%
zero-knowledge-proofs privacy mixer ethereum zerocash zk-snarks zeth research-and-development clearmatics-research

zeth's Introduction

Zeth - Zerocash on Ethereum

macOS build ubuntu build

WARNING This project is a Proof of Concept. It is highly inefficient and has not been thoroughly reviewed. Please do not use in production!

Disclaimer: This work is inspired from babyzoe, Miximus. It follows and extends the design presented in zerocash-ethereum by adapting some code initially written by Zcash.

It is not intended for handling real value or for use on public networks. The authors have not created any such deployment, and assume no responsibility for any fork of the code or deployment created by other parties.

Check our paper, and the protocol specifications for more information about Zeth.

Collaboration is welcome. Consider opening an issue or a pull-request targeting this repository, or writing a Zeth Protocol Improvement Proposal (ZPIP).

Building and running the project:

Warning This project primarily targets x86_64 Linux and macOS platforms.

Environment

In order to follow the README below, you will need:

  • Docker
  • Npm (at least version 6.9.0)
  • Node (recommended version v10 to be able to build and use the custom ganache-cli)
  • Python3 (at least version 3.7)
  • Pip (at least version 19.0.2)

Additionally, several tools from the GCC and LLVM tools suite are used to improve code quality and generate the documentation of the project. These are required in order to compile the project with all options enabled:

To use the Zeth functionality, 3 components are required:

  • An Ethereum network (the commands below use a local testnet) to host the Zeth contracts and handle transactions.
  • A running prover-server process, used by Zeth clients to generate proofs.
  • Client tools, which generate all inputs required for a Zeth operations, request proofs from the prover-server, and transmit transactions to the Ethereum network holding the Zeth contract.

We use 3 terminals, one for each of the above components.

Note: Mac users should increase docker runtime memory from 2GB to 4GB to allow Terminal 1 to complete successfully.

Terminal 1:

We propose 2 alternatives to run the prover-server below.

Fetch the prover-server image (recommended)
docker pull ghcr.io/clearmatics/zeth:latest-prover
docker run -ti -p 50051:50051 --name prover ghcr.io/clearmatics/zeth:latest-prover prover-server
Build and run the prover-server in the development container
# Clone this repository:
git clone [email protected]:clearmatics/zeth.git
cd zeth

# Build the zeth-dev image
docker build -f Dockerfile-dev -t zeth-dev .
# Start the zeth development container
docker run -ti -p 50051:50051 --name zeth zeth-dev:latest

# All the commands below are run in the docker container
# Configure your environment
. ./setup_env.sh

# Compile the proving server
mkdir build
cd build
cmake .. [<flags (see below)>]
# Compile all libraries and tools, including the prover-server
make
# (optional) Run the unit tests
make test
# (optional) Run the all tests (unit tests, syntax checks, etc)
make check

# Start the prover-server process
prover-server

Note: By default, prover-server generates a key at startup. Flags can be used to force the server to load and/or save keys. Run prover-server --help for more details.

Build Options

Some flags to the cmake command can control the build configuration. -DCMAKE_BUILD_TYPE=Release or -DCMAKE_BUILD_TYPE=Debug can be used to force a release or debug build.

By default, zeth makes use of the GROTH16 zk-snark. To chose a different zksnark run the following: cmake -DZETH_SNARK=$ZKSNARK .. where $ZETH_SNARK is PGHR13 (see https://eprint.iacr.org/2013/279, http://eprint.iacr.org/2013/879) or GROTH16(see https://eprint.iacr.org/2016/260).

Terminal 2: Ethereum testnet

scripts/ganache-start

Terminal 3: Python client

# Configure your environment
. ./setup_env.sh

cd client

Follow the steps described in the client README to run tests or invoke the zeth tools.

Secure Multi Party Computation for the Groth16 SRS generation

See MPC for SRS generation documentation

Development dependencies (for building outside of the Docker container)

Immediate dependencies are provided as submodules and compiled during the Zeth build. Ensure submodules are synced.

The following libraries are also required to build:

  • grpc
  • gmp
  • boost
  • openssl

Generate the Doxygen documentation

To generate the documentation of Zeth:

cd build
cmake .. -DGEN_DOC=ON && make docs

Compile the project using 'sanitizers'

You can select the sanitizer of your choice (one of the sanitizers listed here) by passing the flag -DSANITIZER=<sanitizer> to cmake.

Example:

cd build
cmake -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DSANITIZER=Address -DCMAKE_BUILD_TYPE=Debug ..
make check

Docker images

Docker files Image Tags Description
./Dockerfile-prover ghcr.io/clearmatics/zeth:latest-prover latest-prover, X.Y.Z-prover - Release of zeth, git-%HASH%-prover - developers build by git-commit Zeth Prover Server. Image use zeth-base for building
./Dockerfile-client ghcr.io/clearmatics/zeth:latest-client latest-client, X.Y.Z-client - Release of zeth, git-%HASH%-client - developers build by git-commit Python client to interact with the prover
./Dockerfile-mpc ghcr.io/clearmatics/zeth:latest-mpc latest-mpc, X.Y.Z-mpc - Release of zeth, git-%HASH%-mpc - developers build by git-commit Tools for Multi-Party Computation. Image use zeth-base for building
./Dockerfile-base ghcr.io/clearmatics/zeth:latest-base latest-base, A.B.C-base - Release of zeth-base Base image for building other containers

Run analysis tools on the code

Several tools can be ran on the code. These can be enabled via a set of compilation options.

Note: The clang-tidy target runs a clang-tidy python script that should be fetched from here. To do so, run: cd build && wget https://raw.githubusercontent.com/llvm/llvm-project/master/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py

Example:

# run-clang-tidy.py needs to be in the PATH to be found
PATH=$PATH:${PWD}
chmod +x run-clang-tidy.py

cmake -DUSE_CLANG_FORMAT=ON -DUSE_CPP_CHECK=ON -DUSE_CLANG_TIDY=ON ..
make cppcheck
make clang-format
make clang-tidy

Generate code coverage report

  1. Make sure to enable the CODE_COVERAGE option in the CMake configuration.
  2. Compile the tests
cd build && cmake -DCODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug .. && make check
  1. Generate the coverage report:
make coverage

Note: In order to generate the coverage reports, you will need lcov, along with genhtml and xdg-open.

References and useful links

License notices:

Zcash

Copyright (c) 2016-2018 The Zcash developers
Copyright (c) 2009-2018 The Bitcoin Core developers
Copyright (c) 2009-2018 Bitcoin Developers

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


The MIT software license (http://www.opensource.org/licenses/mit-license.php)
above applies to the code directly included in this source distribution.
Dependencies downloaded as part of the build process may be covered by other
open-source licenses. For further details see 'contrib/debian/copyright'.


This product includes software developed by the OpenSSL Project for use in the
OpenSSL Toolkit (https://www.openssl.org/). This product includes cryptographic
software written by Eric Young ([email protected]).


Although almost all of the Zcash code is licensed under "permissive" open source
licenses, users and distributors should note that when built using the default
build options, Zcash depends on Oracle Berkeley DB 6.2.x, which is licensed
under the GNU Affero General Public License.

Libsnark

The libsnark library is developed by SCIPR Lab (http://scipr-lab.org)
and contributors.

Copyright (c) 2012-2014 SCIPR Lab and contributors (see AUTHORS file).

All files, with the exceptions below, are released under the MIT License:

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Miximus

barryWhiteHat/miximus GNU General Public License v3.0

zeth's People

Contributors

antoinerondelet avatar dependabot[bot] avatar dtebbs avatar riemann89 avatar rrtoledo avatar shapeshed avatar shirikatsu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zeth's Issues

Fix commitment scheme

Our commitment scheme follows ZeroCash's and truncates the outer commitment to 128 bits.

ZCash considers this as a vulnerability however as an adversary would need to perform only 2^64 operations to find a collision which they argue is feasible nowadays (c.f. https://electriccoin.co/blog/fixing-zcash-vulns/).

I propose in this issue to remove the truncation (and have r_trap of size 256 bits). This changes our security properties from statistical hiding commitment scheme to computationally hiding.

Check coin data is compatible with commitment

In testEtherMixing.py and testERCTokenMixing.py: when Charlie receives 1 ETH/1 ETHToken from BOB, he should

  • Recompute the commitment from the coin's data (to check the validity of the payment)

  • Make sure this recomputed commitment is equal to the commitment at address cm_address1BtB

Make digest packing bit order match the EVM

Currently, when digests are packed into multiple field elements, the bits are ordered so that bit0 of the digest has lowest order, and bit255 has highest.

For big-endian machines, the full set of 256 bits must be reversed. For little-endian machines, the bits in each byte must be reveresed. In particular, this wastes gas in the mixer contract (which hits the big-endian case above).

Import contributors

In #88

  • Add functionalities to import the list of contributors to the protocol-coordinator
  • Make sure to verify the message signatures to check knowledge of the private keys associated to the registered pub keys

Transaction malleability needs to be prevented

See Section 4.15.1 of https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
(or Section 4.10 of the same document).

It should also be feasible to extend the statement with a PoK for the statement I know (m, r) s.t for each c_i (the ciphertexts), c_i = E(m, r). This should enable to "attach/bind" the ciphertexts to the rest of the statement, and force the Adversary willing to modify the ciphertexts of a tx, to generate a new proof. However, I guess that representing E as a multiplicative sub-circuit, and evaluating it on each plaintext is way too "constraint-expensive"..

Split the proving and the CRS generation utility

For now, and as detailed in the paper, the prover server is also in charge of generating the CRS. This is fine for the proof of concept, but impedes the use of Zeth as it comes with major trust assumptions (having a centralized CRS generation on the Prover is quite bad since the soundness of the system could be violated in the event of a malicious prover).

Thus, it is important to decouple the CRS generation from the prover and to consider running a sMPC for the CRS generation.

Clean-up circuits helper functions

There are a few functions in helper files (e.g. util.*, circuits-util.*, bits.* ...) which are not used any longer and could be removed.

Change note value unit in solidity contract

We might need to use the Szabo as a unit for the payments.

In fact, note values are represented (in the prover/circuit) by hexadecimal strings encoded on 64bits. As a consequence, the maximum value for a note is: 0xFFFFFFFFFFFFFFFF which corresponds to: 18446744073709551615 in decimal.

Now, if we use this number as Wei, this represents: 18.446744073709551615 ETH. However, we might not need such a long mantissa. Moreover, we would like to be able to do payments of more than 18ETH.
If we change the unit from Wei to Szabo, the number 18446744073709551615 becomes equal to 18 446 744 073 709.551615 ETH which presents a sufficiently high upper bound for note values and which contains 6 digits in the mantissa.

See: https://solidity.readthedocs.io/en/v0.5.0/units-and-global-variables.html#ether-units for some infos on how to change the units.

Optimize zeth contracts

Let's do a pass on the smart contracts to try and optimize them in order to reduce the gas cost of the state transitions

Further abstraction and type information in pyClient

  • Replace values of the form Tuple[str, str, int, bytes, bytes] with meaningful types
  • Abstract out many bits of functionality
    • details of creating commitments and signatures
    • snark-specific code
  • ... other obvious refactorings ...

This will facilitate much of #8

Dependencies in cmake files

Source file and dependency specifications seem to suffer from a few problems:

  • source files are re-specified for every executable (utility and unit test) which inflates build times
  • some include files and .tcc files are not specified as belonging to any target which means that incremental builds (using Makefiles) are often incomplete.

Polish CLIs MPC

Just ran mpc --help on #73 and I have:

Usage:
  ./mpc [<options>] <command> <command-arguments> ...

  -h [ --help ]         This help
  -v [ --verbose ]      Verbose output

Commands:
  create-keypair  dummy-phase2  linear-combination  phase2-begin  phase2-contribute  phase2-verify-contribution  phase2-verify-transcript
  1. I would follow the following formatting for the flags/options:
    -short-flags, --long-flags ARG Explanation and usage
  2. All the commands are listed on the same line. It'd be great and clearer to list them in column and specify a brief description of the command.

So basically, I'd be great to have the following output for the mpc --help

Usage:
  ./mpc [<options>] <command> <command-arguments>

[mpc command description]

Options:
  -h, --help        Display this help and exit
  -v, --verbose      Verbose output

Commands:
  create-keypair                         Brief description of sub-command
  dummy-phase2                       Brief description of sub-command
  linear-combination                   Brief description of sub-command
  phase2-begin                          Brief description of sub-command
  phase2-contribute                   Brief description of sub-command
  phase2-verify-contribution       Brief description of sub-command
  phase2-verify-transcript           Brief description of sub-command

(I don't know how to align stuffs properly in markdown... all messages should consistently be aligned...)
Having such detailed help message is clearer. It would also (potentially) enable to rename several "long commands" with more succint names, like linear-combination -> lin-comb, phase2-begin -> p2-begin and so forth without losing clarity

Write an "entrypoint.sh" script to easily run the prover as a daemon

For now several commands need to be ran in the container to compile the project and start the server. It might be worth running all these commands in a script to be able to start the container in the background by running docker run -d -p 50051:50051 --name zeth zeth-dev

Optimise contract primary inputs assembly

For the assembly of the $nf$ in function check_mkroot_nullifiers_hsig_append_nullifiers_state(, it should be more efficient to have a second counter actually than recomputing the index (as we would have a C_variable_declaration + jsinC_addition instead of jsin(C_addition + C_division) and C_var_declaration < C_division ).
something like:

uint nf_count;
for(uint i = 1; i < 1 + 2*jsIn; i += 2) {  
    digest_inputs[0] = primary_inputs[i];  
    digest_inputs[1] = primary_inputs[i+1];  
    bytes32 current_nullifier = Bytes.sha256_digest_from_field_elements(digest_inputs);  
    nfs[nf_count] = Bytes.sha256_digest_from_field_elements(digest_inputs);  
    nf_count = nf_count + 1;  
}

Modify the packing policy to reduce the number of primary inputs processed by the Verifier

In the current state of the project, several primary inputs are digest (of bit-length 256) and are packed into field elements. This set of field elements represent the set of primary inputs sent to the Verifier (contract), which then executes the SNARK verification routine. The verification routine of the SNARK used does a number of scalar multiplications linear in the number of primary inputs.

For now, each 256-bit digest (d) is packed into 2 field elements:

  1. d1: One field element containing 253 bits from the digest
  2. d2: Another field element containing the 3 remaining bits of the digest (and all zeroes afterwards)
    This "packing policy" was chosen to keep things simple, but we clearly see that, if we have the following set of primary inputs:
    {rt, n1, n2, c1, c2, vpub_in, vpub_out}, where {n1,n2,c1,c2} are digests, then, we'll send the set {rt, n11, n12, n21, n22, c11, c12, c21, c22, vpub_in, vpub_out} of field elements as the set of primary inputs, to the Verifier.

This is quite inefficient since we know that {n12, n22, c12, c22} will only contain 3 "meaningful bits" (the other bits in the field element representation will be set to 0's).

It'd be better to represent the information of the set {n12, n22, c12, c22} in a single field element.

Doing so would reduce the cardinality of the set of primary inputs and save a few calls to the bn256ScalarMul precompiled contract, saving gas on the Verifier side.

Contract compilation error with solc-v0.6.1

Currently if a user clones and executes Zeth from scratch will incur in a compilation error caused by py-solcx-v0.1.1 compiling with solc-v0.6.1 and deprecated flags. This happens if no compiler is available and, by default, the latest version is downloaded. More recent releases of py-solcx avoid this problems since they check the compiler version and filter unsupported options. Updating py-solcx would solve this problem but it will introduce two different issues:

  • solc-v.0.6.1 cannot be used in any case with our contracts since we have to stick to versions 0.5.x.

  • compiler installation folder used by py-solcx has changed and now $HOME/.solcx is used. So we are not able anymore to take everything into the virtual environment if we install the compiler by using the wrapper.

At the moment, a possible solution is to update py-solcx and then force the installation of the right version of the compiler, either before the make setup of the python client or by adding the related installation command in the tests i.e. install_solc('v0.5.x'). The compiler has to be installed into the $HOME/.solcx folder since it's the place where py-solcx looks for.
To keep everything into the virtual environment we should propose to the py-solcx mainteiners to support a custom installation folder for the compiler.

Debug build triggers asserts

When running tests or constructing the joinsplit circuit, asserts are hit in 3rd party libs and internal code:

$ cmake -DCMAKE_BUILD_TYPE=Debug .. && make check

Initially, libsnark asserts due to empty annotations. If those asserts are disabled, zeth circuit gen asserts related to number of inputs.

Side-channel attack considerations

Parts of the PoC implementation could / should be chaged to address some of these points:

  • no query methods on contract
  • clients keep merkle tree
  • contract emits nullifiers
  • periodic sync instead of on-demand
  • (MAYBE) clients maintain set of "spent" notes
  • (MAYBE) automatically add public vin/vout to create complex transactions
  • (MAYBE) track more statistics and warn about anonymity set (based on heuristics)

Remove all PGHR13 files

Think about removing all support for PGHR13.

Now that the layer of abstractions are set to support various SNARKs in the backend, we don't need to support multiple of them necessarily (more code => more potential flaws and more work to maintain the code. As such "Less is more"). The goal is to make sure that we can easily switch from one proof system to another (ie: make sure the proof system used is properly abstracted away in the code base); but we know that in practice we will use Groth16 (especially now that we have implemented an mpc for it). As such, I think it would make sense to remove PGHR13 related files.

Google Test is fetched two times

Google test dependency is added two times into the project. At the repo level, there is no problem since we have just two references, so no big deal. But when we run submodule update init --recursive we download it two times. So it would be nice to remove one of the two occurrences (the one in our dependency folder depends/googletest, leaving the one in the libsnark-fork folder in order to diverge as less as possible from the main repo).

Gas optimization (general): Initializing to null values

On multiple occasions (in multiple contracts), variables are explicitly initialized to their null values. This is unnecessary as initialization to null values is the default and explicitly initializing to null values costs additional gas.

For example, loops in MerkleTreeSha256 are currently written as "uint i=0;" but using "uint i;" would achieve the same outcome and reduce the gas costs for deployment and execution.

Set up Travis CI

Let's set up travis CI to ease reviews and make sure we keep high standards on the code being merged in the repository.
A minimal configuration of Travis would:

  • Run the tests
  • Check that the code follows the style guide (TBD, see #57)

h_sig independant to vk

In the non-malleability upgrade, we introduced a few variables including h_sig. h_sig is used to compute the message authentication tags (h_i) and the new notes identifiers (h_i). h_sig is computed as the hash of the signature verification key (vk), some randomness (randomSeed) and the old notes nullifiers ({nf}_old).

The vulnerability is that we do not check anywhere that h_sig is correctly computed, and even provide it to the contract (see "verifyTransaction in Zerocash full paper Figure 2 p21). An adversary could thus take the primary inputs (including h_sig) and the proof and create a new transaction with them (by faking the ciphertexts and creating a new verification key/signature).

To correct the vulnerability we need to force the contract to check the correctness of h_sig. We could,

  • remove h_sig from the "inputs" variable and have the contract recompute them. This would be cheaper in term of variable but we would need extra computation to reassemble the primary inputs.
  • check that h_sig = Hash( randomSeed, vk, {nf_{old}}. We already reassemble the {nf_{old}} so this solution should cost us a hash.

Using Blake2 personalization tags

So far we use prefixes in PRFs to ensure domain separation which leads to truncating some bits out of the a_sk and phi.

Blake2 offers personalization tags (see Parameter Block Section 2.8) which have the same goal.

I propose here to use personalization tags instead of prefixes (and thus use the full length of a_sk and phi).

Clean up pyClient

The client code could be organized and cleanup.
For instance, several functions of zethGRPC should be in zethUtils.

Assemble variables only once in Mix contracts

In non-malleability, we are assembling the primary inputs several times which is expensive.

We should assemble only the inputs needed for each check then assemble the rest of them.

Write a few pre-commit git hooks to (locally) check code quality and standards before Travis breaks

A bunch of scripts are ran by Travis (to run the tests and check that code standards are followed). It may be useful though to add a few useful git-hooks (with the commands in the README on how to use them in a local clone) to enforce some formatting and styling best practices locally before the build breaks (ie: the formatting check fail on Travis)

For that, add a section to the README to explain how to use the git-hooks and add the hooks in .github hidden folder

Use code formatting tools

There are a few inconsistencies in term of code style in the code base. I think it'd be great to remove these style-related discrepancies to keep a code base uniform (ideally, we should not be able to distinguish between the authors of 2 randomly selected files of the code base). Removing frictions related to code-style allows to focus fully on the "algorithmic part" (what really matters) for reviews.

Languages like Golang come with some tooling like GoFmt that runs on the code and formats it "the standard way". I quickly DuckDuckGoed "code formatter cpp" and it seems tools like this exist for cpp too. I haven't used any of them, but from my flash reading it seems that clang-format is a good candidate and is nicely configurable (see: http://clang.llvm.org/docs/ClangFormatStyleOptions.html). Maybe we can go for this one.

[EDIT:] I can see that we can base the clang-format config on some style-guides (like: https://google.github.io/styleguide/cppguide.html). This is exactly what I was looking for. Let's use such style guide here (I quite like Google's one actually) to avoid spending time defining ours and arguing about style issues.

MerkleTreeSha256.sol Gas optimization

Currently, the global array "leaves" is defined dynamically as "bytes32[] leaves", and then explicitly set to size nbLeaves in the constructor. The entries of leaves are also manually initialized to their null value using a for loop in the constructor. This explicit initialization increases the gas cost of deployment by a non-trivial amount (especially for deep trees).

An alternative approach is to define a local array of fixed size nbLeaves, that is automatically initialized to its null value, in the constructor and then set the global array equal to this fixed-length array. E.g.

contract MerkleTreeSha256 {
...
bytes32[] leaves

constructor(uint treeDepth) public {
    ...   
    bytes32[] memory leavesBuilder = new bytes32[](nbLeaves);
    leaves = leavesBuilder;
}
...

}
Remix tests indicate that this reduces the cost of deployment.

Fix and update contract standalone tests

The standalone tests (in /zeth-contracts/test) do not work anymore.

This may be due to the migration scriptd being obsolete (e.g. the contracts were renamed and moved here ) and some updates in the dependencies.

Switch sha256 to Blake2s

Blake2s (see: https://blake2.net/) looks more efficient - constraint-wise - than sha256. Hence, we should consider switching to this hash function when possible to diminish the number of multiplicative gates in the arithmetic circuit.

Related discussion: zcash/zcash#2630

Fix test_sha256

This test has a few issues:

  • The name is not conformed to the convention "xxx_test"
  • The variable allocation do not have an annotation
  • libsnark::SHA256_block_size is not a function argument anymore

Consider preprocessor on solidity code

Significant optimizations are possible if certain configuration values are known at compile time (in particular, depth of the merkle tree, number of inputs / outputs, which allow much more efficient data structures in memory and storage).

Consider ways to share the configuration information with src/zeth.h and use this as constants in solidity code.

Look into proof batching to amortize the verification cost of proofs

It might be useful to consider the case where a user does multiple payments and, as a result, sends a set of proofs on chain. If so, verifying each proof independently is very inefficient. A better way to proceed in such a setting would be to "batch-verify" the set of proofs.
This can be done quite easily - at least for Groth16 - by using random scalars for each proof to verify and use these to factorize several pairings together at the cost of a few extra scalar multiplications.

Zeth code design: clarifications on ZethNote and JSInput

Zeth joinsplit circuit takes as inputs among other things the input notes and the output notes. In the implementation however, we respectively use JSInputs and ZethNotes structures for them.

A ZethNote is defined by the note's variables: a_pk, v, rho, r (not cm). A JSInput is defined as a ZethNote plus the note path, address and nullifier as well as the spending key.

In the circuit, we actually do not use all of the underlying variables: we do not use a_pk for the input note nor do we use rho for the output note as we recompute them in the circuits. This is not a concern for security, because what happens is that we assign a default value to a wire of the circuit which is then overwritten when we assign values to the input wires and "run the circuit".

This issue is about using minimalist structures. For instance, we could have the BaseNote structure, that can be the mother class of 2 types of ZethNotes: Input and Output ZethNotes. Each of which having the set of attributes strictly needed.
The JSInput data structure would then need to be changed accordingly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.