> For the complete documentation index, see [llms.txt](https://docs.hollowdb.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hollowdb.xyz/zero-knowledge-proofs/proofs-from-signatures.md).

# Proofs from Signatures

When HollowDB is used together with a dApp, we have the perfect opportunity to use zero-knowledge proofs by making use of the user wallet. In particular, we can derive a secret at client-side using the user wallet, and then generate our key from that derived secret. Here is an example flow for such a use-case:

* **Secret**: A *signature* on a pre-determined a constant string, signed by users for your dApp
* **Preimage**: the secret hashed to a group element (i.e. a circuit-friendly value)
* **Key**: A key derived from the preimage using Poseidon hash (i.e. a zk-friendly hash function)

To try this flow yourself, you can quickly get started with a dApp boilerplate and follow this guide. We think [Rainbowkit](https://www.rainbowkit.com/) provides a really simple boilerplate dApp where you can connect your wallet, so start by setting up the scaffold code described at [Rainbowkit quickstart](https://www.rainbowkit.com/docs/installation#quick-start).

```sh
npm init @rainbow-me/rainbowkit@latest    # npm
pnpm create @rainbow-me/rainbowkit@latest # pnpm
yarn create @rainbow-me/rainbowkit        # yarn
```

We don't really need anything other than the wallet connection button here, so go ahead to `index.tsx` and change the component to the following:

```tsx
return (
  <div className={styles.container}>
    <main className={styles.main}>
      <ConnectButton />
    </main>
  </div>
);
```

We will make use of our prover utility class, so let us install it too:

```sh
yarn add hollowdb-prover # or npm, or pnpm
```

Then, make sure you configure Webpack options, describe at the section: [HollowDB Prover](/zero-knowledge-proofs/hollowdb-prover.md#proving-in-nextjs).

## Getting the Signature

The first thing we have to do is obtain the user signatures for some string. To do so, add the following to within the component:

```tsx
const [signature, setSignature] = useState<string>();
const { signMessage } = useSignMessage({
  message: "your-message-for-this-dapp",
  onSuccess: (data) => setSignature(data),
  onError: (err) => alert(err.message),
});
```

`useSignMessage` is a hook exported by Wagmi, which Rainbowkit wraps around. When we call `signMessage`, it will cause for instance MetaMask to pop-up and ask for user to sign a message.

Let's add a tiny button to get that signature, just below `<ConnectButton />` we will add:

```tsx
<div>
  <button
    className={styles.button}
    onClick={() => {
      signMessage();
    }}
  >
    Sign
  </button>
</div>
```

We have added a tiny style to our button as well, if you would like to add within your `Home.module.css`:

```css
.button {
  background-color: white;
  color: black;
  border: 2px solid #e7e7e7;
  font-size: larger;
  padding: 5px;
  border-radius: 5px;
  margin: 5px;
}

.button:hover {
  background-color: #e7e7e7;
}
```

## Hashing the Signature

We can hash this signature to a circuit-friendly value; or in a bit more technical term: we can do a hash-to-group operation where the result of hash must conform to some rules. In the simplest case, the resulting digest must be smaller than some value (order of the group).&#x20;

Our HollowDB Prover utility class provides a hash-to-group function:

```ts
const { hashToGroup } = require("hollowdb-prover");
```

Then we add a `useMemo` to calculate this hash whenever signature changes.

```ts
const preimage = useMemo(() => signature && hashToGroup(signature), [signature]);
```

We will use this `preimage` when we are creating zero-knowledge proofs for HollowDB.

You are free to use any other method for the hashing-to-group part, all you have to do is make sure that the resulting digest corresponds to a number that is less than:

```
21888242871839275222246405745257275088548364400416034343698204186575808495617
```

For the curious, that is the order of the scalar field of BN254 curve, which is the finite field that our circuit operates on.

## Generating the Proof

Our utility package also exports a prover class: `Prover`. It is really straightforward to use, you just have to provide paths to the WASM circuit and prover key files. These files can be stored under `public` directory. You can download them from [HollowDB repository](https://github.com/firstbatchxyz/hollowdb/tree/master/config/circuits/hollow-authz-groth16).

Import our Prover above:

```typescript
const { Prover } = require("hollowdb-prover");
```

Let's add our button that will generate the proofs, right inside the same `div` with the previous `button`:

```tsx
<button
  className={styles.button}
  onClick={() => {
    if (!preimage) return alert("Please sign first!");

    // change these based on your application
    const currentValue = { foo: 234 };
    const nextValue = { foo: 456 };

    new Prover("/circuits/hollow-authz.wasm", "/circuits/prover_key.zkey")
      .prove(preimage, currentValue, nextValue)
      .then(({ proof }: { proof: unknown }) => {
        // e.g. make an api call with the proof
        console.log(proof);
        alert("Proof created!");
      });
  }}
>
  Prove
</button>
```

You can see how the `Prover` object is created by providing the paths to WASM circuit and the prover key. Then, we simply call the `prove` function with the preimage, current value and the next value.

The value inputs are "hashed-to-group" and embed within the proof itself, this logic is handled within the function.

## Computing the Key

Can we compute the key without generating a proof? Yes, we have the `computeKey` function for that!

```ts
const { computeKey } = require("hollowdb-prover");
```

We can add another `useMemo` to calculate this final hash whenever the previous hash changes.

```ts
const key = useMemo(() => preimage && computeKey(preimage), [preimage]);
```

The client can use this `key` to read values from HollowDB, without needing to generate proofs.

## Putting it All Together

Here is how `index.tsx` looks like in the end:

```tsx
import { ConnectButton } from "@rainbow-me/rainbowkit";
import type { NextPage } from "next";
import styles from "../styles/Home.module.css";
import { useSignMessage } from "wagmi";
import { useMemo, useState } from "react";
const { hashToGroup, Prover, computeKey } = require("hollowdb-prover");

const Home: NextPage = () => {
  const [signature, setSignature] = useState<string>();
  const { signMessage } = useSignMessage({
    message: "your-message-for-this-dapp",
    onSuccess: (data) => setSignature(data),
    onError: (err) => alert(err.message),
  });
  const preimage = useMemo(() => signature && hashToGroup(signature), [signature]);
  const key = useMemo(() => preimage && computeKey(preimage), [preimage]);

  return (
    <div className={styles.container}>
      <main className={styles.main}>
        <ConnectButton />

        <div>
          <button
            className={styles.button}
            onClick={() => {
              signMessage();
            }}
          >
            Sign
          </button>

          <button
            className={styles.button}
            onClick={() => {
              if (!preimage) return alert("Please sign first!");

              // change these based on your dApp!
              const currentValue = { foo: 234 };
              const nextValue = { foo: 456 };

              new Prover("/circuits/hollow-authz.wasm", "/circuits/prover_key.zkey")
                .prove(preimage, currentValue, nextValue)
                .then(({ proof }: { proof: unknown }) => {
                  // e.g. make an api call with the proof
                  console.log(proof);
                  alert("Proof created!");
                });
            }}
          >
            Prove
          </button>
        </div>
      </main>
    </div>
  );
};

export default Home;
```

You should see something like this in the middle of the screen when you connect your wallet:

<figure><img src="/files/DWMrZFskSXxn9IVBhMin" alt=""><figcaption><p>screenshot of wallet connection and buttons</p></figcaption></figure>
