Files
plonkathon/verifier.py
2023-01-28 14:36:17 -05:00

106 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import py_ecc.bn128 as b
from utils import *
from dataclasses import dataclass
from curve import *
from transcript import Transcript
from poly import Polynomial, Basis
@dataclass
class VerificationKey:
"""Verification key"""
# we set this to some power of 2 (so that we can FFT over it), that is at least the number of constraints we have (so we can Lagrange interpolate them)
group_order: int
# [q_M(x)]₁ (commitment to multiplication selector polynomial)
Qm: G1Point
# [q_L(x)]₁ (commitment to left selector polynomial)
Ql: G1Point
# [q_R(x)]₁ (commitment to right selector polynomial)
Qr: G1Point
# [q_O(x)]₁ (commitment to output selector polynomial)
Qo: G1Point
# [q_C(x)]₁ (commitment to constants selector polynomial)
Qc: G1Point
# [S_σ1(x)]₁ (commitment to the first permutation polynomial S_σ1(X))
S1: G1Point
# [S_σ2(x)]₁ (commitment to the second permutation polynomial S_σ2(X))
S2: G1Point
# [S_σ3(x)]₁ (commitment to the third permutation polynomial S_σ3(X))
S3: G1Point
# [x]₂ = xH, where H is a generator of G_2
X_2: G2Point
# nth root of unity (i.e. ω^1), where n is the program's group order.
w: Scalar
# More optimized version that tries hard to minimize pairings and
# elliptic curve multiplications, but at the cost of being harder
# to understand and mixing together a lot of the computations to
# efficiently batch them
def verify_proof(self, group_order: int, pf, public=[]) -> bool:
# 4. Compute challenges
# 5. Compute zero polynomial evaluation Z_H(ζ) = ζ^n - 1
# 6. Compute Lagrange polynomial evaluation L_0(ζ)
# 7. Compute public input polynomial evaluation PI(ζ).
# Compute the constant term of R. This is not literally the degree-0
# term of the R polynomial; rather, it's the portion of R that can
# be computed directly, without resorting to elliptic cutve commitments
# Compute D = (R - r0) + u * Z, and E and F
# Run one pairing check to verify the last two checks.
# What's going on here is a clever re-arrangement of terms to check
# the same equations that are being checked in the basic version,
# but in a way that minimizes the number of EC muls and even
# compressed the two pairings into one. The 2 pairings -> 1 pairing
# trick is basically to replace checking
#
# Y1 = A * (X - a) and Y2 = B * (X - b)
#
# with
#
# Y1 + A * a = A * X
# Y2 + B * b = B * X
#
# so at this point we can take a random linear combination of the two
# checks, and verify it with only one pairing.
return False
# Basic, easier-to-understand version of what's going on
def verify_proof_unoptimized(self, group_order: int, pf, public=[]) -> bool:
# 4. Compute challenges
# 5. Compute zero polynomial evaluation Z_H(ζ) = ζ^n - 1
# 6. Compute Lagrange polynomial evaluation L_0(ζ)
# 7. Compute public input polynomial evaluation PI(ζ).
# Recover the commitment to the linearization polynomial R,
# exactly the same as what was created by the prover
# Verify that R(z) = 0 and the prover-provided evaluations
# A(z), B(z), C(z), S1(z), S2(z) are all correct
# Verify that the provided value of Z(zeta*w) is correct
return False
# Compute challenges (should be same as those computed by prover)
def compute_challenges(
self, proof
) -> tuple[Scalar, Scalar, Scalar, Scalar, Scalar, Scalar]:
transcript = Transcript(b"plonk")
beta, gamma = transcript.round_1(proof.msg_1)
alpha, _fft_cofactor = transcript.round_2(proof.msg_2)
zeta = transcript.round_3(proof.msg_3)
v = transcript.round_4(proof.msg_4)
u = transcript.round_5(proof.msg_5)
return beta, gamma, alpha, zeta, v, u