all files / contracts/verifiers/ UserStateTransitionVerifier.sol

100% Statements 14/14
50% Branches 9/18
100% Functions 2/2
100% Lines 30/30
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96                                                        83× 83× 83× 83× 83× 83× 83× 83× 83× 83× 83×                         83× 83× 83× 83×   83×     83×     83× 83×   83× 83×   83× 83×   83× 83×       83× 498× 498×     83×   83×                        
// SPDX-License-Identifier: MIT
 
pragma solidity ^0.8.0;
 
import {Pairing} from '../libraries/Pairing.sol';
 
contract UserStateTransitionVerifier {
 
    using Pairing for *;
 
    uint256 constant SNARK_SCALAR_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    uint256 constant PRIME_Q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
 
    struct VerifyingKey {
        Pairing.G1Point alpha1;
        Pairing.G2Point beta2;
        Pairing.G2Point gamma2;
        Pairing.G2Point delta2;
        Pairing.G1Point[7] IC;
    }
 
    struct Proof {
        Pairing.G1Point A;
        Pairing.G2Point B;
        Pairing.G1Point C;
    }
 
    function verifyingKey() internal pure returns (VerifyingKey memory vk) {
        vk.alpha1 = Pairing.G1Point(uint256(20491192805390485299153009773594534940189261866228447918068658471970481763042),uint256(9383485363053290200918347156157836566562967994039712273449902621266178545958));
        vk.beta2 = Pairing.G2Point([uint256(4252822878758300859123897981450591353533073413197771768651442665752259397132),uint256(6375614351688725206403948262868962793625744043794305715222011528459656738731)], [uint256(21847035105528745403288232691147584728191162732299865338377159692350059136679),uint256(10505242626370262277552901082094356697409835680220590971873171140371331206856)]);
        vk.gamma2 = Pairing.G2Point([uint256(11559732032986387107991004021392285783925812861821192530917403151452391805634),uint256(10857046999023057135944570762232829481370756359578518086990519993285655852781)], [uint256(4082367875863433681332203403145435568316851327593401208105741076214120093531),uint256(8495653923123431417604973247489272438418190587263600148770280649306958101930)]);
        vk.delta2 = Pairing.G2Point([uint256(14549173230613160247778015355407028900516112506588680209196010970501931370428),uint256(20822826699873746389251306826702083919595819295688256787466903777253962071398)], [uint256(15637632621102099563336926956479705466335249773083083294227111633261907299945),uint256(4519282789633715439653929605141792333929204180248195063015998750227084376225)]);
        vk.IC[0] = Pairing.G1Point(uint256(2481388117010838745014528013856968120306340818254839318044434527551900450658),uint256(18629832891948328839863944399558600703073879333683758862606741203305527372588));
        vk.IC[1] = Pairing.G1Point(uint256(10648484456169410816932600663328543344107298480470087945568808037508485049184),uint256(10823356084401490469110137705772183233661082906241510166015737496886433013810));
        vk.IC[2] = Pairing.G1Point(uint256(13276406972754736935295830616189739440685635964298147801320400879677652055196),uint256(19593738291019657177814229283873607290758373549681073900819986536140632026339));
        vk.IC[3] = Pairing.G1Point(uint256(5638844376664510293219253563800424985730084097792727583774947274157537363512),uint256(18548662660704778299827258903432597467868563668265235274527348749662186012391));
        vk.IC[4] = Pairing.G1Point(uint256(6134734389963552125162771260343635871624005693190679222183770377770858047646),uint256(21025663827734571189932651546599649712998774962656273292711498182245757937090));
        vk.IC[5] = Pairing.G1Point(uint256(5915704185706330432838225312891779777741207617382120986069263096233343200100),uint256(13139071769958042210847706750015402022913576399842398609531299463871578962094));
        vk.IC[6] = Pairing.G1Point(uint256(15781533633647252930667598769583572342740307766983921831502643126521089680405),uint256(14081928433252454002535000741990460264870325942569009321164587339548290574084));
 
    }
 
    /*
     * @returns Whether the proof is valid given the hardcoded verifying key
     *          above and the public inputs
     */
    function verifyProof(
        uint256[] calldata input,
        uint256[8] calldata _proof
    ) public view returns (bool) {
 
        Proof memory proof;
        proof.A = Pairing.G1Point(_proof[0], _proof[1]);
        proof.B = Pairing.G2Point([_proof[2], _proof[3]], [_proof[4], _proof[5]]);
        proof.C = Pairing.G1Point(_proof[6], _proof[7]);
 
        VerifyingKey memory vk = verifyingKey();
 
        // Compute the linear combination vk_x
        Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);
 
        // Make sure that proof.A, B, and C are each less than the prime q
        Erequire(proof.A.X < PRIME_Q, "verifier-aX-gte-prime-q");
        Erequire(proof.A.Y < PRIME_Q, "verifier-aY-gte-prime-q");
 
        Erequire(proof.B.X[0] < PRIME_Q, "verifier-bX0-gte-prime-q");
        Erequire(proof.B.Y[0] < PRIME_Q, "verifier-bY0-gte-prime-q");
 
        Erequire(proof.B.X[1] < PRIME_Q, "verifier-bX1-gte-prime-q");
        Erequire(proof.B.Y[1] < PRIME_Q, "verifier-bY1-gte-prime-q");
 
        Erequire(proof.C.X < PRIME_Q, "verifier-cX-gte-prime-q");
        Erequire(proof.C.Y < PRIME_Q, "verifier-cY-gte-prime-q");
 
        // Make sure that every input is less than the snark scalar field
        //for (uint256 i = 0; i < input.length; i++) {
        for (uint256 i = 0; i < 6; i++) {
            Erequire(input[i] < SNARK_SCALAR_FIELD,"verifier-gte-snark-scalar-field");
            vk_x = Pairing.plus(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));
        }
 
        vk_x = Pairing.plus(vk_x, vk.IC[0]);
 
        return Pairing.pairing(
            Pairing.negate(proof.A),
            proof.B,
            vk.alpha1,
            vk.beta2,
            vk_x,
            vk.gamma2,
            proof.C,
            vk.delta2
        );
    }
}