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