From fef183db9abdcbfa222abd03efdd1c1907803465 Mon Sep 17 00:00:00 2001 From: Uncle Fatso Date: Wed, 29 Oct 2025 17:44:05 +0300 Subject: [PATCH] code cleanups; scalars check added Signed-off-by: Uncle Fatso --- src/Verifier.sol | 94 ++++++------------------------------------------ 1 file changed, 11 insertions(+), 83 deletions(-) diff --git a/src/Verifier.sol b/src/Verifier.sol index f33a214..6d802c8 100644 --- a/src/Verifier.sol +++ b/src/Verifier.sol @@ -27,6 +27,8 @@ abstract contract GhostVerifier { bytes calldata proof, bytes calldata missedIndexes ) internal view returns (uint256 res) { + require(s < GhostEllipticCurves.N); // scalar check + uint256 px = pubkeyX; uint256 py = pubkeyY; uint256 e; @@ -34,21 +36,22 @@ abstract contract GhostVerifier { uint256 ry; { - uint256[] memory rNonces = new uint256[](4); uint256[] memory coefficients = new uint256[](2); - _reconstructNonces(rNonces, nonces); - _computeCoefficients(px, m, rNonces, coefficients); + { + uint256[] memory rNonces = new uint256[](4); + _reconstructNonces(rNonces, nonces); + _computeCoefficients(px, m, rNonces, coefficients); + (rx, ry) = _aggregateNonce(rNonces, coefficients); + } - (rx, ry) = _aggregateNonce(rNonces, coefficients); e = _computeChallenge(bytes32(rx), bytes32(px), m); + require(e < GhostEllipticCurves.N); // scalar check (rx, ry) = _restoreAdaptiveNonce(nonces, coefficients); } - { - require(signersHash == sha256(proof)); // check proof correctness - (px, py) = _aggregatePubkey(px, py, proof, missedIndexes); - } + require(signersHash == sha256(proof)); // check proof correctness + (px, py) = _aggregatePubkey(px, py, proof, missedIndexes); unchecked { s = GhostEllipticCurves.N - mulmod(s, px, GhostEllipticCurves.N); @@ -148,81 +151,6 @@ abstract contract GhostVerifier { return (r1x, r1y); } - function _computeAggregationCoefficients( - uint16 length, - bytes32[] memory ais, - bytes calldata proof - ) internal pure { - uint16 i = length; - for (; i > 0;) { - unchecked { --i; } - - uint256 pix; - uint16 l; - uint16 r; - - assembly { - let base := add(proof.offset, mul(i, 128)) - pix := calldataload(base) - - l := add(shl(1, i), 1) - r := add(l, 1) - } - - ais[i] = bytes32(_computeCoefficientKeyAgg( - l < length ? ais[l] : bytes32(0x0), - r < length ? ais[r] : bytes32(0x0), - bytes32(pix) - )); - } - } - - function _checkAggregationCorrectness( - uint256 xx, uint256 yy, uint256 ai, - bytes calldata proof - ) internal pure returns (uint256 res) { - uint256 px; - uint256 py; - uint256 pz; - - uint16 i; - for (; i < 3;) { - uint256 x; - uint256 y; - - assembly { - let base := add(proof.offset, mul(i, 128)) - let j := mul(gt(i, 0), 64) - x := calldataload(add(base, j)) - y := calldataload(add(base, add(32, j))) - } - - if (i == 0) { - (px, py, pz) = GhostEllipticCurves.mulAddAffineSingle(x, y, ai); - } else { - (px, py, pz) = GhostEllipticCurves.projectiveAddMixed(px, py, pz, x, y); - } - - unchecked { ++i; } - } - - (px, py) = GhostEllipticCurves.toAffine(px, py, pz); - uint256 hix; - assembly { - let base := proof.offset - hix := calldataload(add(base, 64)) - let hiy := calldataload(add(base, 96)) - - if iszero(and(eq(xx, px), eq(xx, hix))) { - revert(0, 0) - } - - if iszero(and(eq(yy, py), eq(yy, hiy))) { - revert(0, 0) - } - } - } - function _aggregatePubkey( uint256 px, uint256 py, bytes calldata proof,