EspressoSystems / cape

Configurable Asset Privacy for Ethereum
https://cape.docs.espressosys.com/
GNU General Public License v3.0
97 stars 16 forks source link

validate proof and public inputs #381

Closed alxiong closed 2 years ago

alxiong commented 2 years ago

For security, we should validate all the group and field elements in a plonk proof and public inputs. This is similar to the small group check we had in our jellyfish's deserialization logic.

zhenfeizhang commented 2 years ago

i realized that there is already a subgroup check function

 /**
     * validate the following:
     *   x != 0
     *   y != 0
     *   x < p
     *   y < p
     *   y^2 = x^3 + 3 mod p
     */
    /// @dev validate G1 point and check if it is on curve
    /// @notice credit: Aztec, Spilsbury Holdings Ltd
    function validateG1Point(G1Point memory point) internal pure {
        bool isWellFormed;
        uint256 p = P_MOD;
        assembly {
            let x := mload(point)
            let y := mload(add(point, 0x20))

            isWellFormed := and(
                and(and(lt(x, p), lt(y, p)), not(or(iszero(x), iszero(y)))),
                eq(mulmod(y, y, p), addmod(mulmod(x, mulmod(x, x, p), p), 3, p))
            )
        }
        require(isWellFormed, "Bn254: invalid G1 point");
    }

Note that the subgroup cofactor is 1, that means we can skip subgroup checks and only do a curve check.

385 implements deserialization now, and has implicit curve membership checks