# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hollowdb.xyz/zero-knowledge-proofs/proofs-from-signatures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
