*Updated on January 7, 2022*

# Compiler hints

Instead of computing some value within a circuit, it’s sometimes more optimal
to compute the value off-circuit and only verify the correctness of the
computation in a circuit. `gnark`

allows you to do this through *hints*. From the prover’s point of view, hints are
essentially input variables provided by a hint function instead of the
user.

For example, consider a decomposition of an integer `a`

into bits. A naive
way to decompose it is to look at the binary representation of the integer and
extract bits from this representation, but `gnark`

doesn’t currently provide
native bit operations. Instead, the hint function `hint.IthBit`

can provide the
bits as variables and the user must constrain these variables as a weighted sum
which equals to `a`

. In a circuit it would look like:

```
var b []frontend.Variable
var Σbi frontend.Variable
base := 1
for i := 0; i < nBits; i++ {
b[i] = cs.NewHint(hint.IthBit, a, i)
cs.AssertIsBoolean(b[i])
Σbi = api.Add(Σbi, api.Mul(b[i], base))
base = base << 1
}
cs.AssertIsEqual(Σbi, a)
```

This method is also implemented in the front end as `ToBinary(...)`

interface method.

`gnark`

provides a list of built-in hint functions.

## Implement hint functions

You can define your own hint functions in addition to built-in hint functions.
You can provide any instance satisfying the
`hint.Function`

to `api.NewHint(...)`

method to compute the hint value.
Additionally, you must provide the hint function as a `backend.WithHints`

option
to the back end, so the back end can access the hint function.

`gnark`

also provides a constructor
`hint.NewStaticHint`

for constructing simple hint functions, which takes a constant number of inputs and
returns a constant number of outputs.