|
| 1 | +# PySNARK |
| 2 | + |
| 3 | +PySNARK is a Python-based system for performing verifiable computations based on the [Pinocchio](https://eprint.iacr.org/2013/279) system and the [Geppetri](https://eprint.iacr.org/2017/013) extension for proofs on authenticated data. |
| 4 | + |
| 5 | +PySNARK is free to use for non-commercial, |
| 6 | +experimental and research purposes, see `LICENSE.md` for details. |
| 7 | + |
| 8 | +## Installation |
| 9 | + |
| 10 | +### Unix (Linux/MacOS/...) |
| 11 | + |
| 12 | +First, download the PySNARK dependencies, `ate-pairing` and `xbyak`: |
| 13 | + |
| 14 | +``` |
| 15 | +git submodule init |
| 16 | +git submodule update |
| 17 | +``` |
| 18 | + |
| 19 | +Build the `ate-pairing` library: |
| 20 | + |
| 21 | +``` |
| 22 | +cd qaptools/ate-pairing |
| 23 | +make SUPPORT_SNARK=1 |
| 24 | +``` |
| 25 | + |
| 26 | +Build the `qaptools` library: |
| 27 | + |
| 28 | +``` |
| 29 | +cd qaptools |
| 30 | +make |
| 31 | +``` |
| 32 | + |
| 33 | +Build and install the `pysnark` library: |
| 34 | + |
| 35 | +``` |
| 36 | +python setup.py install |
| 37 | +``` |
| 38 | + |
| 39 | +### Windows |
| 40 | + |
| 41 | +PySNARK comes with precompiled Windows executables of `qaptools`, meaning it is possible to build an install PySNARK by just running |
| 42 | + |
| 43 | +``` |
| 44 | +python setup.py install |
| 45 | +``` |
| 46 | + |
| 47 | +To recompiling `qaptools` from source, set up a Unix-like build environment such as Mingw with MSYS and use the Unix instructions above. |
| 48 | + |
| 49 | +### Using without installation |
| 50 | + |
| 51 | +It is also possible to run PySNARK applications without installing PySNARK. For this, follow the above steps but run `python setup.py build` instead of `python setup.py install`. This makes sure all files are compiled and put in their correct locations. Then, run the application with the `PYTHONPATH` environment variable set to the PySNARK library, e.g.: |
| 52 | + |
| 53 | +``` |
| 54 | +PYTHONPATH=/path/to/pysnark/sources python script.py |
| 55 | +``` |
| 56 | + |
| 57 | +## The PySNARK toolchain |
| 58 | + |
| 59 | +We discuss the usage of the PySNARK toolchain based on running one of the provided examples acting as each |
| 60 | +of the different types of parties in a verifiable computation: trusted party, prover, or verifier. |
| 61 | + |
| 62 | +### As trusted party |
| 63 | + |
| 64 | +To try out running PySNARK as trusted party performing key generation, do the following: |
| 65 | + |
| 66 | +``` |
| 67 | +cd examples |
| 68 | +python cube.py 3 |
| 69 | +``` |
| 70 | + |
| 71 | +If PySNARK has been correctly installed, this will perform a verifiable computation that will compute the cube of the input value, `3`. |
| 72 | +At the same time, it will generate all key material needed to verifiably perform the computation in the script. |
| 73 | +(Performing an example computation is the only way to generate this key material.) |
| 74 | +PySNARK produces the following files: |
| 75 | + |
| 76 | +* Files that should be kept secret by the trusted party generating the key material: |
| 77 | + * `pysnark_mastersk`: zk-SNARK master secret key |
| 78 | +* Files that the trusted party should distribute to provers along with the Python script (i.e., `cube.py` in this case): |
| 79 | + * `pysnark_schedule`: schedule of functions called in the computation |
| 80 | + * `pysnark_masterek`: master evaluation key |
| 81 | + * `pysnark_ek_main`: zk-SNARK evaluation |
| 82 | + key for the main function of the computation |
| 83 | + * `pysnark_eqs_main`: equations for the main function of the computation |
| 84 | +* Files that the trusted party should distribute to verifiers: |
| 85 | + * `pysnark_schedule`: schedule of functions called in the computation |
| 86 | + * `pysnark_masterpk`: master public key |
| 87 | + * `pysnark_vk_main`: verificaiton key for the main function |
| 88 | +* Files that the prover should distribute to verifiers: |
| 89 | + * `pysnark_proof`: proof that the particular computation was performed correctly |
| 90 | + * `pysnark_values`: input/output values of the computation |
| 91 | +* Files that are not needed anymore after the execution: |
| 92 | + * `pysnark_eqs`: equations for the zk-SNARK |
| 93 | + * `pysnark_wires`: wire values of the computation |
| 94 | + |
| 95 | +### As prover |
| 96 | + |
| 97 | +To try out running PySNARK as a prover, put the files discussed above (i.e., `pysnark_schedule`, `pysnark_masterek`, `pysnark_ek_main`, and `pysnark_eqs_main`) together with `cube.py` in a directory and run the same command: |
| 98 | + |
| 99 | +``` |
| 100 | +cd examples |
| 101 | +python cube.py 3 |
| 102 | +``` |
| 103 | + |
| 104 | +This will perform a verifiable computation based on the previously generated key material. |
| 105 | + |
| 106 | +### As verifier |
| 107 | + |
| 108 | +To try out running PySNARK as a verifier, put the files discussed above (i.e., `pysnark_schedule`, `pysnark_masterpk` and `pysnark_vk_main` received from the trusted party, and `pysnark_proof` and `pysnark_values` received from the prover) in a folder and run |
| 109 | + |
| 110 | +``` |
| 111 | +PYTHONPATH=../.. python -m pysnark.qaptools.runqapver |
| 112 | +``` |
| 113 | + |
| 114 | +This will verify the computation proof with respect to the input/output values from the `pysnark_values` file, e.g,: |
| 115 | + |
| 116 | +``` |
| 117 | +# PySNARK i/o |
| 118 | +main/o_in: 21 |
| 119 | +main/o_out: 9261 |
| 120 | +``` |
| 121 | + |
| 122 | +In this case, we have verifiably computed the fact that the cube of 21 is 9261. See the `examples` folder for additional examples. |
| 123 | + |
| 124 | + |
| 125 | +### Using commitments |
| 126 | + |
| 127 | +PySNARK allows proofs to refer to committed data using [Geppetri](https://eprint.iacr.org/2017/013). |
| 128 | +This has three applications: |
| 129 | + - it allows proofs to refer to external private inputs from parties other than the trusted third party; |
| 130 | + - it allows different verifiable computations to share secret data with each other; and |
| 131 | + - it allows to divide a verifiable computation into multiple subcomputations, each with their own evaluation and verification keys (but all based on the same master secret key) |
| 132 | + |
| 133 | +See `examples/testcomm.py` for examples. |
| 134 | + |
| 135 | +#### External secret inputs |
| 136 | + |
| 137 | +To commit to data, use `pysnark.qaptools.runqapinput`, e.g., to commit to values 1, 2, and 3 using a commitment named `test`, use: |
| 138 | + |
| 139 | +```python -m pysnark.qaptools.runqapinput test 1 2 3``` |
| 140 | + |
| 141 | +Share `pysnark_wires_test` with any prover who wants to perform a computation with respect to this committed data, and `pysnark_comm_test` to any verifier. |
| 142 | +Alternatively, use `pysnark.qaptools.runqapinput.gencomm` from a Python script. |
| 143 | + |
| 144 | +Import this data into the verifiable computation with |
| 145 | + |
| 146 | +```[one,two,three] = pysnark.runtime.importcomm("test")``` |
| 147 | + |
| 148 | +#### Sharing data between verifiable computations |
| 149 | + |
| 150 | +In the first computation, do |
| 151 | + |
| 152 | +```pysnark.runtime.exportcomm([Var(1),Var(2),Var(3)], "test")``` |
| 153 | + |
| 154 | +and share `pysnark_wires_test` and `pysnark_comm_test` with the other prover and the verifier, respectively. |
| 155 | + |
| 156 | +In the second verifiable computation, do |
| 157 | + |
| 158 | +```[one,two,three] = pysnark.runtime.importcomm("test")``` |
| 159 | + |
| 160 | +#### Sharing data between different parts of a verifiable computation |
| 161 | + |
| 162 | +This is implicitly used whenever a function is called that is decorated with `@pysnark.runtime.subqap`. |
| 163 | +When a particular functon is used multiple times in a verifiable computation, using `@pysnark.runtime.subqap` prevents the circuit for the function to be replicated, resulting in smaller key material (but slower verification). |
| 164 | + |
| 165 | +## Using PySNARK for smart contracts |
| 166 | + |
| 167 | +PySNARK supports the automatic generation of smart contracts that verify the correctness of the given zk-SNARK. |
| 168 | +These smart contracts are written in Solidity and require support for the recent zkSNARK verification opcodes ([EIP 196](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-196.md), [EIP 197](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-197.md)). |
| 169 | +To test them out, install a development version of Truffle using [these instructions](https://github.com/trufflesuite/truffle/blob/develop/CONTRIBUTING.md). |
| 170 | + |
| 171 | +Continuing the above example, as verifier first run |
| 172 | +``` |
| 173 | +truffle init |
| 174 | +``` |
| 175 | +to initialise Truffle (to just see the Solidity code without installing truffle, create two empty directories `contracts` and `test`). |
| 176 | +Next, run |
| 177 | +``` |
| 178 | +python -m pysnark.contract |
| 179 | +``` |
| 180 | +to generate smart contract `contracts/Pysnark.sol` to verify computations of the `cube.py` script (using library `contracts/Pairing.sol` that is also copied into the directory), and test script `test/TestPysnark.sol` that gives a test case for the contract based on the current I/O and proof. |
| 181 | +Finally, run |
| 182 | +``` |
| 183 | +truffle test |
| 184 | +``` |
| 185 | +to run the test script and check that the given proof can indeed be verified in Solidity. |
| 186 | + |
| 187 | +Note that `test/TestPysnark.sol` indeed contains the I/O from the computation: |
| 188 | +``` |
| 189 | +pragma solidity ^0.4.2; |
| 190 | +
|
| 191 | +import "truffle/Assert.sol"; |
| 192 | +import "../contracts/Pysnark.sol"; |
| 193 | +
|
| 194 | +contract TestPysnark { |
| 195 | + function testVerifies() public { |
| 196 | + Pysnark ps = new Pysnark(); |
| 197 | + uint[] memory proof = new uint[](22); |
| 198 | + uint[] memory io = new uint[](2); |
| 199 | + proof[0] = ...; |
| 200 | + ... |
| 201 | + proof[21] = ...; |
| 202 | + io[0] = 21; // main/o_in |
| 203 | + io[1] = 9261; // main/o_out |
| 204 | + Assert.equal(ps.verify(proof, io), true, "Proof should verify"); |
| 205 | + } |
| 206 | +} |
| 207 | +``` |
| 208 | + |
| 209 | +Smart contracts can also refer to commitments, e.g., as imported with the `pysnark.runtime.importcomm` API call. |
| 210 | +In this case, the commitment becomes an argument to the verification function (a six-valued integer array), and the test case shows how the commitment used in the present computation should be used as value for that argument, e.g.: |
| 211 | + |
| 212 | +``` |
| 213 | +pragma solidity ^0.4.2; |
| 214 | +
|
| 215 | +import "truffle/Assert.sol"; |
| 216 | +import "../contracts/Pysnark.sol"; |
| 217 | +
|
| 218 | +contract TestPysnark { |
| 219 | + function testVerifies() public { |
| 220 | + Pysnark ps = new Pysnark(); |
| 221 | + uint[] memory pysnark_comm_test = new uint[](6); |
| 222 | + pysnark_comm_test[0] = ...; |
| 223 | + ... |
| 224 | + Assert.equal(ps.verify(proof, io, pysnark_comm_test), true, "Proof should verify"); |
| 225 | + } |
| 226 | +}``` |
| 227 | +
|
| 228 | +### Documentation |
| 229 | +
|
| 230 | +To generate PySNARK's documentation, do: |
| 231 | +
|
| 232 | +``` |
| 233 | +cd docs |
| 234 | +make html |
| 235 | +``` |
| 236 | +
|
| 237 | +Then, open `docs/_build/html/index.html`. |
| 238 | +
|
| 239 | +A compiled PDF of the documentation is available as `docs/_build/latex/PySNARK.pdf` but this file may not always be up-to-date. |
| 240 | +
|
| 241 | +## Acknowledgements |
| 242 | +
|
| 243 | +This work is part of the [SODA](https://www.soda-project.eu/) project that has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 731583. |
0 commit comments