# 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 부분과 연관지어 설명
- 주석들 언급