# HollowDB Prover

To ease proof generation, we provide a prover utility for the circuit used by HollowDB.

{% embed url="<https://github.com/firstbatchxyz/hollowdb-prover>" %}
HollowDB Prover
{% endembed %}

## Usage

To generate proofs, you will need the zero-knowledge circuit WASM file, and a prover key. Both can be found within the repo, see [here](https://github.com/firstbatchxyz/hollowdb-prover/tree/master/circuits). Notice that there are separate files for each protocol, Groth16 and PLONK respectively.

To create the prover:

```typescript
const prover = new Prover(
    "./path-to-circuit-wasm",
    "./path-to-prover-key",
    "groth16" // or "plonk"
);
```

Let us explain the constructor arguments in order:

* `wasmPath` is the relative path to the circuit WASM file. In a web application, this file can be stored under `public`.
* `proverKeyPath` is the relative path to the WASM circuit. In a web application, this file can be stored under `public`.
* `protocol` is the proof system to be used, that is either `groth16` or `plonk`. HollowDB supports both proof systems, and the verifier can determine which one to use by looking at the verification key.

To generate a proof, simply call `prove` function of the newly created `prover`:

```typescript
const {proof, publicSignals} = prover.prove(PREIMAGE, CURRENT_VALUE, NEXT_VALUE);
```

The proof object here shall be provided to HollowDB contract, where it will be checked to verify. Note that public signals are also exported, although we do not use them; the contract obtains them in it's own ways.

The value inputs are "hashed-to-group" and then fed into the circuit. See the [#hash-to-group](#hash-to-group "mention")section below for more information.

For the curious, the public signals is a triple with the following elements in order:

* Current value hash
* Next value hash
* Key, equal to Poseidon hash of the preimage

### Prove with Hashes

The `prove` function takes as input two objects, and it converts them to be circuit-friendly inputs within the function. If you would like to re-use these hashes, or you simply have access to them, you can generate a proof from them too:

```typescript
const {proof} = prover.proveHashed(PREIMAGE, CUR_VAL_HASH, NEXT_VAL_HASH);
```

### Proving In NextJS

Note that to use SnarkJS in a NextJS environment you may need to configure some settings w\.r.t server-side rendering. We suggest adding the following Webpack option to your NextJS config:

```js
webpack: (config, { isServer }) => {
  if (!isServer) {
    config.resolve.alias = {
      ...config.resolve.alias,
      fs: false, // added for SnarkJS
      readline: false, // added for SnarkJS
    };
  }
  // added to run WASM for SnarkJS
  config.experiments = { asyncWebAssembly: true };
  return config;
},
```

You might also have to make some configurations in other frameworks if you have server-side rendering enabled.

## Computing the Key without Proofs

When HollowDB is used with proofs in particular, the `key` is computed by taking the [Poseidon hash](https://www.poseidon-hash.info/) of some secret preimage. The key can be extracted from the `publicSignals` which is in the object that is returned from the `prove` function.

However, if one wants to compute the `key` without creating a proof (e.g. the user just wants to get a value at their own key) they can do so with `computeKey`.

```typescript
import {computeKey} from 'hollowdb-prover'

const key = computeKey(PREIMAGE);
```

## Hash-to-Group

To "embed" the current value and next value within our proofs, we need to map them to a number. This number must be circuit-friendly (to be more technical, it must be within the scalar field of the curve used in our circuit, which is `alt_bn128`).

We provide a `hashToGroup` function for this purpose:

```typescript
import {hashToGroup} from 'hollowdb-prover'

const valueHashed = hashToGroup({foo: "bar", num: 123});
```

Note that the output of this function is a `bigint`, not a string! To store it as a string, you may use `toString` method of the BigInt, with an optional radix. We suggest storing these as hexadecimal strings with `0x` prefix, which allows them to be converted to BigInt easily.

```typescript
const valueHashedStr = '0x' + valueHashed.toString(16);
```
