---
# System prepended metadata

title: Summa Solvency V2 Walkthrough

---

# Summa Solvency V2 Walkthrough

The front part of SNARK Proof consists of:
1. 64bytes: commitment of the polynomial for the username hash column.
2. 64bytes: commitment of the polynomial for the token0 balance column
3. 64 bytes: commitment of the polynomial for the token1 balance column (I cannot figure out the exact code in halo2 that makes this order)

The first 64 bytes of `slicedSnarkProof` is not used in GrandSumVerifier. GrandsumVerifier does not use the username hash column. 
[https://github.com/summa-dev/summa-solvency/blob/fec83a747ead213261aecfaf4a01b43fff9731ee/contracts/src/Summa.sol#L252-L257](https://github.com/summa-dev/summa-solvency/blob/fec83a747ead213261aecfaf4a01b43fff9731ee/contracts/src/Summa.sol#L252-L257) 

It is saved to be used in `inclusionVerifier`. 
[https://github.com/summa-dev/summa-solvency/blob/fec83a747ead213261aecfaf4a01b43fff9731ee/contracts/src/Summa.sol#L273-L281](https://github.com/summa-dev/summa-solvency/blob/fec83a747ead213261aecfaf4a01b43fff9731ee/contracts/src/Summa.sol#L273-L281)

If there are many tokens to prove, the balance polynomial can be B_1, B_2, ....
I will denote it as B supposing there are only one token.

#### Grand sum proof
$C = B(s)$
$Q_B = (B(s) - B(0)) / (s - 0)$
$e([B(s)]_1 - [B(0)]_1, [1]_2) = e([Q_B]_1, [s]_2 - [0]_2)$

#### User inclusion proof
$C = B(s)$
$Q_B = (B(s) - B(w^i)) / (s - w^i)$
$e([B(s)]_1 - [B(w^i)]_1, [1]_2) = e([Q_B]_1, [s]_2 - [w^i]_2)$

#### Username hash proof
$C = U(s)$
$Q_U = (U(s) - U(w^i)) / (s - w^i)$
$e([U(s)]_1 - [U(w^i)]_1, [1]_2) = e([Q_U]_1, [s]_2 - [w^i]_2)$

### Batch verification
User balance batch verification

Let s be a secret in the trusted setup.

$P := \{i \ | i \in user \ indices \ to\ verify \}$ $L_{i}= \prod_{j \in P, \ j \neq i}\frac{(x-w^j)}{(w^i - w^j)}$

$I(x) = \sum_{i \in P}{L_i(w^i) \cdot B(w^i)}$

If $B(w^i) = I(w^i)$ holds for all $i \in P$, then $B(x) - I(x) = Q(x)\prod_{i \in P}(x - w^i)$.

Therefore, the verification can be done as below. $Q(s) = \frac{B(s) - I(s)}{\prod_{i \in P}(s - w^i)}$

$e([B(s)]_1 - [I(s)]_1, [1]_2) = e([Q(s)]_1, [\prod_{i \in P} (s - w^i)]_2)$

reference: [https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html#multiproofs](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html#multiproofs)


## gen_commit_and_proofs

### The order of challenges input (TODO)

> Elements a * i + b of F_p^2 are encoded as two elements of F_p, (a, b).

[https://eips.ethereum.org/EIPS/eip-197](https://eips.ethereum.org/EIPS/eip-197 "https://eips.ethereum.org/EIPS/eip-197")

F_p^2 is represented by `c0 + c1 * i` in PSE halo2. The order is opposite. [https://github.com/privacy-scaling-explorations/halo2curves/blob/main/src/bn256/fq2.rs#L14-L19](https://github.com/privacy-scaling-explorations/halo2curves/blob/main/src/bn256/fq2.rs#L14-L19 "https://github.com/privacy-scaling-explorations/halo2curves/blob/main/src/bn256/fq2.rs#L14-L19")

F_p^2 is another field where an element is represented by two elements of F_p (a,b) for `a * i + b`. Therefore a point (x, y) needs 4 uint256. This is one example in [https://eips.ethereum.org/EIPS/eip-197](https://eips.ethereum.org/EIPS/eip-197 "https://eips.ethereum.org/EIPS/eip-197")

`P2 = (   11559732032986387107991004021392285783925812861821192530917403151452391805634 * i +   10857046999023057135944570762232829481370756359578518086990519993285655852781,   4082367875863433681332203403145435568316851327593401208105741076214120093531 * i +   8495653923123431417604973247489272438418190587263600148770280649306958101930 )`

### Endian
little endian에서 big endian으로 가야함.
Elements of F_p are encoded as 32 byte big-endian numbers.
[EIP-197: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128](https://eips.ethereum.org/EIPS/eip-197)jk


InclusionVerifier 분석
- (ai + b, ci + d) 순서
	- gen_commit_and_proofs 부분과 연관지어 설명
- 주석들 언급
