diff --git a/common-files/classes/proof.mjs b/common-files/classes/proof.mjs index 597ab8f42..b9f66064a 100644 --- a/common-files/classes/proof.mjs +++ b/common-files/classes/proof.mjs @@ -2,7 +2,7 @@ /* ignore unused exports */ /** -Class representing a GM17 proof. Depending on the local definition of 'proof', +Class representing a G16 proof. Depending on the local definition of 'proof', an object from this class may contain the public inputs as well as the a, b, c terms. Verifier.sol expects the public inputs to be separate, zokrates verify expects them to be in the same object. This class can accomodate either. diff --git a/config/default.js b/config/default.js index f55c14946..6f86e8749 100644 --- a/config/default.js +++ b/config/default.js @@ -51,8 +51,8 @@ module.exports = { onTimeout: false, }, }, - PROVING_SCHEME: process.env.PROVING_SCHEME || 'gm17', - BACKEND: process.env.BACKEND || 'libsnark', + PROVING_SCHEME: process.env.PROVING_SCHEME || 'g16', + BACKEND: process.env.BACKEND || 'bellman', CURVE: process.env.CURVE || 'bn128', PROOF_QUEUE: 'generate-proof', BN128_GROUP_ORDER: 21888242871839275222246405745257275088548364400416034343698204186575808495617n, diff --git a/nightfall-deployer/contracts/Pairing.sol b/nightfall-deployer/contracts/Pairing.sol index 2b263e125..cc7cd4e3f 100644 --- a/nightfall-deployer/contracts/Pairing.sol +++ b/nightfall-deployer/contracts/Pairing.sol @@ -6,367 +6,7 @@ pragma solidity ^0.8.0; * @title Elliptic curve operations on twist points for alt_bn128 * @author Mustafa Al-Bassam (mus@musalbas.com) */ -library BN256G2 { - uint256 internal constant FIELD_MODULUS = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; - uint256 internal constant TWISTBX = 0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5; - uint256 internal constant TWISTBY = 0x9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2; - uint internal constant PTXX = 0; - uint internal constant PTXY = 1; - uint internal constant PTYX = 2; - uint internal constant PTYY = 3; - uint internal constant PTZX = 4; - uint internal constant PTZY = 5; - /** - * @notice Add two twist points - * @param pt1xx Coefficient 1 of x on point 1 - * @param pt1xy Coefficient 2 of x on point 1 - * @param pt1yx Coefficient 1 of y on point 1 - * @param pt1yy Coefficient 2 of y on point 1 - * @param pt2xx Coefficient 1 of x on point 2 - * @param pt2xy Coefficient 2 of x on point 2 - * @param pt2yx Coefficient 1 of y on point 2 - * @param pt2yy Coefficient 2 of y on point 2 - * @return (pt3xx, pt3xy, pt3yx, pt3yy) - */ - function ECTwistAdd( - uint256 pt1xx, uint256 pt1xy, - uint256 pt1yx, uint256 pt1yy, - uint256 pt2xx, uint256 pt2xy, - uint256 pt2yx, uint256 pt2yy - ) public pure returns ( - uint256, uint256, - uint256, uint256 - ) { - if ( - pt1xx == 0 && pt1xy == 0 && - pt1yx == 0 && pt1yy == 0 - ) { - if (!( - pt2xx == 0 && pt2xy == 0 && - pt2yx == 0 && pt2yy == 0 - )) { - assert(_isOnCurve( - pt2xx, pt2xy, - pt2yx, pt2yy - )); - } - return ( - pt2xx, pt2xy, - pt2yx, pt2yy - ); - } else if ( - pt2xx == 0 && pt2xy == 0 && - pt2yx == 0 && pt2yy == 0 - ) { - assert(_isOnCurve( - pt1xx, pt1xy, - pt1yx, pt1yy - )); - return ( - pt1xx, pt1xy, - pt1yx, pt1yy - ); - } - assert(_isOnCurve( - pt1xx, pt1xy, - pt1yx, pt1yy - )); - assert(_isOnCurve( - pt2xx, pt2xy, - pt2yx, pt2yy - )); - uint256[6] memory pt3 = _ECTwistAddJacobian( - pt1xx, pt1xy, - pt1yx, pt1yy, - 1, 0, - pt2xx, pt2xy, - pt2yx, pt2yy, - 1, 0 - ); - return _fromJacobian( - pt3[PTXX], pt3[PTXY], - pt3[PTYX], pt3[PTYY], - pt3[PTZX], pt3[PTZY] - ); - } - /** - * @notice Multiply a twist point by a scalar - * @param s Scalar to multiply by - * @param pt1xx Coefficient 1 of x - * @param pt1xy Coefficient 2 of x - * @param pt1yx Coefficient 1 of y - * @param pt1yy Coefficient 2 of y - * @return (pt2xx, pt2xy, pt2yx, pt2yy) - */ - function ECTwistMul( - uint256 s, - uint256 pt1xx, uint256 pt1xy, - uint256 pt1yx, uint256 pt1yy - ) public pure returns ( - uint256, uint256, - uint256, uint256 - ) { - uint256 pt1zx = 1; - if ( - pt1xx == 0 && pt1xy == 0 && - pt1yx == 0 && pt1yy == 0 - ) { - pt1xx = 1; - pt1yx = 1; - pt1zx = 0; - } else { - assert(_isOnCurve( - pt1xx, pt1xy, - pt1yx, pt1yy - )); - } - uint256[6] memory pt2 = _ECTwistMulJacobian( - s, - pt1xx, pt1xy, - pt1yx, pt1yy, - pt1zx, 0 - ); - return _fromJacobian( - pt2[PTXX], pt2[PTXY], - pt2[PTYX], pt2[PTYY], - pt2[PTZX], pt2[PTZY] - ); - } - /** - * @notice Get the field modulus - * @return The field modulus - */ - function GetFieldModulus() public pure returns (uint256) { - return FIELD_MODULUS; - } - function submod(uint256 a, uint256 b, uint256 n) internal pure returns (uint256) { - return addmod(a, n - b, n); - } - function _FQ2Mul( - uint256 xx, uint256 xy, - uint256 yx, uint256 yy - ) internal pure returns(uint256, uint256) { - return ( - submod(mulmod(xx, yx, FIELD_MODULUS), mulmod(xy, yy, FIELD_MODULUS), FIELD_MODULUS), - addmod(mulmod(xx, yy, FIELD_MODULUS), mulmod(xy, yx, FIELD_MODULUS), FIELD_MODULUS) - ); - } - function _FQ2Muc( - uint256 xx, uint256 xy, - uint256 c - ) internal pure returns(uint256, uint256) { - return ( - mulmod(xx, c, FIELD_MODULUS), - mulmod(xy, c, FIELD_MODULUS) - ); - } - function _FQ2Add( - uint256 xx, uint256 xy, - uint256 yx, uint256 yy - ) internal pure returns(uint256, uint256) { - return ( - addmod(xx, yx, FIELD_MODULUS), - addmod(xy, yy, FIELD_MODULUS) - ); - } - function _FQ2Sub( - uint256 xx, uint256 xy, - uint256 yx, uint256 yy - ) internal pure returns(uint256 rx, uint256 ry) { - return ( - submod(xx, yx, FIELD_MODULUS), - submod(xy, yy, FIELD_MODULUS) - ); - } - function _FQ2Div( - uint256 xx, uint256 xy, - uint256 yx, uint256 yy - ) internal pure returns(uint256, uint256) { - (yx, yy) = _FQ2Inv(yx, yy); - return _FQ2Mul(xx, xy, yx, yy); - } - function _FQ2Inv(uint256 x, uint256 y) internal pure returns(uint256, uint256) { - uint256 inv = _modInv(addmod(mulmod(y, y, FIELD_MODULUS), mulmod(x, x, FIELD_MODULUS), FIELD_MODULUS), FIELD_MODULUS); - return ( - mulmod(x, inv, FIELD_MODULUS), - FIELD_MODULUS - mulmod(y, inv, FIELD_MODULUS) - ); - } - function _isOnCurve( - uint256 xx, uint256 xy, - uint256 yx, uint256 yy - ) internal pure returns (bool) { - uint256 yyx; - uint256 yyy; - uint256 xxxx; - uint256 xxxy; - (yyx, yyy) = _FQ2Mul(yx, yy, yx, yy); - (xxxx, xxxy) = _FQ2Mul(xx, xy, xx, xy); - (xxxx, xxxy) = _FQ2Mul(xxxx, xxxy, xx, xy); - (yyx, yyy) = _FQ2Sub(yyx, yyy, xxxx, xxxy); - (yyx, yyy) = _FQ2Sub(yyx, yyy, TWISTBX, TWISTBY); - return yyx == 0 && yyy == 0; - } - function _modInv(uint256 a, uint256 n) internal pure returns(uint256 t) { - t = 0; - uint256 newT = 1; - uint256 r = n; - uint256 newR = a; - uint256 q; - while (newR != 0) { - q = r / newR; - (t, newT) = (newT, submod(t, mulmod(q, newT, n), n)); - (r, newR) = (newR, r - q * newR); - } - } - function _fromJacobian( - uint256 pt1xx, uint256 pt1xy, - uint256 pt1yx, uint256 pt1yy, - uint256 pt1zx, uint256 pt1zy - ) internal pure returns ( - uint256 pt2xx, uint256 pt2xy, - uint256 pt2yx, uint256 pt2yy - ) { - uint256 invzx; - uint256 invzy; - (invzx, invzy) = _FQ2Inv(pt1zx, pt1zy); - (pt2xx, pt2xy) = _FQ2Mul(pt1xx, pt1xy, invzx, invzy); - (pt2yx, pt2yy) = _FQ2Mul(pt1yx, pt1yy, invzx, invzy); - } - function _ECTwistAddJacobian( - uint256 pt1xx, uint256 pt1xy, - uint256 pt1yx, uint256 pt1yy, - uint256 pt1zx, uint256 pt1zy, - uint256 pt2xx, uint256 pt2xy, - uint256 pt2yx, uint256 pt2yy, - uint256 pt2zx, uint256 pt2zy) internal pure returns (uint256[6] memory pt3) { - if (pt1zx == 0 && pt1zy == 0) { - ( - pt3[PTXX], pt3[PTXY], - pt3[PTYX], pt3[PTYY], - pt3[PTZX], pt3[PTZY] - ) = ( - pt2xx, pt2xy, - pt2yx, pt2yy, - pt2zx, pt2zy - ); - return pt3; - } else if (pt2zx == 0 && pt2zy == 0) { - ( - pt3[PTXX], pt3[PTXY], - pt3[PTYX], pt3[PTYY], - pt3[PTZX], pt3[PTZY] - ) = ( - pt1xx, pt1xy, - pt1yx, pt1yy, - pt1zx, pt1zy - ); - return pt3; - } - (pt2yx, pt2yy) = _FQ2Mul(pt2yx, pt2yy, pt1zx, pt1zy); // U1 = y2 * z1 - (pt3[PTYX], pt3[PTYY]) = _FQ2Mul(pt1yx, pt1yy, pt2zx, pt2zy); // U2 = y1 * z2 - (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1zx, pt1zy); // V1 = x2 * z1 - (pt3[PTZX], pt3[PTZY]) = _FQ2Mul(pt1xx, pt1xy, pt2zx, pt2zy); // V2 = x1 * z2 - if (pt2xx == pt3[PTZX] && pt2xy == pt3[PTZY]) { - if (pt2yx == pt3[PTYX] && pt2yy == pt3[PTYY]) { - ( - pt3[PTXX], pt3[PTXY], - pt3[PTYX], pt3[PTYY], - pt3[PTZX], pt3[PTZY] - ) = _ECTwistDoubleJacobian(pt1xx, pt1xy, pt1yx, pt1yy, pt1zx, pt1zy); - return pt3; - } - ( - pt3[PTXX], pt3[PTXY], - pt3[PTYX], pt3[PTYY], - pt3[PTZX], pt3[PTZY] - ) = ( - 1, 0, - 1, 0, - 0, 0 - ); - return pt3; - } - (pt2zx, pt2zy) = _FQ2Mul(pt1zx, pt1zy, pt2zx, pt2zy); // W = z1 * z2 - (pt1xx, pt1xy) = _FQ2Sub(pt2yx, pt2yy, pt3[PTYX], pt3[PTYY]); // U = U1 - U2 - (pt1yx, pt1yy) = _FQ2Sub(pt2xx, pt2xy, pt3[PTZX], pt3[PTZY]); // V = V1 - V2 - (pt1zx, pt1zy) = _FQ2Mul(pt1yx, pt1yy, pt1yx, pt1yy); // V_squared = V * V - (pt2yx, pt2yy) = _FQ2Mul(pt1zx, pt1zy, pt3[PTZX], pt3[PTZY]); // V_squared_times_V2 = V_squared * V2 - (pt1zx, pt1zy) = _FQ2Mul(pt1zx, pt1zy, pt1yx, pt1yy); // V_cubed = V * V_squared - (pt3[PTZX], pt3[PTZY]) = _FQ2Mul(pt1zx, pt1zy, pt2zx, pt2zy); // newz = V_cubed * W - (pt2xx, pt2xy) = _FQ2Mul(pt1xx, pt1xy, pt1xx, pt1xy); // U * U - (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt2zx, pt2zy); // U * U * W - (pt2xx, pt2xy) = _FQ2Sub(pt2xx, pt2xy, pt1zx, pt1zy); // U * U * W - V_cubed - (pt2zx, pt2zy) = _FQ2Muc(pt2yx, pt2yy, 2); // 2 * V_squared_times_V2 - (pt2xx, pt2xy) = _FQ2Sub(pt2xx, pt2xy, pt2zx, pt2zy); // A = U * U * W - V_cubed - 2 * V_squared_times_V2 - (pt3[PTXX], pt3[PTXY]) = _FQ2Mul(pt1yx, pt1yy, pt2xx, pt2xy); // newx = V * A - (pt1yx, pt1yy) = _FQ2Sub(pt2yx, pt2yy, pt2xx, pt2xy); // V_squared_times_V2 - A - (pt1yx, pt1yy) = _FQ2Mul(pt1xx, pt1xy, pt1yx, pt1yy); // U * (V_squared_times_V2 - A) - (pt1xx, pt1xy) = _FQ2Mul(pt1zx, pt1zy, pt3[PTYX], pt3[PTYY]); // V_cubed * U2 - (pt3[PTYX], pt3[PTYY]) = _FQ2Sub(pt1yx, pt1yy, pt1xx, pt1xy); // newy = U * (V_squared_times_V2 - A) - V_cubed * U2 - } - function _ECTwistDoubleJacobian( - uint256 pt1xx, uint256 pt1xy, - uint256 pt1yx, uint256 pt1yy, - uint256 pt1zx, uint256 pt1zy - ) internal pure returns( - uint256 pt2xx, uint256 pt2xy, - uint256 pt2yx, uint256 pt2yy, - uint256 pt2zx, uint256 pt2zy - ) { - (pt2xx, pt2xy) = _FQ2Muc(pt1xx, pt1xy, 3); // 3 * x - (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1xx, pt1xy); // W = 3 * x * x - (pt1zx, pt1zy) = _FQ2Mul(pt1yx, pt1yy, pt1zx, pt1zy); // S = y * z - (pt2yx, pt2yy) = _FQ2Mul(pt1xx, pt1xy, pt1yx, pt1yy); // x * y - (pt2yx, pt2yy) = _FQ2Mul(pt2yx, pt2yy, pt1zx, pt1zy); // B = x * y * S - (pt1xx, pt1xy) = _FQ2Mul(pt2xx, pt2xy, pt2xx, pt2xy); // W * W - (pt2zx, pt2zy) = _FQ2Muc(pt2yx, pt2yy, 8); // 8 * B - (pt1xx, pt1xy) = _FQ2Sub(pt1xx, pt1xy, pt2zx, pt2zy); // H = W * W - 8 * B - (pt2zx, pt2zy) = _FQ2Mul(pt1zx, pt1zy, pt1zx, pt1zy); // S_squared = S * S - (pt2yx, pt2yy) = _FQ2Muc(pt2yx, pt2yy, 4); // 4 * B - (pt2yx, pt2yy) = _FQ2Sub(pt2yx, pt2yy, pt1xx, pt1xy); // 4 * B - H - (pt2yx, pt2yy) = _FQ2Mul(pt2yx, pt2yy, pt2xx, pt2xy); // W * (4 * B - H) - (pt2xx, pt2xy) = _FQ2Muc(pt1yx, pt1yy, 8); // 8 * y - (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1yx, pt1yy); // 8 * y * y - (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt2zx, pt2zy); // 8 * y * y * S_squared - (pt2yx, pt2yy) = _FQ2Sub(pt2yx, pt2yy, pt2xx, pt2xy); // newy = W * (4 * B - H) - 8 * y * y * S_squared - (pt2xx, pt2xy) = _FQ2Muc(pt1xx, pt1xy, 2); // 2 * H - (pt2xx, pt2xy) = _FQ2Mul(pt2xx, pt2xy, pt1zx, pt1zy); // newx = 2 * H * S - (pt2zx, pt2zy) = _FQ2Mul(pt1zx, pt1zy, pt2zx, pt2zy); // S * S_squared - (pt2zx, pt2zy) = _FQ2Muc(pt2zx, pt2zy, 8); // newz = 8 * S * S_squared - } - function _ECTwistMulJacobian( - uint256 d, - uint256 pt1xx, uint256 pt1xy, - uint256 pt1yx, uint256 pt1yy, - uint256 pt1zx, uint256 pt1zy - ) internal pure returns(uint256[6] memory pt2) { - while (d != 0) { - if ((d & 1) != 0) { - pt2 = _ECTwistAddJacobian( - pt2[PTXX], pt2[PTXY], - pt2[PTYX], pt2[PTYY], - pt2[PTZX], pt2[PTZY], - pt1xx, pt1xy, - pt1yx, pt1yy, - pt1zx, pt1zy); - } - ( - pt1xx, pt1xy, - pt1yx, pt1yy, - pt1zx, pt1zy - ) = _ECTwistDoubleJacobian( - pt1xx, pt1xy, - pt1yx, pt1yy, - pt1zx, pt1zy - ); - d = d / 2; - } - } -} -// This file is MIT Licensed. -// // Copyright 2017 Christian Reitwiessner // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -422,11 +62,6 @@ library Pairing { // This condition will be checked upstream using the returned bool value /* require(success, "EC addition failed"); */ } - /// @return r the sum of two points of G2 - function addition2(G2Point memory p1, G2Point memory p2) internal pure returns (G2Point memory r) { - (r.X[0], r.X[1], r.Y[0], r.Y[1]) = BN256G2.ECTwistAdd(p1.X[0],p1.X[1],p1.Y[0],p1.Y[1],p2.X[0],p2.X[1],p2.Y[0],p2.Y[1]); - - } /// @return r the product of a point on G1 and a scalar, i.e. /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p. function scalar_mul(G1Point memory p, uint s) internal returns (G1Point memory r, bool success) { @@ -520,3 +155,4 @@ library Pairing { return pairing(p1, p2); } } + \ No newline at end of file diff --git a/nightfall-deployer/contracts/Verifier.sol b/nightfall-deployer/contracts/Verifier.sol index dfd402de1..e4c00e893 100644 --- a/nightfall-deployer/contracts/Verifier.sol +++ b/nightfall-deployer/contracts/Verifier.sol @@ -21,7 +21,7 @@ Harry R /** @title Verifier -@dev Example Verifier Implementation - GM17 proof verification. +@dev Example Verifier Implementation - G16 proof verification. @notice Do not use this example in any production code! */ @@ -34,19 +34,18 @@ library Verifier { using Pairing for *; - struct Proof_GM17 { + struct Proof_G16 { Pairing.G1Point A; Pairing.G2Point B; Pairing.G1Point C; } - struct Verification_Key_GM17 { - Pairing.G2Point H; - Pairing.G1Point Galpha; - Pairing.G2Point Hbeta; - Pairing.G1Point Ggamma; - Pairing.G2Point Hgamma; - Pairing.G1Point[2] query; + struct Verification_Key_G16 { + Pairing.G1Point alpha; + Pairing.G2Point beta; + Pairing.G2Point gamma; + Pairing.G2Point delta; + Pairing.G1Point[] gamma_abc; } function verify(uint256[] memory _proof, uint256 _publicInputsHash, uint256[] memory _vk) public returns (bool result) { @@ -59,9 +58,9 @@ library Verifier { function verificationCalculation(uint256[] memory _proof, uint256 _publicInputsHash, uint256[] memory _vk) public returns (uint) { - Proof_GM17 memory proof; + Proof_G16 memory proof; Pairing.G1Point memory vk_dot_inputs; - Verification_Key_GM17 memory vk; + Verification_Key_G16 memory vk; vk_dot_inputs = Pairing.G1Point(0, 0); //initialise @@ -69,21 +68,23 @@ library Verifier { proof.B = Pairing.G2Point([_proof[2], _proof[3]], [_proof[4], _proof[5]]); proof.C = Pairing.G1Point(_proof[6], _proof[7]); - vk.H = Pairing.G2Point([_vk[0],_vk[1]],[_vk[2],_vk[3]]); - vk.Galpha = Pairing.G1Point(_vk[4],_vk[5]); - vk.Hbeta = Pairing.G2Point([_vk[6],_vk[7]],[_vk[8],_vk[9]]); - vk.Ggamma = Pairing.G1Point(_vk[10],_vk[11]); - vk.Hgamma = Pairing.G2Point([_vk[12],_vk[13]],[_vk[14],_vk[15]]); - - // vk.query.length = (_vk.length - 16)/2; - uint j = 0; - for (uint i = 16; i < _vk.length; i+=2) { - vk.query[j++] = Pairing.G1Point(_vk[i], _vk[i+1]); + vk.alpha = Pairing.G1Point(_vk[0],_vk[1]); + vk.beta = Pairing.G2Point([_vk[2],_vk[3]],[_vk[4],_vk[5]]); + vk.gamma = Pairing.G2Point([_vk[6],_vk[7]],[_vk[8],_vk[9]]); + vk.delta = Pairing.G2Point([_vk[10],_vk[11]],[_vk[12],_vk[13]]); + + // vk.gamma_abc.length = (_vk.length - 14)/2; + if (_vk.length > 14) { + vk.gamma_abc = new Pairing.G1Point[]((_vk.length - 14)/2); // num public inputs + 1 + for (uint i = 14; i < _vk.length; i+=2) { + vk.gamma_abc[(i-14)/2] = Pairing.G1Point( + _vk[i], _vk[i+1] + ); + } } - - /* require(vk.query.length == 2, "Length of vk.query is incorrect!"); */ + /* require(vk.gamma.abc.length == 2, "Length of vk.gamma.abc is incorrect!"); */ // Replacing for the above require statement so that the proof verification returns false. Removing require statements to ensure a wrong proof verification challenge's require statement correctly works - if (vk.query.length != 2) { + if (vk.gamma_abc.length != 2) { return 1; } @@ -92,7 +93,7 @@ library Verifier { // The following success variables replace require statements with corresponding functions called. Removing require statements to ensure a wrong proof verification challenge's require statement correctly works bool success_sm_qpih; bool success_vkdi_sm_qpih; - (sm_qpih, success_sm_qpih) = Pairing.scalar_mul(vk.query[1], _publicInputsHash); + (sm_qpih, success_sm_qpih) = Pairing.scalar_mul(vk.gamma_abc[1], _publicInputsHash); (vk_dot_inputs, success_vkdi_sm_qpih) = Pairing.addition( vk_dot_inputs, sm_qpih @@ -105,7 +106,7 @@ library Verifier { { // The following success variables replace require statements with corresponding functions called. Removing require statements to ensure a wrong proof verification challenge's require statement correctly works bool success_vkdi_q; - (vk_dot_inputs, success_vkdi_q) = Pairing.addition(vk_dot_inputs, vk.query[0]); + (vk_dot_inputs, success_vkdi_q) = Pairing.addition(vk_dot_inputs, vk.gamma_abc[0]); if (!success_vkdi_q) { return 3; } @@ -118,36 +119,18 @@ library Verifier { * where psi = \sum_{i=0}^l input_i pvk.query[i] */ { - Pairing.G1Point memory add_A_Galpha; // The following success variables replace require statements with corresponding functions called. Removing require statements to ensure a wrong proof verification challenge's require statement correctly works bool success_pp4_out_not_0; bool success_pp4_pairing; - { - bool success_add_A_Galpha; - (add_A_Galpha, success_add_A_Galpha) = Pairing.addition(proof.A, vk.Galpha); - if (!success_add_A_Galpha) { - return 4; - } - } - (success_pp4_out_not_0, success_pp4_pairing) = Pairing.pairingProd4(vk.Galpha, vk.Hbeta, vk_dot_inputs, vk.Hgamma, proof.C, vk.H, Pairing.negate(add_A_Galpha), Pairing.addition2(proof.B, vk.Hbeta)); + (success_pp4_out_not_0, success_pp4_pairing) = Pairing.pairingProd4( + proof.A, proof.B, + Pairing.negate(vk_dot_inputs), vk.gamma, + Pairing.negate(proof.C), vk.delta, + Pairing.negate(vk.alpha), vk.beta); if (!success_pp4_out_not_0 || !success_pp4_pairing) { return 5; } } - - /** - * e(A, H^{gamma}) = e(G^{gamma}, B) - */ - { - // The following success variables replace require statements with corresponding functions called. Removing require statements to ensure a wrong proof verification challenge's require statement correctly works - bool success_pp2_out_not_0; - bool success_pp2_pairing; - (success_pp2_out_not_0, success_pp2_pairing) = Pairing.pairingProd2(proof.A, vk.Hgamma, Pairing.negate(vk.Ggamma), proof.B); - if (!success_pp2_out_not_0 || !success_pp2_pairing) { - return 6; - } - } - return 0; } -} +} \ No newline at end of file diff --git a/nightfall-deployer/migrations/2_Shield_migration.js b/nightfall-deployer/migrations/2_Shield_migration.js index 3a204fca6..6415d59d2 100644 --- a/nightfall-deployer/migrations/2_Shield_migration.js +++ b/nightfall-deployer/migrations/2_Shield_migration.js @@ -1,4 +1,3 @@ -const BN256G2 = artifacts.require('BN256G2'); const Verifier = artifacts.require('Verifier.sol'); const Shield = artifacts.require('Shield.sol'); const MerkleTree_Stateless = artifacts.require('MerkleTree_Stateless.sol'); @@ -13,8 +12,6 @@ const State = artifacts.require('State.sol'); module.exports = function(deployer) { deployer.then(async () => { - await deployer.deploy(BN256G2); - await deployer.link(BN256G2, Verifier); await deployer.deploy(Verifier); await deployer.link(Verifier, [Challenges,ChallengesUtil]); await deployer.deploy(MiMC); diff --git a/nightfall-optimist/src/classes/verification-key.mjs b/nightfall-optimist/src/classes/verification-key.mjs index 541f7d62b..02095f75d 100644 --- a/nightfall-optimist/src/classes/verification-key.mjs +++ b/nightfall-optimist/src/classes/verification-key.mjs @@ -17,12 +17,11 @@ class VerificationKey { if (!Array.isArray(vkArray)) throw new Error('The input must be an array'); if (vkArray.length % 2 !== 0) throw new Error('The verification array must have an even length'); - this.h = generalise([vkArray.slice(0, 2), vkArray.slice(2, 4)]).all.hex(32); - this.g_alpha = generalise(vkArray.slice(4, 6)).all.hex(32); - this.h_beta = generalise([vkArray.slice(6, 8), vkArray.slice(8, 10)]).all.hex(32); - this.g_gamma = generalise(vkArray.slice(10, 12)).all.hex(32); - this.h_gamma = generalise([vkArray.slice(12, 14), vkArray.slice(14, 16)]).all.hex(32); - this.query = generalise(pairArray(vkArray.slice(16))).all.hex(32); + this.alpha = generalise(vkArray.slice(0, 2)).all.hex(32); + this.beta = generalise([vkArray.slice(2, 4), vkArray.slice(4, 6)]).all.hex(32); + this.gamma = generalise([vkArray.slice(6, 8), vkArray.slice(8, 10)]).all.hex(32); + this.delta = generalise([vkArray.slice(10, 12), vkArray.slice(12, 14)]).all.hex(32); + this.gamma_abc = generalise(pairArray(vkArray.slice(14))).all.hex(32); } } diff --git a/nightfall-optimist/test/compression.mjs b/nightfall-optimist/test/compression.mjs index 16b81f158..306b9b076 100644 --- a/nightfall-optimist/test/compression.mjs +++ b/nightfall-optimist/test/compression.mjs @@ -49,14 +49,14 @@ describe('compression tests', () => { assert.deepStrictEqual(testProof.b, decompressedG2b); }); - it('should compress and decompress a GM17 proof object', async () => { + it('should compress and decompress a G16 proof object', async () => { const compressedProof = await compressProof(testProof); const decompressedProof = decompressProof(compressedProof); const flatProof = [testProof.a, testProof.b, testProof.c].flat(2); assert.deepStrictEqual(flatProof, decompressedProof); }); - it('should compress and decompress a flattened GM17 proof array', async () => { + it('should compress and decompress a flattened G16 proof array', async () => { const compressedProof = await compressProof(Object.values(testProof).flat(Infinity)); const decompressedProof = decompressProof(compressedProof); const flatProof = [testProof.a, testProof.b, testProof.c].flat(2); diff --git a/zokrates-worker/src/services/generateKeys.mjs b/zokrates-worker/src/services/generateKeys.mjs index c9249d646..17bf42961 100644 --- a/zokrates-worker/src/services/generateKeys.mjs +++ b/zokrates-worker/src/services/generateKeys.mjs @@ -5,9 +5,9 @@ import logger from '../utils/logger.mjs'; export default async function generateKeys({ filepath, - curve = 'bls12_377', - backend = 'ark', - provingScheme = 'gm17', + curve = 'bn128', + backend = 'bellman', + provingScheme = 'g16', }) { const outputPath = `./output`; const circuitsPath = `./circuits`; @@ -18,7 +18,7 @@ export default async function generateKeys({ fs.mkdirSync(`${outputPath}/${circuitDir}`, { recursive: true }); - logger.debug( + logger.info( `${circuitsPath}/${filepath}`, `${outputPath}/${circuitDir}`, `${circuitName}_out`, diff --git a/zokrates-worker/src/services/generateProof.mjs b/zokrates-worker/src/services/generateProof.mjs index e706de851..51653943e 100644 --- a/zokrates-worker/src/services/generateProof.mjs +++ b/zokrates-worker/src/services/generateProof.mjs @@ -14,8 +14,8 @@ export default async ({ transactionInputs, outputDirectoryPath, proofFileName, - backend = 'ark', - provingScheme = 'gm17', + backend = 'bellman', + provingScheme = 'g16', }) => { const outputPath = `./output`; let proof; diff --git a/zokrates-worker/src/utils/filing.mjs b/zokrates-worker/src/utils/filing.mjs index 87a5b8d89..ef14d2662 100644 --- a/zokrates-worker/src/utils/filing.mjs +++ b/zokrates-worker/src/utils/filing.mjs @@ -22,8 +22,8 @@ const readJsonFile = filePath => { Strip the 'raw' field from the vk data */ const stripRawData = vk => { - const { h, g_alpha, h_beta, g_gamma, h_gamma, query } = vk; - return { h, g_alpha, h_beta, g_gamma, h_gamma, query }; + const { alpha, beta, gamma, delta, gamma_abc } = vk; + return { alpha, beta, gamma, delta, gamma_abc }; }; export const getVerificationKeyByCircuitPath = circuitPath => { diff --git a/zokrates-worker/src/zokrates-lib/generate-proof.mjs b/zokrates-worker/src/zokrates-lib/generate-proof.mjs index 8a204a5de..19f627e2b 100644 --- a/zokrates-worker/src/zokrates-lib/generate-proof.mjs +++ b/zokrates-worker/src/zokrates-lib/generate-proof.mjs @@ -34,8 +34,8 @@ export default async function generateProof( provingKeyPath, codePath, witnessPath, - provingScheme = 'gm17', - backend = 'ark', + provingScheme = 'g16', + backend = 'bellman', options = {}, ) { if (!fs.existsSync(codePath)) { diff --git a/zokrates-worker/src/zokrates-lib/setup.mjs b/zokrates-worker/src/zokrates-lib/setup.mjs index 9b8ecfa40..6c3604ca8 100644 --- a/zokrates-worker/src/zokrates-lib/setup.mjs +++ b/zokrates-worker/src/zokrates-lib/setup.mjs @@ -22,8 +22,8 @@ const { spawn } = childProcess; export default async function setup( codePath, outputPath = './', - provingScheme = 'gm17', - backend = 'ark', + provingScheme = 'g16', + backend = 'bellman', vkName = 'verification.key', pkName = 'proving.key', options = {}, diff --git a/zokrates-worker/src/zokrates-lib/verify.mjs b/zokrates-worker/src/zokrates-lib/verify.mjs index 39928aa93..eacd0f17a 100644 --- a/zokrates-worker/src/zokrates-lib/verify.mjs +++ b/zokrates-worker/src/zokrates-lib/verify.mjs @@ -33,8 +33,8 @@ const { writeFile } = jsonfile; export default async function verify( vk, proof, - provingScheme = 'gm17', - backend = 'ark', + provingScheme = 'g16', + backend = 'bellman', curve = 'bn128', ) { // we've provided a json proof and a verifying key but Zokrates needs to read