Home

Awesome

xJsnark

This is a high-level framework for developing applications for zk-SNARKs. xJsnark aims at bridging the gap between high-level programming and performance. It provides a collection of front end features that enables programmers to write zk-SNARK circuits in a higher level way than before (especially for cryptographic applications). On the other side, xjsnark's back end uses several techniques to reduce the cost of the output circuits, which could finally get to the cost of manually-developed circuits for some applications.

xJsnark's front end is currently developed as a java extension on top of Jetbrains MPS V 3.3.5 (Installation instructions below). Using this framework enabled to have assistive customizable IDE features for our purposes, but users might need to get familiar to editing in this environment in the beginning. In the future, we will also consider extending the back end of our circuit generation to other front ends. xJsnark's back end code has not been released yet. It's just released as a jar with class files in this repo, but the implementation of some techniques can be found in the low-level gadgets that are provided in jsnark, such as RSA and AES gadgets. xJsnark produces circuits using the same format as jsnark, which are transformed to r1cs constraints using the jsnark-libsnark interface (See guidelines below about how to run xJsnark circuits on libsnark).

Examples included

This table includes a list of the examples that are currently available in the repository, with the current number of gates and links to code previews. Please note that the code is editable through the framework after checking out the project. Also, the front end has some updates compared to the examples presented in the paper, so please refer to the most recent version of the examples and the comments within the code, when using the framework.

Example (previews)DescriptionNumber of constraints
SHA-256 (Unpadded)High-level implementation of SHA-256 which is compiled to an optimized circuit similar to the one produced by manual/low-level libraries, as in jsnark.25538
AES 128This example applies an improved technique for S-Box implementation in the back end. The reported cost is for encrypting 1 block and includes the cost of the key expansion14240
RSA Secret Key KnowledgeThis example illustrates the long integer types provided by xJsnark and the underlying efficient long integer checks/operations. The reported cost assumes a key size of 2048.2578
EC Secret Key KnowledgeThis example illustrates the customizable non-native finite field types. You can check FieldDefTable for the field definition. Note that the complexity of the code does not change when the field is different from the field that the zk-SNARK circuit uses. This example proves the knowledge of a secret key for an ECDSA public key using the Nist P-256 curve.687228
Sudoku 9x9This example shows how to write an efficient circuit proving the knowledge of a valid 9x9 sudoku puzzle solution, using built-in permutation verification and constraints on native field elements.756
SortingThis example illustrates how to use the external code blocks for non-determinism (setting the values of the external witnesses provided by the prover), and the usage of the permutation verification native instruction which could enable writing more optimized circuits for some applications, like sorting, or pointer chasing. The reported cost is for sorting an array of 1024 16-bit unsigned integers.29166
ZeroCash Pour CircuitHigh-level implementation of the Pour circuit in the ZeroCash paper, that results into an optimized circuit similar to the manually-optimized circuit. The number of constraints reported assumes a height of 64 for the Merkle trees.3814991
RSA Modular ExponentiationThis example shows how to use the long integer modular arithmetic supported by xJsnark to implement modular exponentiation for RSA. This is supported through a type for the multiplicative group of integers modulo N. See the code for more notes. This version includes examples for fixed modulus fixed exponent and fixed modulus variable exponent. Support for types with variable modulus has not been pushed to the front end of this version yet. Note that Jsnark has implementations that can support all these cases and includes the optimizations of xJsnark. The reported cost in this table is for a hardcoded 2048-bit modulus and a hardcoded exponent 0x10001.88949

Getting started

Installation

After checking out and opening the project using the MPS framework,

Running and generating an example circuit

The sandbox solution contains the examples listed above, each in a separate module.

    Config.writeCircuits = true;
    Config.outputFilesPath = ""; // set the path of the output circuit

Note: To paste the above two lines or java code into the MPS framework, right click in the editor -> paste as java statements (or java class content if the copied code appears outside methods). If the Config class is not visible, use ctrl+r as mentioned before.

More detailed instructions and editing hints will be added incrementally about how to define your own circuit, and set other configurations.

Running xJsnark output circuits on libsnark

Field Configuration

By default, xJsnark circuits use the scalar field corresponding to the bn128 curve (as in the case of jsnark default configuration). Note that if the default finite field is not used, i.e. other curves are used, the jsnark-libsnark interface will need to be modified as well.

To update the field configuration, the following can be done in the main method of the xjsnark program:

    Config.setFiniteFieldModulus(new BigInteger(".."));

Note: To paste java code into the MPS framework, right click in the editor -> paste as java statements (or java class content if the copied code appears outside methods). If the Config class is not visible, use ctrl+r as mentioned before.

Debugging Circuits

To trace the intermediate values of xJsnark variables/expressions, you could use the log instruction log(<expression>, "message"). To view the values of the logged expressions, Config.debugVerbose will need to be enabled in the main method. (To import the Config class when it is not visible, you could use using ctrl+r, while checking the non-project module box).

Generating circuits on a different platform

Updating the project

To apply any updates and add new examples automatically: apply VCS-> Update Project from the MPS framework. You might need to rebuild the xJsnark language after updates (right-click-> rebuild).

Disclaimer

This is an early release that could contain issues and inconsistencies. The project is still in dev mode. At this point, I am still optimizing the back end, and adding features and refinements beyond what was in the conference version of the paper, and consequently a lot of integration and testing are still ongoing.