---
# System prepended metadata

title: Pedersen Hashing in TurboPlonk
tags: [audit]

---

# Pedersen Hashing in TurboPlonk
**Disclaimer:** This documentation was written on March, 2022. It is intended to give readers a high-level understanding. The codebase is the canonical source of truth, and over time this document might fall behind the implementation details of the code.
###### tags: `audit`
##### Authors: Suyash and Arijit
The aim of this document is to chalk out all the details of how Pedersen hashing in TurboPlonk works. This should serve as a standalone document to understand Pedersen hash implementation in TurboPlonk. Credits to Cody, Ariel and Zac for previous documentations in different places.

### wNAF Representation

The $w$NAF form is used to break a large scalar into smaller quads for enabling efficient scalar multiplication in Elliptic Curve Cryptography. In the context of Aztec, we define the following functions to compute the $w$NAF of a field scalar $b \in \mathbb{F}_r \equiv \{0,1,2, \dots, r-1\}$:
$$
\begin{aligned}
\textsf{wnaf_decompose}(b) &:= (\{q_{127}, q_{126}, \dots, q_0\}, s) \\
b = \textsf{wnaf_reconstruct}\Big(\{q_i\}_{i=0}^{127}, \ s\Big) &:= \left(\sum_{i=0}^{127}q_i4^i\right) - s.
\end{aligned}
$$
where we refer to $\{q_i\}_{i=0}^{127}$ as quads and $s$ as the skew. To understand how $w$NAF representations work in detail, we refer the reader to the $w$NAF [documentation](https://hackmd.io/TEjx7DC6T22g2W5ZJFKfog?view).

A brief summary is as follows. In case of an even $b$, the function $\textsf{wnaf_decompose}$ computes decomposition of $b+1$ (the next odd number) and sets $s=1$. In case of an odd $b$, the function $\textsf{wnaf_decompose}$ computes decomposition of $b$ and sets $s=0$. 

In case of an odd $b$, the function $\textsf{wnaf_reconstruct}$ gets back original $b$ using the reconstruction formula. In case of an odd $b$, $\textsf{wnaf_reconstruct}$ gets back $b+1$, and obtains $b$ by subtracting $s=1$ from it.

### Scalar Multiplication Using Quads

Before describing our pedersen hash in the next section, we describe a simpler and more straightforward primitive of scalar multiplication.
Given a scalar $b \in \mathbb{F}_r$, we wish to compute $B = bP$. To do this efficiently, we use the quad representation of $b$. We do the following:

1. Input: $b \in \mathbb{F}_r$.
3. Compute the $w$NAF of the modified input: 
$$
\textsf{wnaf_decompose}(b) = \Big(\{q_i\}_{i=0}^{127}, s\Big)
$$ 
where $\{q_i\}_{i=0}^{127}$ are the quads (for $b$ if $b$ is odd, for $b+1$ if $b$ is even) and $s$ is the skew ($s=1$ if the input $b$ is even). We have
$$
b = \textsf{wnaf_reconstruct}\Big(\{q_i\}_{i=0}^{127}, s\Big) = \left(\sum_{i=0}^{127}4^iq_i\right) - s 
$$

Therefore, the scalar multiplication can be written as:
$$
B = bP =  \sum_{i = 0}^{127} q_i \cdot 4^{i}P -sP
$$

It it worth noting an important observation from the $w$NAF [documentation](https://hackmd.io/TEjx7DC6T22g2W5ZJFKfog?view): The most significant quad $q_{127}=1$ for any scalar $b\in \mathbb{F}_r$. Thus, we can rewrite $B$ as:
$$
B = bP = 4^{127} + \sum_{i = 0}^{126} q_i \cdot 4^{i}P - sP.
$$

Now, if we have pre-computed the following group elements: $-3P_i, -P_i, P_i, 3P_i$ where $P_i = 4^iP$, then we can compute the scalar multiplication in our circuit by cumulative point additions. Notice that we only need to compute scalar multiplications of quad values $1$ and $3$, i.e. $P_i$ and $3P_i$ . The scalar multiplications for $-1$ and $-3$ can be obtained by negating the y-coordinates of that of $P_i$ and $3P_i$ respectively while keeping the x coordinates the same. We store these pre-computed group elements in the `hash_ladder` struct in the code.




### From scalar multiplication to Pedersen

In a particular Pedersen hash (say for computing a commitment to a  `value_note`), you need to hash together multiple field scalars each with a unique and uniformly generated set of group generators. This is simplified in the code using something called as `hash_index`. A `hash_index` is a tuple of integers which chooses the generator $P \in \mathbb{G}_1$ and auxiliary generator $P_{\text{aux}} \in \mathbb{G}_1$ for computing Pedersen hashes. We also have a `skew_generator` for a particular `hash_index`.

But why do we need three generators for computing a Pedersen hash of a single scalar? The reason is we want a collision resistant hash function. Since we take only the x-coordinate of the Pedersen hash as output, we need to ensure that the input $b < p/2$ where $p=|\mathbb{G}_1|$ (For a proof see the answers of [this](https://crypto.stackexchange.com/questions/96275/two-elliptic-curve-points-having-the-same-x-coordinate?answertab=active#tab-top), collision resistance is formally proved below. See the exact value of $p$ (Grumpkin group order) in the [Aztec Yellow paper](https://hackmd.io/@aztec-network/ByzgNxBfd#◈-First-pairing-source-group)). In the current setting, the input value can exceed $p/2$. For instance, let $b_{max}$ denote the maximum value of the scalar you can represent using our $w$NAF form (taking $n=127$ below). 
$$
b_{max} = 4^{n} + 3(4^{n-1} + 4^{n-2} + \dots + 4 + 1)-s = 2\cdot 4^{n}-1-0 = 2^{255}-1.
$$
Clearly, $b_{max}>p/2$. Let's drop the least significant quad $q_{0}$ and consider only the remaining 127 quads. In that case, we can have powers of $4$ till $4^{n-1}$, so 
$$
b_{max} = 4^{n-1} + 3(4^{n-2} + 4^{n-1} + \dots + 4 + 1)-s = 2\cdot 4^{n-1}-1-0 = 2^{253}-1.
$$
and hence $b_{max}>p/2$. Similarly, let's drop the two least significant quads $q_{0},q_{1}$ and the skew $s$ and see what is the maximum value we can represent.
$$
b_{max} = 4^{n-2} + 3(4^{n-3} + 4^{n-4} + \dots + 4 + 1) = 2\cdot 4^{n-2}-1 = 2^{251}-1.
$$.
In this case, we do have $b_{max}<p/2$. Therefore, we need to separate the original input $b$ in two parts: $\gamma$ which contains the quads $( q_{0}, q_{1})$ and $\lambda$ which contains $(q_2, q_3\dots, q_{126}, q_{127}=1)$. If the skew $s$ is 1, we use a `skew_generator` $P_{\text{skew}}$. Thus, we define the Pedersen hash of a scalar $b\in \mathbb{F}_r$ as:

$$
\begin{align*}
H_P(b) &= \underbrace{\left(4^{125} + q_{126}4^{124} + \dots + q_{3}4 + q_{2}\right)P}_{\lambda P} + \underbrace{\left( q_{1}4 + q_{0}\right)P_{\text{aux}}}_{\gamma P_{\text{aux}}} - sP_{\text{skew}} \\
&= \underbrace{(4^{125}P - sP_{\text{skew}})}_{\text{Gate }0} + \underbrace{(q_{126}4^{124} + \dots + q_{3}4 + q_{2})P}_{\text{Gates }1, 2, \dots, 125} + \underbrace{(4q_1 + q_0)P_{\text{aux}}}_{\text{Gate }126, 127}
\end{align*}
$$

From the above equation, it is evident that $1 \le \lambda < 2^{251} < \frac{p}{2}$, $-15 \le \gamma \le 15$, $\gamma \neq 0$).

In the code, the powers of the generators are pre-computed and stored in a struct called `hash_ladder`. For generators $P,P_{\text{aux}}\in \mathbb{G}_1$ we define a `hash_ladder` as follows:

| index    | quad           | $\texttt{one}$    | $\texttt{three}$          |
| -------- | -------------- | ----------------- | ------------------------- |
| 0        | $q_{127}(= 1)$ | $4^{125}P$        | $3 \cdot 4^{125}P$        |
| 1        | $q_{126}$      | $4^{124}P$        | $3 \cdot 4^{124}P$        |
| 2        | $q_{125}$      | $4^{123}P$        | $3 \cdot 4^{123}P$        |
| $\vdots$ | $\vdots$       | $\vdots$          | $\vdots$                  |
| 124      | $q_{3}$        | $4P$              | $3 \cdot 4P$              |
| 125      | $q_{2}$        | $1P$              | $3P$                      |
| 126      | $q_{1}$        | $4P_{\text{aux}}$ | $3 \cdot 4P_{\text{aux}}$ |
| 127      | $q_{0}$        | $1P_{\text{aux}}$ | $3P_{\text{aux}}$         |

To confirm the structure of the above table, we have a added a test called `hash_ladder_structure` in `pedersen.test.cpp`.
### Proving Collision Resistance

We prove this by contradiction. Let $a,b \in \mathbb{F}_r$ be two distinct field scalars for which we get a collision (Pedersen hashes yield curve points whose x-coordinates are the same). Thus, we have:
$$
\begin{aligned}
H_P(a) &= \gamma_1 P_{\text{aux}}+\lambda_1P -s_1P_{\text{skew}} = A \implies (x,y_1) \\
H_P(b) &= \gamma_2 P_{\text{aux}}+\lambda_2P -s_2P_{\text{skew}} = B \implies (x,y_2).
\end{aligned}
$$

For collision to occur, we need $y^2_1 = y^2_2 \implies y_1 = \pm y_2$ (as both $A$ and $B$ satisfy the curve equation $y^2 = x^3 - 17$). If $y_1 = -y_2$, $A$ and $B$ are inverses of each other i.e. 
$$
\begin{aligned}
A + B &= \mathcal{O}  \\
\implies (\lambda_1+\lambda_2)P + (\gamma_1+\gamma_2) P_{\text{aux}}  -(s_1+s_2)P_{\text{skew}} &= \mathcal{O}  
\end{aligned}
\tag{1}
$$
Since $1 \le \lambda_1, \lambda_2 < 2^{251} < \frac{p}{2}$, we know that $0 < (\lambda_1 + \lambda_2) < p$. Hence to satisfy equation (1) with uniform generators $P$, $P_{\text{aux}}$, and $P_{\text{skew}}$, an adversary needs to come up with non-zero scalar solution $(a_1,a_2,a_3)$ such that
$$
a_1P+a_2P_{\text{aux}}+a_3P_{\text{skew}} = \mathcal{O}
$$
holds. Here $a_1$ is constrained to be non-zero ensuring that the adversary needs to produce non-zero scalar solution. Coming up with such a solution is equivalent to solving DL problem as shown in this [document](https://hackmd.io/urZOnB1gQimMqsMdf7ZBvw?view).


If $y_1=y_2$, we must have
$$
\begin{aligned}
&A = B \\
&\implies \lambda_1P + \gamma_1P_{\text{aux}} - s_1P_{\text{skew}} = \lambda_2P + \gamma_2P_{\text{aux}} - s_1P_{\text{skew}} \\
&\implies (\gamma_1-\gamma_2)P_{\text{aux}} +(\lambda_2-\lambda_1)P +(s_2-s_1)P_{\text{skew}} = \mathcal{O}. 
\end{aligned}
\tag{2}
$$

Let ${c = (\gamma_1-\gamma_2), d = (\lambda_2-\lambda_1)}$, and $e = (s_2-s_1)$. All $c$, $d$, and $e$ cannot be zero simultaneously since then $a = b$, a contradiction to our assumption of having two distinct scalars producing collision. Again, $e$ should ideally lie in the set $\{-1,0,1\}$. But we do not need to enforce that since that will make the adversary more powerful. Coming up with non-zero scalar solution such that equation (2) holds is equivalent to solving DL problem as shown in this [document](https://hackmd.io/urZOnB1gQimMqsMdf7ZBvw?view). 

Hence our Pedersen hash function is collision resistant. $\blacksquare$ 




### Gate Structure:

In this section, we describe the gate structure for computing a fixed-base scalar multiplication in circuits. We call this as `fixed_group_add_gate` in the code. For input $b = t + \sum_{i = 0}^{126} b_i \cdot 4^{i}$ and generator $P\in \mathbb{G}_1$, we have $n=127$ quads (excluding $q_{127}=1$) and we need a total of $n+1 = 128$ following gates. 

| $w_1$ | $w_2$ | $w_3$ | $w_4$ |
| -------- | -------- | -------- | --- |
| $x_0$ | $y_0$ | $4^{-n}$ | $a_0 = (1 - s4^{-n}) \in \{1, 1 - 4^{-n}\}$ |
| $x_1$ | $y_1$ | $x_{\alpha, 0}$ | $a_1 = 4a_0 + q_{126}$ |
| $x_2$ | $y_2$ | $x_{\alpha, 1}$ | $a_2 = 4^2a_0 + 4q_{126} + q_{125}$ |
| $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
| $x_i$ | $y_i$ | $x_{\alpha, i-1}$ | $a_{i} = 4^{i}a_0 + 4^{i-1}q_{126} + 4^{i-2}q_{125} + \dots + 4q_{127-i+1} + q_{127-i}$ |
| $x_{i+1}$ | $y_{i+1}$ | $x_{\alpha, i}$ | $a_{i+1} = 4^{i+1}a_0 + 4^{i}q_{126} + 4^{i-1}q_{125} + \dots + 4q_{127-i} + q_{127-i-1}$ |
| $\vdots$ | $\vdots$ | $\vdots$ | $\vdots$ |
| $x_{n}$ | $y_{n}$ | $x_{\alpha, n-1}$ | $a_{n} = 4^{n}a_0 + 4^{n-1}q_{126} + 4^{n-2}q_{125} + \dots + 4^2q_2 + 4q_{1} + q_{0} =: b$ |


For the $i$th gate, we have the wires values $w_1 = x_i, w_2 = y_i$ such that $(x_i,y_i) \in \mathbb{G}_1$ denotes the cumulative addition until that gate. In the third wire of the *next* gate, we store $x_{\alpha,i}$ - the x-coordinate of the next point to be added, i.e. $\{-3P_{124-i}, -P_{124-i}, P_{124-i}, 3P_{124-i}\}$. Thus, we have:

$$
(x_{i+1},y_{i+1}) = (x_{i},\ y_{i}) \ +_{ecc} \ (x_{\alpha, i},\ y_{\alpha, i})
$$

The forth wire values are the cumulative sums of the quad values. We use cumulative sums for efficiency reasons. Therefore, the wire value $w_4$ of the last gate should be equal to the original input $b$. Note that in the last gate, we have $4^{n}a_0 = 4^n(1 - s4^{-n}) = 4^n - s$ gives $4^{n}$ when $b$ is odd and $4^{n}-1$ when $b$ is even, so the skew term is taken care of. We describe the constraints on the wire values (i.e. witnesses) in the next section.

### Constraints

To prove that the fixed-base scalar multiplication is correctly computed, we need to enforce the following constraints on the $i$th gate for all $i \in \{0,1,\dots, n-1\}$:

![](https://hackmd.io/_uploads/Hy3G2KHOY.png)

1. Check if the quad value is indeed $\{-3,-1,1,3\}$. We have $\delta_i = q_{126-i} = a_{i+1} - 4 a_i$
$$
\boxed{(\delta_i+3)(\delta_i+1)(\delta_i-1)(\delta_i-3) = 0}
\tag{a}
$$
2. Check if the x-coordinate of the point to be added next is correct. Now, we know the point to be added has to be $(x_{\alpha,i}, y_{\alpha,i}) \in \left\{(x_{\beta}, y_{\beta}), (x_{\beta}, -y_{\beta}), (x_{\gamma}, y_{\gamma}), (x_{\gamma}, -y_{\gamma})\right\}$ where $(x_{\beta}, y_{\beta}) \equiv P_{124-i}$ and $(x_{\gamma}, y_{\gamma}) \equiv 3P_{124-i}$ are pre-computed constants (note that $\delta_i^2$ can either be 9 or 1 below).
$$
\begin{aligned}
x_{\alpha,i} :=& \left(\frac{\delta_i^2 - 9}{-8}\right)x_\beta + \left(\frac{\delta_i^2 - 1}{8}\right)x_{\gamma}
\\
=& \bigg(\underbrace{\frac{x_\gamma-x_\beta}{8}}_{q_{1,i}}\bigg) \delta_i^2 + \bigg(\underbrace{\frac{9x_\beta - x_\gamma}{8}}_{q_{2,i}}\bigg)
\end{aligned}
$$
$$
\therefore \quad \boxed{q_{1,i}\delta_i^2 + q_{2,i} - x_{\alpha,i} = 0}
\tag{b}
$$
3. Check if x-coordinate of the resulting point addition is correct. For this, we use the elliptic curve point addition formula:
$$
\begin{gather}
x_{i+1} = \left(\frac{y_{\alpha,i} - y_i}{x_{\alpha,i} - x_i}\right)^2 - x_{\alpha,i} - x_i \\
\implies (x_{i+1} + x_{\alpha,i} + x_i)(x_{\alpha,i} - x_i)^2 - (y_{\alpha,i} - y_i)^2 = 0 \\
\implies (x_{i+1} + x_{\alpha,i} + x_i)(x_{\alpha,i} - x_i)^2 - y_{\alpha,i}^2 + 2y_{\alpha,i}y_i - y_i^2 = 0 \tag{2}
\end{gather}
$$
We can derive $y_{\alpha,i}$ from $x_{\alpha,i}$ as 
$$
\begin{aligned}
y_{\alpha,i} :=& \ \frac{(x_{\alpha,i}-x_\gamma)\delta_i}{(x_\beta - x_\gamma)}y_\beta+ \frac{(x_{\alpha,i} - x_\beta)\delta_i}{3(x_\gamma - x_\beta)}y_\gamma \\ 
=& \ \bigg( \underbrace{\frac{3y_\beta - y_\gamma}{3(x_\beta - x_\gamma)}}_{q_{ecc,i}} \bigg) x_{\alpha,i}\delta_i + \bigg( \underbrace{\frac{x_\beta y_\gamma - 3x_\gamma y_\beta}{3(x_\beta - x_\gamma)}}_{q_{3,i}} \bigg)\delta_i
\end{aligned}
$$
Substituting $y_{\alpha,i} = q_{ecc,i}x_{\alpha,i}\delta_i + q_{3,i}$ and $y_{\alpha,i}^2 = x_{\alpha,i}^3 + b_{\text{grumpkin}}$ in $(2)$, we get:
$$
\boxed{(x_{i+1} + x_{\alpha,i} + x_i)(x_{\alpha,i} - x_i)^2 - (x_{\alpha,i}^3 + b_{\text{grumpkin}}) + 2y_i(q_{ecc,i}x_{\alpha,i}\delta_i + q_{3,i}) - y_i^2 = 0}
\tag{c}
$$
4. Check if the y-coordinate of the resulting point addition is correct.
$$
\begin{gather}
y_{i+1} = \bigg(\frac{y_{\alpha,i} - y_i}{x_{\alpha,i} - x_i}\bigg)\big(x_i - x_{i+1}\big) - y_i 
\\
\therefore \quad \boxed{(y_{i+1} + y_i)(x_{\alpha,i} - x_i) - (q_{ecc,i}x_{\alpha,i}\delta_i + q_{3,i} - y_i)(x_i - x_{i+1}) = 0}
\tag{d}
\end{gather}
$$
5. Initialisation for $i=0$: we need to check $a_0 \in \{1, 1-4^{-n}\}$. Note that the selector $q_{c,i} = 0$ for $i\neq 0$.
$$
\begin{gather}
\boxed{q_{c,i}(1 - a_i)(1 - 4^{-n} - a_i) = 0}
\tag{e}
\end{gather}
$$
5. Initialisation for $i=0$: $x_0$ must be the x-coordinate of either of $Q_0=4^{125}P$ or $Q_1=4^{125}P - P_{\text{skew}}$. Define selector values for $i=0$:
$$
\begin{gather}
q_{4,0}=Q_{0, x}, \quad q_{5,0}=(Q_{0,x}-Q_{1,x}) 
\\
q_{m,0}=Q_{0, y}, \quad q_{c,0}=(Q_{0,y}-Q_{1,y})
\\ \\
\boxed{q_{c,i} (w_{3,i}(q_{4,i} - x_i) + q_{5,i}(1 - a_i)) = 0}
\tag{f}
\end{gather}
$$
7. Initialisation for $i=0$: $y_0$ must be the y-coordinate of either of $Q_0=4^{125}P$ or $Q_1=4^{125}P- P_{\text{skew}}$.
$$
\boxed{q_{c,i} (w_{3,i}(q_{m,i} - y_i) + q_{c,i}(1 - a_i)) = 0}
\tag{g}
$$

We combine the constraints in equations $(a,b,c,d,e,f, g)$ using powers of a challenge. Linear and non-linear terms are separately computed in `transition_widgets/turbo_fixed_base_widget.hpp`.

### Range Constraining the Input to Pedersen Hashes

Suppose our input to the hash function is $b \in \mathbb{Z}_2^{254}$, we need to prove that $b \in \mathbb{F}_r$. For that, we can split the bit-wise representation of $b$ in two parts:
$$
b = \big(\underbrace{b_{hi}}_{128} \ \| \ \underbrace{b_{lo}}_{126} \big) \in \mathbb{F}_r
$$

Now, suppose we split the field modulus in a same manner as $r = (r_{hi} \ \| \ r_{lo})$. If we prove either of the following condition holds:

1. $r_{hi} - b_{hi} >0$
2. $r_{hi} - b_{hi} =0$ and $r_{lo} - b_{lo} >0$

then we effectively prove that $b < r$. Only question remains to be answered is how do we compute $b_{hi}$ and $b_{lo}$ from the accumulating $w$NAF sums.


#### Computing Upper Half $b_{hi}$

We can compute the upper half $b_{hi}$ from $a_{64}$ in the following way. For $i=64$, we have:

$$
\begin{aligned}
a_{64} &= 4^{64}a_0 + 4^{63}q_{126} + 4^{62}q_{125} + \dots + 4q_{64} + q_{63} \\
&= 4^{64}\left(1 - s \cdot 4^{-127}\right) + 4^{63}q_{126} + 4^{62}q_{125} + \dots + 4q_{64} + q_{63} \\
&= -s \cdot 4^{-63} + \underbrace{4^{64}\cdot 1 + 4^{63}q_{126} + 4^{62}q_{125} + \dots + 4q_{64} + q_{63}}_{b_{hi}} \\
&= -s \cdot 4^{-63} + b_{hi}
\end{aligned}
$$

Note that the most significant quad in $b_{hi}$ too is 1 for the same reasons why it was 1 for $b$.

$$
\boxed{\therefore \quad b_{hi} = a_{64} + s \cdot 2^{-126}}
$$

#### Computing Lower Half $b_{lo}$

We compute the lower half as follows
$$
\begin{aligned}
b_{lo} &= a_{127} - 2^{126} \cdot b_{hi}  \\
&= a_{127} - 2^{126}\left(a_{64} + s \cdot 2^{-126}\right)
\end{aligned}
$$

$$
\boxed{\therefore \quad b_{lo} = a_{127} - 2^{126}a_{64} - s}
$$


### References

1. Barrtenberg implementation: 
    a. [`stdlib/hash/pedersen/pedersen.cpp`](https://github.com/AztecProtocol/aztec2-internal/blob/defi-bridge-project/barretenberg/src/aztec/stdlib/hash/pedersen/pedersen.cpp) 
    b. [`plonk/proof_system/widgets/transition_widgets/turbo_fixed_base_widget.hpp`](https://github.com/AztecProtocol/aztec2-internal/blob/defi-bridge-project/barretenberg/src/aztec/plonk/proof_system/widgets/transition_widgets/turbo_fixed_base_widget.hpp) 
2. The Turbo-PLONK program syntax for specifying SNARK programs, Ariel G and Zac W. 
Link: https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf
3. Fixed-base Multiplication gate, Cody G. 
Link: https://hackmd.io/MCmV2bipRYelT1WUNLj02g?view