Here you can find documentation on how to use **snarky**, a DSL for using zk-SNARKS, as well as **snarkyjs-crypto** a companion JavaScript library providing a suite of cryptographic primitives suitable for use with **snarky**.

## The structure of a SNAPPa

A SNAPP (or snarkified app) has two parts:

- The definition of your zk-SNARK program. This part will be built using
**snarky**and specifically the snarky-universe standard library. -
The rest of the application, which calls into

**snarky**to create and verify proofs. There are currently APIs for Node.js and OCaml/ReasonML for interacting with**snarky**programs in this way.We'll use two Node.js libraries:

- snarkyjs-crypto, which gives us access to cryptographic hashes, merkle-trees, and signatures that mirror those in snarky-universe
- snarkyjs which gives us methods for creating and verifying SNARK proofs.

## An example appa

Let's build a simple app for proving we know a pre-image to a hash function. You can find the completed app here.

### Building the SNARKa

This first step in building our SNAPP is to define our SNARK. In this case, our SNARK
will prove, given a hash value **h**

I know a field element

xsuch thathash(x) = h.

where **hash** is the Poseidon hash function provided in snarky-universe.

The snarky component -- defined in this file -- is as follows:

```
module Universe = (val Snarky_universe.default());
open! Universe.Impl;
open! Universe;
let input = InputSpec.[(module Hash)];
module Witness = Field;
let main = (preimage: Witness.t, h, ()) =>
Field.assertEqual(Hash.hash([|preimage|]), h);
runMain(input, (module Witness), main);
```

Let's break down this file bit by bit. The top 3 lines

```
module Universe = (val Snarky_universe.default());
open! Universe.Impl;
open! Universe;
```

are just a preamble which brings in scope all the functions we need. It uses the "default" SNARK construction backend, which is the Groth16 SNARK instantiated using the bn128 curve.

The next line

```
let input = InputSpec.[(module Hash)];
```

declares that the public input to our SNARK will be a hash. The "public input" (or "statement") is the value that our SNARK is checked against.

The next line

```
module Witness = Field;
```

states that our top-level "witness" (that is, the thing we're proving we know) will be a single field element, as described above.

Next, we have the `main`

function, which really defines our SNARK

```
let main = (preimage: Witness.t, h, ()) =>
Field.assertEqual(Hash.hash([|preimage|]), h);
```

Here we write just what we described above: `main`

computes the hash of the witness and asserts that it is
equal to the public input `h`

.

The arguments to `main`

must be

- The top level witness value.
- Any public inputs. Here we just have one,
`h`

. - A dummy
`()`

argument.

The final line

```
runMain(input, (module Witness), main);
```

sets up our program to work with the Node.js API.

### Using the SNARKa

Now we're ready to use our SNARK. We're going to use the Node.js API.

The API is fairly straightforward. We can create a "snarky" object which has 2 methods:

`prove`

, which takes a statement and a witness and returns a promise of a proof.`verify`

, which takes a statement and a proof and returns a promise of a bool.

Here is how it all comes together:

```
const { bn128 } = require('snarkyjs-crypto');
const Snarky = require('snarkyjs');
const snarky = new Snarky("./ex_preimage.exe");
const preImage = bn128.Field.ofInt(5);
const statement = bn128.Hash.hash([ preImage ]);
snarky.prove({
statement: [ statement ],
witness: preImage
}).then((proof) => {
console.log("Created proof:\n" + proof + "\n");
return snarky.verify({
"statement": [ statement ],
"proof": proof
});
}, console.log).then((verified) => {
console.log("Was the proof verified? " + verified);
if (verified) {
process.exit(0);
} else {
process.exit(1);
}
}, () => { process.exit(1); });
```