Files
mev-beta/vendor/github.com/crate-crypto/go-ipa/ipa/verifier.go

105 lines
2.9 KiB
Go

package ipa
import (
"fmt"
"github.com/crate-crypto/go-ipa/bandersnatch/fr"
"github.com/crate-crypto/go-ipa/banderwagon"
"github.com/crate-crypto/go-ipa/common"
)
// CheckIPAProof verifies an IPA proof for a committed polynomial in evaluation form.
// It verifies that `proof` is a valid proof for the polynomial at the evaluation
// point `evalPoint` with result `result`
func CheckIPAProof(transcript *common.Transcript, ic *IPAConfig, commitment banderwagon.Element, proof IPAProof, evalPoint fr.Element, result fr.Element) (bool, error) {
transcript.DomainSep(labelDomainSep)
if len(proof.L) != len(proof.R) {
return false, fmt.Errorf("vectors L and R should be the same size")
}
if len(proof.L) != int(ic.numRounds) {
return false, fmt.Errorf("the number of points for L and R should be equal to the number of rounds")
}
b := computeBVector(ic, evalPoint)
transcript.AppendPoint(&commitment, labelC)
transcript.AppendScalar(&evalPoint, labelInputPoint)
transcript.AppendScalar(&result, labelOutputPoint)
w := transcript.ChallengeScalar(labelW)
// Rescaling of q.
var q banderwagon.Element
q.ScalarMul(&ic.Q, &w)
var qy banderwagon.Element
qy.ScalarMul(&q, &result)
commitment.Add(&commitment, &qy)
challenges := generateChallenges(transcript, &proof)
challengesInv := fr.BatchInvert(challenges)
// Compute expected commitment
var err error
for i := 0; i < len(challenges); i++ {
x := challenges[i]
L := proof.L[i]
R := proof.R[i]
commitment, err = commit([]banderwagon.Element{commitment, L, R}, []fr.Element{fr.One(), x, challengesInv[i]})
if err != nil {
return false, fmt.Errorf("could not compute commitment+x*L+x^-1*R: %w", err)
}
}
g := ic.SRS
// We compute the folding-scalars for g and b.
foldingScalars := make([]fr.Element, len(g))
for i := 0; i < len(g); i++ {
scalar := fr.One()
for challengeIdx := 0; challengeIdx < len(challenges); challengeIdx++ {
if i&(1<<(7-challengeIdx)) > 0 {
scalar.Mul(&scalar, &challengesInv[challengeIdx])
}
}
foldingScalars[i] = scalar
}
g0, err := MultiScalar(g, foldingScalars)
if err != nil {
return false, fmt.Errorf("could not compute g0: %w", err)
}
b0, err := InnerProd(b, foldingScalars)
if err != nil {
return false, fmt.Errorf("could not compute b0: %w", err)
}
var got banderwagon.Element
// g0 * a + (a * b) * Q;
var part_1 banderwagon.Element
part_1.ScalarMul(&g0, &proof.A_scalar)
var part_2 banderwagon.Element
var part_2a fr.Element
part_2a.Mul(&b0, &proof.A_scalar)
part_2.ScalarMul(&q, &part_2a)
got.Add(&part_1, &part_2)
return got.Equal(&commitment), nil
}
func generateChallenges(transcript *common.Transcript, proof *IPAProof) []fr.Element {
challenges := make([]fr.Element, len(proof.L))
for i := 0; i < len(proof.L); i++ {
transcript.AppendPoint(&proof.L[i], labelL)
transcript.AppendPoint(&proof.R[i], labelR)
challenges[i] = transcript.ChallengeScalar(labelX)
}
return challenges
}