Skip to content

Commit

Permalink
Fixed verifier returns (#8)
Browse files Browse the repository at this point in the history
* fixed verifier

* optimizied verifier
  • Loading branch information
Arvolear authored Jul 12, 2024
1 parent 2fabd6c commit 0da31ca
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 68 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@solarity/zkit",
"version": "0.2.2",
"version": "0.2.3",
"license": "MIT",
"author": "Distributed Lab",
"readme": "README.md",
Expand Down
123 changes: 58 additions & 65 deletions src/core/templates/verifier_groth16.sol.ejs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// SPDX-License-Identifier: MIT

/* AUTOGENERATED FILE BY HARDHAT-ZKIT. DO NOT EDIT. */

pragma solidity >=0.7.0 <0.9.0;

contract <%=verifier_id%> {
/// @dev Base field size
/// @dev base field size
uint256 public constant BASE_FIELD_SIZE =
21888242871839275222246405745257275088696311157297823662689037894645226208583;

/// @dev Verification Key data
/// @dev verification key data
uint256 public constant ALPHA_X =
<%=vk_alpha_1[0]%>;
uint256 public constant ALPHA_Y =
Expand Down Expand Up @@ -42,75 +45,66 @@ contract <%=verifier_id%> {
<%=IC[i][1]%>;
<% } -%>

/// @dev Memory data
uint16 public constant P_VK = 0;
uint16 public constant P_PAIRING = 128;
uint16 public constant P_LAST_MEM = 896;
/// @dev memory pointer sizes
uint16 public constant P_PUBLIC_SIGNALS_ACCUMULATOR_SIZE = 128;
uint16 public constant P_TOTAL_SIZE = 896;

function verifyProof(
uint256[2] memory pA_,
uint256[2][2] memory pB_,
uint256[2] memory pC_,
uint256[<%=IC.length-1%>] memory pubSignals_
) public view returns (bool) {
uint256[2] memory pointA_,
uint256[2][2] memory pointB_,
uint256[2] memory pointC_,
uint256[<%=IC.length-1%>] memory publicSignals_
) public view returns (bool verified_) {
assembly {
function checkField(v) {
if iszero(lt(v, BASE_FIELD_SIZE)) {
mstore(0, 0)
return(0, 0x20)
}
function checkField(signal_) -> res_ {
res_ := lt(signal_, BASE_FIELD_SIZE)
}

/// @dev G1 function to multiply a G1 value(x,y) to value in an address
function g1MulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
function g1MulAdd(pR_, x_, y_, s_) -> res_ {
let pointer_ := mload(64) // free pointer

mstore(mIn, x)
mstore(add(mIn, 32), y)
mstore(add(mIn, 64), s)
mstore(pointer_, x_)
mstore(add(pointer_, 32), y_)
mstore(add(pointer_, 64), s_)

success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
res_ := staticcall(sub(gas(), 2000), 7, pointer_, 96, pointer_, 64) // ecMul
res_ := and(res_, gt(returndatasize(), 0)) // check that multiplication succeeded

if iszero(success) {
mstore(0, 0)
return(0, 0x20)
if iszero(res_) {
leave
}

mstore(add(mIn, 64), mload(pR))
mstore(add(mIn, 96), mload(add(pR, 32)))
mstore(add(pointer_, 64), mload(pR_))
mstore(add(pointer_, 96), mload(add(pR_, 32)))

success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
res_ := staticcall(sub(gas(), 2000), 6, pointer_, 128, pR_, 64) // ecAdd
res_ := and(res_, gt(returndatasize(), 0)) // check that addition succeeded
}

function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
let pPairing_ := add(pMem, P_PAIRING)
let pVk_ := add(pMem, P_VK)
function checkPairing(pA_, pB_, pC_, pubSignals_, pointer_) -> res_ {
let pPairing_ := add(pointer_, P_PUBLIC_SIGNALS_ACCUMULATOR_SIZE)

mstore(pVk_, IC0_X)
mstore(add(pVk_, 32), IC0_Y)
mstore(pointer_, IC0_X)
mstore(add(pointer_, 32), IC0_Y)

/// @dev Compute the linear combination vk_x
<% for (let i = 1; i <= nPublic; i++) { %>g1MulAccC(pVk_, IC<%=i%>_X, IC<%=i%>_Y, mload(add(pubSignals, <%=(i-1)*32%>)))
/// @dev compute the linear combination of public signals
<% for (let i = 1; i <= nPublic; i++) { %>if iszero(g1MulAdd(pointer_, IC<%=i%>_X, IC<%=i%>_Y, mload(add(pubSignals_, <%=(i-1)*32%>)))) {
leave
}
<% } -%>

/// @dev -A
mstore(pPairing_, mload(pA))
mstore(pPairing_, mload(pA_))
mstore(
add(pPairing_, 32),
mod(sub(BASE_FIELD_SIZE, mload(add(pA, 32))), BASE_FIELD_SIZE)
mod(sub(BASE_FIELD_SIZE, mload(add(pA_, 32))), BASE_FIELD_SIZE)
)

/// @dev B
mstore(add(pPairing_, 64), mload(mload(pB)))
mstore(add(pPairing_, 96), mload(add(mload(pB), 32)))
mstore(add(pPairing_, 128), mload(mload(add(pB, 32))))
mstore(add(pPairing_, 160), mload(add(mload(add(pB, 32)), 32)))
mstore(add(pPairing_, 64), mload(mload(pB_)))
mstore(add(pPairing_, 96), mload(add(mload(pB_), 32)))
mstore(add(pPairing_, 128), mload(mload(add(pB_, 32))))
mstore(add(pPairing_, 160), mload(add(mload(add(pB_, 32)), 32)))

/// @dev alpha1
mstore(add(pPairing_, 192), ALPHA_X)
Expand All @@ -122,9 +116,9 @@ contract <%=verifier_id%> {
mstore(add(pPairing_, 320), BETA_Y1)
mstore(add(pPairing_, 352), BETA_Y2)

/// @dev vk_x
mstore(add(pPairing_, 384), mload(add(pMem, P_VK)))
mstore(add(pPairing_, 416), mload(add(pMem, add(P_VK, 32))))
/// @dev public signals
mstore(add(pPairing_, 384), mload(pointer_))
mstore(add(pPairing_, 416), mload(add(pointer_, 32)))

/// @dev gamma2
mstore(add(pPairing_, 448), GAMMA_X1)
Expand All @@ -133,32 +127,31 @@ contract <%=verifier_id%> {
mstore(add(pPairing_, 544), GAMMA_Y2)

/// @dev C
mstore(add(pPairing_, 576), mload(pC))
mstore(add(pPairing_, 608), mload(add(pC, 32)))
mstore(add(pPairing_, 576), mload(pC_))
mstore(add(pPairing_, 608), mload(add(pC_, 32)))

/// @dev delta2
mstore(add(pPairing_, 640), DELTA_X1)
mstore(add(pPairing_, 672), DELTA_X2)
mstore(add(pPairing_, 704), DELTA_Y1)
mstore(add(pPairing_, 736), DELTA_Y2)

let success_ := staticcall(sub(gas(), 2000), 8, pPairing_, 768, pPairing_, 0x20)

isOk := and(success_, mload(pPairing_))
res_ := staticcall(sub(gas(), 2000), 8, pPairing_, 768, pPairing_, 32) // ecPairing
res_ := and(res_, mload(pPairing_)) // check that pairing succeeded
}

let pMem_ := mload(0x40)
mstore(0x40, add(pMem_, P_LAST_MEM))
let pointer_ := mload(64) // free pointer
mstore(64, add(pointer_, P_TOTAL_SIZE))

/// @dev Validate that all evaluations ∈ F
<% for (let i = 0; i < IC.length; i++) { %>checkField(mload(add(pubSignals_, <%=i*32%>)))
/// @dev check that all public signals are in F
verified_ := 1
<% for (let i = 0; i < IC.length; i++) { %>verified_ := and(verified_, checkField(mload(add(publicSignals_, <%=i*32%>))))
<% } -%>

/// @dev Validate all evaluations
let isValid := checkPairing(pA_, pB_, pC_, pubSignals_, pMem_)

mstore(0, isValid)
return(0, 0x20)
/// @dev check pairings
if not(iszero(verified_)) {
verified_ := checkPairing(pointA_, pointB_, pointC_, publicSignals_, pointer_)
}
}
}
}

0 comments on commit 0da31ca

Please sign in to comment.