chore: remove redundant fns

This commit is contained in:
rymnc 2023-07-03 18:15:21 +05:30
parent 2dd8d56d5f
commit 3ce9856d5b
No known key found for this signature in database
GPG Key ID: AAA088D5C68ECD34
4 changed files with 16 additions and 794 deletions

View File

@ -1,9 +0,0 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT
pragma solidity 0.8.15;
interface IVerifier {
function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)
external
view
returns (bool);
}

View File

@ -3,43 +3,16 @@
pragma solidity 0.8.15;
import {IPoseidonHasher} from "./PoseidonHasher.sol";
import {IVerifier} from "./IVerifier.sol";
/// The tree is full
error FullTree();
/// Invalid deposit amount
/// @param required The required deposit amount
/// @param provided The provided deposit amount
error InsufficientDeposit(uint256 required, uint256 provided);
/// Member is already registered
error DuplicateIdCommitment();
/// Invalid receiver address, when the receiver is the contract itself or 0x0
error InvalidReceiverAddress(address to);
/// Member is not registered
error MemberNotRegistered(uint256 idCommitment);
/// Member has no stake
error MemberHasNoStake(uint256 idCommitment);
/// User has insufficient balance to withdraw
error InsufficientWithdrawalBalance();
/// Contract has insufficient balance to return
error InsufficientContractBalance();
/// Invalid proof
error InvalidProof();
contract RLN {
/// @notice The deposit amount required to register as a member
uint256 public immutable MEMBERSHIP_DEPOSIT;
/// @notice The depth of the merkle tree
uint256 public immutable DEPTH;
uint256 public immutable DEPTH = 20;
/// @notice The size of the merkle tree, i.e 2^depth
uint256 public immutable SET_SIZE;
@ -47,134 +20,42 @@ contract RLN {
/// @notice The index of the next member to be registered
uint256 public idCommitmentIndex = 1;
/// @notice The amount of eth staked by each member
/// maps from idCommitment to the amount staked
mapping(uint256 => uint256) public stakedAmounts;
/// @notice The membership status of each member
/// maps from idCommitment to their index in the set
mapping(uint256 => uint256) public members;
/// @notice The balance of each user that can be withdrawn
mapping(address => uint256) public withdrawalBalance;
mapping(uint256 => bool) public members;
/// @notice The Poseidon hasher contract
IPoseidonHasher public immutable poseidonHasher;
/// @notice The groth16 verifier contract
IVerifier public immutable verifier;
/// Emitted when a new member is added to the set
/// @param idCommitment The idCommitment of the member
/// @param index The index of the member in the set
event MemberRegistered(uint256 idCommitment, uint256 index);
/// Emitted when a member is removed from the set
/// @param idCommitment The idCommitment of the member
/// @param index The index of the member in the set
event MemberWithdrawn(uint256 idCommitment, uint256 index);
constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier) {
MEMBERSHIP_DEPOSIT = membershipDeposit;
DEPTH = depth;
SET_SIZE = 1 << depth;
constructor(uint256[] memory constructMembers, address _poseidonHasher) {
poseidonHasher = IPoseidonHasher(_poseidonHasher);
verifier = IVerifier(_verifier);
SET_SIZE = 1 << DEPTH;
if (constructMembers.length > SET_SIZE) revert FullTree();
for (uint256 i = 0; i < constructMembers.length; i++) {
_register(constructMembers[i]);
}
/// Allows a user to register as a member
/// @param idCommitment The idCommitment of the member
function register(uint256 idCommitment) external payable {
if (msg.value != MEMBERSHIP_DEPOSIT) {
revert InsufficientDeposit(MEMBERSHIP_DEPOSIT, msg.value);
}
_register(idCommitment, msg.value);
}
/// Registers a member
/// @param idCommitment The idCommitment of the member
/// @param stake The amount of eth staked by the member
function _register(uint256 idCommitment, uint256 stake) internal {
if (members[idCommitment] != 0) revert DuplicateIdCommitment();
if (idCommitmentIndex >= SET_SIZE) revert FullTree();
function _register(uint256 idCommitment) internal {
if (members[idCommitment] != false) revert DuplicateIdCommitment();
members[idCommitment] = idCommitmentIndex;
stakedAmounts[idCommitment] = stake;
members[idCommitment] = true;
emit MemberRegistered(idCommitment, idCommitmentIndex);
idCommitmentIndex += 1;
}
/// @dev Allows a user to slash a member
/// @param idCommitment The idCommitment of the member
function slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) external {
_slash(idCommitment, receiver, proof);
}
/// @dev Slashes a member by removing them from the set, and adding their
/// stake to the receiver's available withdrawal balance
/// @param idCommitment The idCommitment of the member
/// @param receiver The address to receive the funds
function _slash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof) internal {
if (receiver == address(this) || receiver == address(0)) {
revert InvalidReceiverAddress(receiver);
}
if (members[idCommitment] == 0) revert MemberNotRegistered(idCommitment);
// check if member is registered
if (stakedAmounts[idCommitment] == 0) {
revert MemberHasNoStake(idCommitment);
}
if (!_verifyProof(idCommitment, receiver, proof)) {
revert InvalidProof();
}
uint256 amountToTransfer = stakedAmounts[idCommitment];
// delete member
uint256 index = members[idCommitment];
members[idCommitment] = 0;
stakedAmounts[idCommitment] = 0;
// refund deposit
withdrawalBalance[receiver] += amountToTransfer;
emit MemberWithdrawn(idCommitment, index);
}
/// Allows a user to withdraw funds allocated to them upon slashing a member
function withdraw() external {
uint256 amount = withdrawalBalance[msg.sender];
if (amount == 0) revert InsufficientWithdrawalBalance();
if (amount > address(this).balance) {
revert InsufficientContractBalance();
}
withdrawalBalance[msg.sender] = 0;
payable(msg.sender).transfer(amount);
}
/// Hashes a value using the Poseidon hasher
/// NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the second input is 0
/// @param input The value to hash
function hash(uint256 input) internal view returns (uint256) {
return poseidonHasher.hash(input);
}
/// @dev Groth16 proof verification
function _verifyProof(uint256 idCommitment, address receiver, uint256[8] calldata proof)
internal
view
returns (bool)
{
return verifier.verifyProof(
[proof[0], proof[1]],
[[proof[2], proof[3]], [proof[4], proof[5]]],
[proof[6], proof[7]],
[idCommitment, uint256(uint160(receiver))]
);
}
}

View File

@ -1,303 +0,0 @@
// File: https://github.com/Rate-Limiting-Nullifier/rln-contract-v1/blob/main/src/RLNVerifier.sol
// 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.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// 2019 OKIMS
// ported to solidity 0.6
// fixed linter warnings
// added requiere error messages
//
//
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.11;
library Pairing {
struct G1Point {
uint256 X;
uint256 Y;
}
// Encoding of field elements is: X[0] * z + X[1]
struct G2Point {
uint256[2] X;
uint256[2] Y;
}
/// @return the generator of G1
function P1() internal pure returns (G1Point memory) {
return G1Point(1, 2);
}
/// @return the generator of G2
function P2() internal pure returns (G2Point memory) {
// Original code point
return G2Point(
[
11559732032986387107991004021392285783925812861821192530917403151452391805634,
10857046999023057135944570762232829481370756359578518086990519993285655852781
],
[
4082367875863433681332203403145435568316851327593401208105741076214120093531,
8495653923123431417604973247489272438418190587263600148770280649306958101930
]
);
/*
// Changed by Jordi point
return G2Point(
[10857046999023057135944570762232829481370756359578518086990519993285655852781,
11559732032986387107991004021392285783925812861821192530917403151452391805634],
[8495653923123431417604973247489272438418190587263600148770280649306958101930,
4082367875863433681332203403145435568316851327593401208105741076214120093531]
);*/
}
/// @return r the negation of p, i.e. p.addition(p.negate()) should be zero.
function negate(G1Point memory p) internal pure returns (G1Point memory r) {
// The prime q in the base field F_q for G1
uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
if (p.X == 0 && p.Y == 0) {
return G1Point(0, 0);
}
return G1Point(p.X, q - (p.Y % q));
}
/// @return r the sum of two points of G1
function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {
uint256[4] memory input;
input[0] = p1.X;
input[1] = p1.Y;
input[2] = p2.X;
input[3] = p2.Y;
bool success;
// solium-disable-next-line security/no-inline-assembly
assembly {
success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)
// Use "invalid" to make gas estimation work
switch success
case 0 { invalid() }
}
require(success, "pairing-add-failed");
}
/// @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, uint256 s) internal view returns (G1Point memory r) {
uint256[3] memory input;
input[0] = p.X;
input[1] = p.Y;
input[2] = s;
bool success;
// solium-disable-next-line security/no-inline-assembly
assembly {
success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)
// Use "invalid" to make gas estimation work
switch success
case 0 { invalid() }
}
require(success, "pairing-mul-failed");
}
/// @return the result of computing the pairing check
/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1
/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should
/// return true.
function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {
require(p1.length == p2.length, "pairing-lengths-failed");
uint256 elements = p1.length;
uint256 inputSize = elements * 6;
uint256[] memory input = new uint[](inputSize);
for (uint256 i = 0; i < elements; i++) {
input[i * 6 + 0] = p1[i].X;
input[i * 6 + 1] = p1[i].Y;
input[i * 6 + 2] = p2[i].X[0];
input[i * 6 + 3] = p2[i].X[1];
input[i * 6 + 4] = p2[i].Y[0];
input[i * 6 + 5] = p2[i].Y[1];
}
uint256[1] memory out;
bool success;
// solium-disable-next-line security/no-inline-assembly
assembly {
success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
// Use "invalid" to make gas estimation work
switch success
case 0 { invalid() }
}
require(success, "pairing-opcode-failed");
return out[0] != 0;
}
/// Convenience method for a pairing check for two pairs.
function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2)
internal
view
returns (bool)
{
G1Point[] memory p1 = new G1Point[](2);
G2Point[] memory p2 = new G2Point[](2);
p1[0] = a1;
p1[1] = b1;
p2[0] = a2;
p2[1] = b2;
return pairing(p1, p2);
}
/// Convenience method for a pairing check for three pairs.
function pairingProd3(
G1Point memory a1,
G2Point memory a2,
G1Point memory b1,
G2Point memory b2,
G1Point memory c1,
G2Point memory c2
) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](3);
G2Point[] memory p2 = new G2Point[](3);
p1[0] = a1;
p1[1] = b1;
p1[2] = c1;
p2[0] = a2;
p2[1] = b2;
p2[2] = c2;
return pairing(p1, p2);
}
/// Convenience method for a pairing check for four pairs.
function pairingProd4(
G1Point memory a1,
G2Point memory a2,
G1Point memory b1,
G2Point memory b2,
G1Point memory c1,
G2Point memory c2,
G1Point memory d1,
G2Point memory d2
) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](4);
G2Point[] memory p2 = new G2Point[](4);
p1[0] = a1;
p1[1] = b1;
p1[2] = c1;
p1[3] = d1;
p2[0] = a2;
p2[1] = b2;
p2[2] = c2;
p2[3] = d2;
return pairing(p1, p2);
}
}
contract Verifier {
using Pairing for *;
struct VerifyingKey {
Pairing.G1Point alfa1;
Pairing.G2Point beta2;
Pairing.G2Point gamma2;
Pairing.G2Point delta2;
Pairing.G1Point[] IC;
}
struct Proof {
Pairing.G1Point A;
Pairing.G2Point B;
Pairing.G1Point C;
}
function verifyingKey() internal pure returns (VerifyingKey memory vk) {
vk.alfa1 = Pairing.G1Point(
20491192805390485299153009773594534940189261866228447918068658471970481763042,
9383485363053290200918347156157836566562967994039712273449902621266178545958
);
vk.beta2 = Pairing.G2Point(
[
4252822878758300859123897981450591353533073413197771768651442665752259397132,
6375614351688725206403948262868962793625744043794305715222011528459656738731
],
[
21847035105528745403288232691147584728191162732299865338377159692350059136679,
10505242626370262277552901082094356697409835680220590971873171140371331206856
]
);
vk.gamma2 = Pairing.G2Point(
[
11559732032986387107991004021392285783925812861821192530917403151452391805634,
10857046999023057135944570762232829481370756359578518086990519993285655852781
],
[
4082367875863433681332203403145435568316851327593401208105741076214120093531,
8495653923123431417604973247489272438418190587263600148770280649306958101930
]
);
vk.delta2 = Pairing.G2Point(
[
12423666958566268737444308034237892912702648013927558883280319245968679130649,
15986964528637281931410749976607406939789163617014270799373312764775965360012
],
[
8394023076056524902583796202128496802110914536948580183128578071394816660799,
4964607673011101982600772762445991192038811950832626693345350322823626470007
]
);
vk.IC = new Pairing.G1Point[](3);
vk.IC[0] = Pairing.G1Point(
1655549413518972190198478012616802994254462093161203201613599472264958303841,
21742734017792296281216385119397138748114275727065024271646515586404591497876
);
vk.IC[1] = Pairing.G1Point(
16497930821522159474595176304955625435616718625609462506360632944366974274906,
10404924572941018678793755094259635830045501866471999610240845041996101882275
);
vk.IC[2] = Pairing.G1Point(
9567910551099174794221497568036631681620409346997815381833929247558241020796,
17282591858786007768931802126325866705896012606427630592145070155065868649172
);
}
function verify(uint256[] memory input, Proof memory proof) internal view returns (uint256) {
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
VerifyingKey memory vk = verifyingKey();
require(input.length + 1 == vk.IC.length, "verifier-bad-input");
// Compute the linear combination vk_x
Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);
for (uint256 i = 0; i < input.length; i++) {
require(input[i] < snark_scalar_field, "verifier-gte-snark-scalar-field");
vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));
}
vk_x = Pairing.addition(vk_x, vk.IC[0]);
if (
!Pairing.pairingProd4(
Pairing.negate(proof.A), proof.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, proof.C, vk.delta2
)
) return 1;
return 0;
}
/// @return r bool true if proof is valid
function verifyProof(uint256[2] memory a, uint256[2][2] memory b, uint256[2] memory c, uint256[2] memory input)
public
view
returns (bool r)
{
Proof memory proof;
proof.A = Pairing.G1Point(a[0], a[1]);
proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
proof.C = Pairing.G1Point(c[0], c[1]);
uint256[] memory inputValues = new uint[](input.length);
for (uint256 i = 0; i < input.length; i++) {
inputValues[i] = input[i];
}
if (verify(inputValues, proof) == 0) {
return true;
} else {
return false;
}
}
}

View File

@ -1,13 +1,5 @@
# Solidity API
## IVerifier
### verifyProof
```solidity
function verifyProof(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[2] input) external view returns (bool)
```
## IPoseidonHasher
### hash
@ -852,21 +844,6 @@ error FullTree()
The tree is full
## InsufficientDeposit
```solidity
error InsufficientDeposit(uint256 required, uint256 provided)
```
Invalid deposit amount
### Parameters
| Name | Type | Description |
| -------- | ------- | --------------------------- |
| required | uint256 | The required deposit amount |
| provided | uint256 | The provided deposit amount |
## DuplicateIdCommitment
```solidity
@ -875,64 +852,8 @@ error DuplicateIdCommitment()
Member is already registered
## InvalidReceiverAddress
```solidity
error InvalidReceiverAddress(address to)
```
Invalid receiver address, when the receiver is the contract itself or 0x0
## MemberNotRegistered
```solidity
error MemberNotRegistered(uint256 idCommitment)
```
Member is not registered
## MemberHasNoStake
```solidity
error MemberHasNoStake(uint256 idCommitment)
```
Member has no stake
## InsufficientWithdrawalBalance
```solidity
error InsufficientWithdrawalBalance()
```
User has insufficient balance to withdraw
## InsufficientContractBalance
```solidity
error InsufficientContractBalance()
```
Contract has insufficient balance to return
## InvalidProof
```solidity
error InvalidProof()
```
Invalid proof
## RLN
### MEMBERSHIP_DEPOSIT
```solidity
uint256 MEMBERSHIP_DEPOSIT
```
The deposit amount required to register as a member
### DEPTH
```solidity
@ -957,32 +878,15 @@ uint256 idCommitmentIndex
The index of the next member to be registered
### stakedAmounts
```solidity
mapping(uint256 => uint256) stakedAmounts
```
The amount of eth staked by each member
maps from idCommitment to the amount staked
### members
```solidity
mapping(uint256 => uint256) members
mapping(uint256 => bool) members
```
The membership status of each member
maps from idCommitment to their index in the set
### withdrawalBalance
```solidity
mapping(address => uint256) withdrawalBalance
```
The balance of each user that can be withdrawn
### poseidonHasher
```solidity
@ -991,14 +895,6 @@ contract IPoseidonHasher poseidonHasher
The Poseidon hasher contract
### verifier
```solidity
contract IVerifier verifier
```
The groth16 verifier contract
### MemberRegistered
```solidity
@ -1014,45 +910,16 @@ Emitted when a new member is added to the set
| idCommitment | uint256 | The idCommitment of the member |
| index | uint256 | The index of the member in the set |
### MemberWithdrawn
```solidity
event MemberWithdrawn(uint256 idCommitment, uint256 index)
```
Emitted when a member is removed from the set
#### Parameters
| Name | Type | Description |
| ------------ | ------- | ---------------------------------- |
| idCommitment | uint256 | The idCommitment of the member |
| index | uint256 | The index of the member in the set |
### constructor
```solidity
constructor(uint256 membershipDeposit, uint256 depth, address _poseidonHasher, address _verifier) public
constructor(uint256[] constructMembers, address _poseidonHasher) public
```
### register
```solidity
function register(uint256 idCommitment) external payable
```
Allows a user to register as a member
#### Parameters
| Name | Type | Description |
| ------------ | ------- | ------------------------------ |
| idCommitment | uint256 | The idCommitment of the member |
### \_register
```solidity
function _register(uint256 idCommitment, uint256 stake) internal
function _register(uint256 idCommitment) internal
```
Registers a member
@ -1060,50 +927,8 @@ Registers a member
#### Parameters
| Name | Type | Description |
| ------------ | ------- | -------------------------------------- |
| ------------ | ------- | ------------------------------ |
| idCommitment | uint256 | The idCommitment of the member |
| stake | uint256 | The amount of eth staked by the member |
### slash
```solidity
function slash(uint256 idCommitment, address payable receiver, uint256[8] proof) external
```
_Allows a user to slash a member_
#### Parameters
| Name | Type | Description |
| ------------ | --------------- | ------------------------------ |
| idCommitment | uint256 | The idCommitment of the member |
| receiver | address payable | |
| proof | uint256[8] | |
### \_slash
```solidity
function _slash(uint256 idCommitment, address payable receiver, uint256[8] proof) internal
```
_Slashes a member by removing them from the set, and adding their
stake to the receiver's available withdrawal balance_
#### Parameters
| Name | Type | Description |
| ------------ | --------------- | -------------------------------- |
| idCommitment | uint256 | The idCommitment of the member |
| receiver | address payable | The address to receive the funds |
| proof | uint256[8] | |
### withdraw
```solidity
function withdraw() external
```
Allows a user to withdraw funds allocated to them upon slashing a member
### hash
@ -1119,175 +944,3 @@ NOTE: The variant of Poseidon we use accepts only 1 input, assume n=2, and the s
| Name | Type | Description |
| ----- | ------- | ----------------- |
| input | uint256 | The value to hash |
### \_verifyProof
```solidity
function _verifyProof(uint256 idCommitment, address receiver, uint256[8] proof) internal view returns (bool)
```
_Groth16 proof verification_
## Pairing
### G1Point
```solidity
struct G1Point {
uint256 X;
uint256 Y;
}
```
### G2Point
```solidity
struct G2Point {
uint256[2] X;
uint256[2] Y;
}
```
### P1
```solidity
function P1() internal pure returns (struct Pairing.G1Point)
```
#### Return Values
| Name | Type | Description |
| ---- | ---------------------- | ------------------- |
| [0] | struct Pairing.G1Point | the generator of G1 |
### P2
```solidity
function P2() internal pure returns (struct Pairing.G2Point)
```
#### Return Values
| Name | Type | Description |
| ---- | ---------------------- | ------------------- |
| [0] | struct Pairing.G2Point | the generator of G2 |
### negate
```solidity
function negate(struct Pairing.G1Point p) internal pure returns (struct Pairing.G1Point r)
```
#### Return Values
| Name | Type | Description |
| ---- | ---------------------- | -------------------------------------------------------------- |
| r | struct Pairing.G1Point | the negation of p, i.e. p.addition(p.negate()) should be zero. |
### addition
```solidity
function addition(struct Pairing.G1Point p1, struct Pairing.G1Point p2) internal view returns (struct Pairing.G1Point r)
```
#### Return Values
| Name | Type | Description |
| ---- | ---------------------- | --------------------------- |
| r | struct Pairing.G1Point | the sum of two points of G1 |
### scalar_mul
```solidity
function scalar_mul(struct Pairing.G1Point p, uint256 s) internal view returns (struct Pairing.G1Point r)
```
#### Return Values
| Name | Type | Description |
| ---- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| r | struct Pairing.G1Point | 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. |
### pairing
```solidity
function pairing(struct Pairing.G1Point[] p1, struct Pairing.G2Point[] p2) internal view returns (bool)
```
#### Return Values
| Name | Type | Description |
| ---- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [0] | bool | the result of computing the pairing check e(p1[0], p2[0]) _ .... _ e(p1[n], p2[n]) == 1 For example pairing([P1(), P1().negate()], [P2(), P2()]) should return true. |
### pairingProd2
```solidity
function pairingProd2(struct Pairing.G1Point a1, struct Pairing.G2Point a2, struct Pairing.G1Point b1, struct Pairing.G2Point b2) internal view returns (bool)
```
Convenience method for a pairing check for two pairs.
### pairingProd3
```solidity
function pairingProd3(struct Pairing.G1Point a1, struct Pairing.G2Point a2, struct Pairing.G1Point b1, struct Pairing.G2Point b2, struct Pairing.G1Point c1, struct Pairing.G2Point c2) internal view returns (bool)
```
Convenience method for a pairing check for three pairs.
### pairingProd4
```solidity
function pairingProd4(struct Pairing.G1Point a1, struct Pairing.G2Point a2, struct Pairing.G1Point b1, struct Pairing.G2Point b2, struct Pairing.G1Point c1, struct Pairing.G2Point c2, struct Pairing.G1Point d1, struct Pairing.G2Point d2) internal view returns (bool)
```
Convenience method for a pairing check for four pairs.
## Verifier
### VerifyingKey
```solidity
struct VerifyingKey {
struct Pairing.G1Point alfa1;
struct Pairing.G2Point beta2;
struct Pairing.G2Point gamma2;
struct Pairing.G2Point delta2;
struct Pairing.G1Point[] IC;
}
```
### Proof
```solidity
struct Proof {
struct Pairing.G1Point A;
struct Pairing.G2Point B;
struct Pairing.G1Point C;
}
```
### verifyingKey
```solidity
function verifyingKey() internal pure returns (struct Verifier.VerifyingKey vk)
```
### verify
```solidity
function verify(uint256[] input, struct Verifier.Proof proof) internal view returns (uint256)
```
### verifyProof
```solidity
function verifyProof(uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[2] input) public view returns (bool r)
```
#### Return Values
| Name | Type | Description |
| ---- | ---- | --------------------------- |
| r | bool | bool true if proof is valid |