### 5 unstable releases

Uses old Rust 2015

0.2.2 | Apr 13, 2018 |
---|---|

0.2.1 | Apr 8, 2018 |

0.2.0 | Apr 8, 2018 |

0.1.0 | Apr 6, 2018 |

0.0.1 | Apr 4, 2018 |

#**34** in #mpc

**68** downloads per month

**MIT/Apache**

45KB

877 lines

# phase2

This library is still under development.

## Documentation

## Security Warnings

This library does not make any guarantees about constant-time operations, memory access patterns, or resistance to side-channel attacks.

## License

Licensed under either of

- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

###
`lib.rs`

:

# zk-SNARK MPCs, made easy.

## Make your circuit

Grab the

and
`bellman`

crates. Bellman
provides a trait called `pairing`

, which you must implement
for your computation.`Circuit`

Here's a silly example: proving you know the cube root of a field element.

`extern` `crate` pairing`;`
`extern` `crate` bellman`;`
`use` `pairing``::``{`Engine`,` Field`}``;`
`use` `bellman``::``{`
Circuit`,`
ConstraintSystem`,`
SynthesisError`,`
`}``;`
`struct` `CubeRoot``<`E`:` Engine`>`` ``{`
`cube_root``:` `Option``<``E``::`Fr`>`
`}`
`impl``<`E`:` Engine`>`` ``Circuit``<`E`>` `for`` ``CubeRoot``<`E`>` `{`
`fn` `synthesize``<`CS`:` ConstraintSystem`<`E`>``>``(`
`self`,
`cs``:` `&``mut` CS
`)`` ``->` `Result``<``(``)`, SynthesisError`>`
`{`
`//` Witness the cube root
`let` root `=` cs`.``alloc``(``|``|` `"`root`"``,` `|``|` `{`
`self``.`cube_root`.``ok_or``(``SynthesisError``::`AssignmentMissing`)`
`}``)``?``;`
`//` Witness the square of the cube root
`let` square `=` cs`.``alloc``(``|``|` `"`square`"``,` `|``|` `{`
`self``.`cube_root
`.``ok_or``(``SynthesisError``::`AssignmentMissing`)`
`.``map``(``|``mut` `root``|` `{`root`.``square``(``)``;` root `}``)`
`}``)``?``;`
`//` Enforce that `square` is root^2
cs`.``enforce``(`
`|``|` `"`squaring`"``,`
`|``lc``|` lc `+` root`,`
`|``lc``|` lc `+` root`,`
`|``lc``|` lc `+` square
`)``;`
`//` Witness the cube, as a public input
`let` cube `=` cs`.``alloc_input``(``|``|` `"`cube`"``,` `|``|` `{`
`self``.`cube_root
`.``ok_or``(``SynthesisError``::`AssignmentMissing`)`
`.``map``(``|``root``|` `{`
`let` `mut` tmp `=` root`;`
tmp`.``square``(``)``;`
tmp`.``mul_assign``(``&`root`)``;`
tmp
`}``)`
`}``)``?``;`
`//` Enforce that `cube` is root^3
`//` i.e. that `cube` is `root` * `square`
cs`.``enforce``(`
`|``|` `"`cubing`"``,`
`|``lc``|` lc `+` root`,`
`|``lc``|` lc `+` square`,`
`|``lc``|` lc `+` cube
`)``;`
`Ok``(``(``)``)`
`}`
`}`

## Create some proofs

Now that we have

implementing `CubeRoot <E>`

`Circuit`

,
let's create some parameters and make some proofs.`extern` `crate` rand`;`
`use` `pairing``::``bls12_381``::``{`Bls12`,` Fr`}``;`
`use` `bellman``::``groth16``::``{`
generate_random_parameters`,`
create_random_proof`,`
prepare_verifying_key`,`
verify_proof
`}``;`
`use` `rand``::``{`OsRng`,` Rand`}``;`
`let` rng `=` `&``mut` `OsRng``::`new`(``)``;`
`//` Create public parameters for our circuit
`let` params `=` `{`
`let` circuit `=` `CubeRoot``::``<`Bls12`>` `{`
cube_root`:` `None`
`}``;`
`generate_random_parameters``::``<`Bls12, `_`, `_``>``(`
circuit`,`
rng
`)``.``unwrap``(``)`
`}``;`
`//` Prepare the verifying key for verification
`let` pvk `=` `prepare_verifying_key``(``&`params`.`vk`)``;`
`//` Let's start making proofs!
`for` `_` `in` `0``..``50` `{`
`//` Verifier picks a cube in the field.
`//` Let's just make a random one.
`let` root `=` `Fr``::`rand`(`rng`)``;`
`let` `mut` cube `=` root`;`
cube`.``square``(``)``;`
cube`.``mul_assign``(``&`root`)``;`
`//` Prover gets the cube, figures out the cube
`//` root, and makes the proof:
`let` proof `=` `create_random_proof``(`
`CubeRoot``::``<`Bls12`>` `{`
cube_root`:` `Some``(`root`)`
`}``,` `&`params`,` rng
`)``.``unwrap``(``)``;`
`//` Verifier checks the proof against the cube
`assert!``(``verify_proof``(``&`pvk`,` `&`proof`,` `&``[`cube`]``)``.``unwrap``(``)``)``;`
`}`

## Creating parameters

Notice in the previous example that we created our zk-SNARK
parameters by calling

. However,
if you wanted you could have called `generate_random_parameters`

with some secret numbers you chose, and kept them for
yourself. Given those numbers, you can create false proofs.`generate_parameters`

In order to convince others you didn't, a multi-party
computation (MPC) can be used. The MPC has the property that
only one participant needs to be honest for the parameters to
be secure. This crate (

) is about creating parameters
securely using such an MPC.`phase2`

Let's start by using

to create some base parameters
for our circuit:`phase2`

`extern` `crate` phase2`;`
`let` `mut` params `=` `phase2``::``MPCParameters``::`new`(`CubeRoot `{`
cube_root`:` `None`
`}``)``.``unwrap``(``)``;`

The first time you try this, it will try to read a file like

from the current directory. You need to grab
that from the Powers of Tau.`phase1radix2m2`

These parameters are not safe to use; false proofs can be created for them. Let's contribute some randomness to these parameters.

`//` Contribute randomness to the parameters. Remember this hash,
`//` it's how we know our contribution is in the parameters!
`let` hash `=` params`.``contribute``(`rng`)``;`

These parameters are now secure to use, so long as you weren't
malicious. That may not be convincing to others, so let them
contribute randomness too!

can be serialized and sent
elsewhere, where they can do the same thing and send new
parameters back to you. Only one person needs to be honest for
the final parameters to be secure.`params`

Once you're done setting up the parameters, you can verify the parameters:

`let` contributions `=` params`.``verify``(`CubeRoot `{`
cube_root`:` `None`
`}``)``.``expect``(``"`parameters should be valid!`"``)``;`
`//` We need to check the `contributions` to see if our `hash`
`//` is in it (see above, when we first contributed)
`assert!``(``phase2``::`contains_contribution`(``&`contributions`,` `&`hash`)``)``;`

Great, now if you're happy, grab the Groth16

with
`Parameters`

, so that you can interact with the bellman APIs
just as before.`params .params()`

#### Dependencies

~1.5MB

~22K SLoC