mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 00:51:33 +01:00
Use optimized goldilocks in codebase (#26)
* gl * stage 1 optimizations * working optimized poseidon * Fix posedion tests * in progress gate type refactor * working gates * working e2e * hm' * hm2 * debug saga continues * more debugging cry * more debug * it finally works * optimizations * more optimizations * new changes * more optimizations * more cleanup * some refactoring * new files * flattening of packages * working commit * more refactor * more flattening * more flattening * more more refactor * more optimizations * more optimizations * more optimizations * plonk benchmark * plonk * fix r1cs * resolve kevin's comments * Update goldilocks/base.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * Update goldilocks/base.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * Update goldilocks/base.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * Update goldilocks/quadratic_extension.go Co-authored-by: Kevin Jue <kjue235@gmail.com> * fix: resolve kevin's confusion --------- Co-authored-by: Kevin Jue <kjue235@gmail.com>
This commit is contained in:
@@ -1,57 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
)
|
||||
|
||||
type VerifierOnlyCircuitData struct {
|
||||
ConstantSigmasCap MerkleCap
|
||||
CircuitDigest poseidon.PoseidonBN128HashOut
|
||||
}
|
||||
|
||||
type CircuitConfig struct {
|
||||
NumWires uint64
|
||||
NumRoutedWires uint64
|
||||
NumConstants uint64
|
||||
UseBaseArithmeticGate bool
|
||||
SecurityBits uint64
|
||||
NumChallenges uint64
|
||||
ZeroKnowledge bool
|
||||
MaxQuotientDegreeFactor uint64
|
||||
FriConfig FriConfig
|
||||
}
|
||||
|
||||
type CommonCircuitData struct {
|
||||
Config CircuitConfig
|
||||
FriParams FriParams
|
||||
Gates []gates.Gate
|
||||
SelectorsInfo gates.SelectorsInfo
|
||||
DegreeBits uint64
|
||||
QuotientDegreeFactor uint64
|
||||
NumGateConstraints uint64
|
||||
NumConstants uint64
|
||||
NumPublicInputs uint64
|
||||
KIs []field.F
|
||||
NumPartialProducts uint64
|
||||
}
|
||||
|
||||
type FriConfig struct {
|
||||
RateBits uint64
|
||||
CapHeight uint64
|
||||
ProofOfWorkBits uint64
|
||||
NumQueryRounds uint64
|
||||
// TODO: add FriReductionStrategy
|
||||
}
|
||||
|
||||
func (fc *FriConfig) Rate() float64 {
|
||||
return 1.0 / float64((uint64(1) << fc.RateBits))
|
||||
}
|
||||
|
||||
type FriParams struct {
|
||||
Config FriConfig
|
||||
Hiding bool
|
||||
DegreeBits uint64
|
||||
ReductionArityBits []uint64
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
)
|
||||
|
||||
type MerkleCap = []poseidon.PoseidonBN128HashOut
|
||||
|
||||
func NewMerkleCap(capHeight uint64) MerkleCap {
|
||||
return make([]poseidon.PoseidonBN128HashOut, 1<<capHeight)
|
||||
}
|
||||
|
||||
type MerkleProof struct {
|
||||
Siblings []poseidon.PoseidonBN128HashOut // Length = CircuitConfig.FriConfig.DegreeBits + CircuitConfig.FriConfig.RateBits - CircuitConfig.FriConfig.CapHeight
|
||||
}
|
||||
|
||||
func NewMerkleProof(merkleProofLen uint64) MerkleProof {
|
||||
return MerkleProof{Siblings: make([]poseidon.PoseidonBN128HashOut, merkleProofLen)}
|
||||
}
|
||||
|
||||
type EvalProof struct {
|
||||
Elements []field.F // Length = [CommonCircuitData.Constants + CommonCircuitData.NumRoutedWires, CommonCircuitData.NumWires + CommonCircuitData.FriParams.Hiding ? 4 : 0, CommonCircuitData.NumChallenges * (1 + CommonCircuitData.NumPartialProducts) + salt, CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor + salt]
|
||||
MerkleProof MerkleProof
|
||||
}
|
||||
|
||||
func NewEvalProof(elements []field.F, merkleProof MerkleProof) EvalProof {
|
||||
return EvalProof{Elements: elements, MerkleProof: merkleProof}
|
||||
}
|
||||
|
||||
type PolynomialCoeffs struct {
|
||||
Coeffs []field.QuadraticExtension
|
||||
}
|
||||
|
||||
func NewPolynomialCoeffs(numCoeffs uint64) PolynomialCoeffs {
|
||||
return PolynomialCoeffs{Coeffs: make([]field.QuadraticExtension, numCoeffs)}
|
||||
}
|
||||
|
||||
type OpeningSet struct {
|
||||
Constants []field.QuadraticExtension // Length = CommonCircuitData.Constants
|
||||
PlonkSigmas []field.QuadraticExtension // Length = CommonCircuitData.NumRoutedWires
|
||||
Wires []field.QuadraticExtension // Length = CommonCircuitData.NumWires
|
||||
PlonkZs []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges
|
||||
PlonkZsNext []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges
|
||||
PartialProducts []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges * CommonCircuitData.NumPartialProducts
|
||||
QuotientPolys []field.QuadraticExtension // Length = CommonCircuitData.NumChallenges * CommonCircuitData.QuotientDegreeFactor
|
||||
}
|
||||
|
||||
func NewOpeningSet(numConstants uint64, numRoutedWires uint64, numWires uint64, numChallenges uint64, numPartialProducts uint64, quotientDegreeFactor uint64) OpeningSet {
|
||||
return OpeningSet{
|
||||
Constants: make([]field.QuadraticExtension, numConstants),
|
||||
PlonkSigmas: make([]field.QuadraticExtension, numRoutedWires),
|
||||
Wires: make([]field.QuadraticExtension, numWires),
|
||||
PlonkZs: make([]field.QuadraticExtension, numChallenges),
|
||||
PlonkZsNext: make([]field.QuadraticExtension, numChallenges),
|
||||
PartialProducts: make([]field.QuadraticExtension, numChallenges*numPartialProducts),
|
||||
QuotientPolys: make([]field.QuadraticExtension, numChallenges*quotientDegreeFactor),
|
||||
}
|
||||
}
|
||||
|
||||
type Proof struct {
|
||||
WiresCap MerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
||||
PlonkZsPartialProductsCap MerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
||||
QuotientPolysCap MerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
||||
Openings OpeningSet
|
||||
OpeningProof FriProof
|
||||
}
|
||||
|
||||
type ProofWithPublicInputs struct {
|
||||
Proof Proof
|
||||
PublicInputs []field.F // Length = CommonCircuitData.NumPublicInputs
|
||||
}
|
||||
|
||||
type ProofChallenges struct {
|
||||
PlonkBetas []field.F
|
||||
PlonkGammas []field.F
|
||||
PlonkAlphas []field.F
|
||||
PlonkZeta field.QuadraticExtension
|
||||
FriChallenges FriChallenges
|
||||
}
|
||||
|
||||
type FriInitialTreeProof struct {
|
||||
EvalsProofs []EvalProof // Length = 4
|
||||
}
|
||||
|
||||
func NewFriInitialTreeProof(evalsProofs []EvalProof) FriInitialTreeProof {
|
||||
return FriInitialTreeProof{EvalsProofs: evalsProofs}
|
||||
}
|
||||
|
||||
type FriQueryStep struct {
|
||||
Evals []field.QuadraticExtension // Length = [2^arityBit for arityBit in CommonCircuitData.FriParams.ReductionArityBits]
|
||||
MerkleProof MerkleProof // Length = [regularSize - arityBit for arityBit in CommonCircuitData.FriParams.ReductionArityBits]
|
||||
}
|
||||
|
||||
func NewFriQueryStep(arityBit uint64, merkleProofLen uint64) FriQueryStep {
|
||||
return FriQueryStep{
|
||||
Evals: make([]field.QuadraticExtension, 1<<arityBit),
|
||||
MerkleProof: NewMerkleProof(merkleProofLen),
|
||||
}
|
||||
}
|
||||
|
||||
type FriQueryRound struct {
|
||||
InitialTreesProof FriInitialTreeProof
|
||||
Steps []FriQueryStep // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
|
||||
}
|
||||
|
||||
func NewFriQueryRound(steps []FriQueryStep, initialTreesProof FriInitialTreeProof) FriQueryRound {
|
||||
return FriQueryRound{InitialTreesProof: initialTreesProof, Steps: steps}
|
||||
}
|
||||
|
||||
type FriProof struct {
|
||||
CommitPhaseMerkleCaps []MerkleCap // Length = Len(CommonCircuitData.FriParams.ReductionArityBits)
|
||||
QueryRoundProofs []FriQueryRound // Length = CommonCircuitData.FriConfig.FriParams.NumQueryRounds
|
||||
FinalPoly PolynomialCoeffs
|
||||
PowWitness field.F
|
||||
}
|
||||
|
||||
type FriChallenges struct {
|
||||
FriAlpha field.QuadraticExtension
|
||||
FriBetas []field.QuadraticExtension
|
||||
FriPowResponse field.F
|
||||
FriQueryIndices []field.F
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -7,11 +7,10 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/utils"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/types"
|
||||
)
|
||||
|
||||
type ProofWithPublicInputsRaw struct {
|
||||
@@ -147,9 +146,9 @@ type VerifierOnlyCircuitDataRaw struct {
|
||||
CircuitDigest string `json:"circuit_digest"`
|
||||
}
|
||||
|
||||
func DeserializeMerkleCap(merkleCapRaw []string) common.MerkleCap {
|
||||
func DeserializeMerkleCap(merkleCapRaw []string) types.FriMerkleCap {
|
||||
n := len(merkleCapRaw)
|
||||
merkleCap := make([]poseidon.PoseidonBN128HashOut, n)
|
||||
merkleCap := make([]poseidon.BN254HashOut, n)
|
||||
for i := 0; i < n; i++ {
|
||||
capBigInt, _ := new(big.Int).SetString(merkleCapRaw[i], 10)
|
||||
merkleCap[i] = frontend.Variable(capBigInt)
|
||||
@@ -157,13 +156,13 @@ func DeserializeMerkleCap(merkleCapRaw []string) common.MerkleCap {
|
||||
return merkleCap
|
||||
}
|
||||
|
||||
func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) common.MerkleProof {
|
||||
func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) types.FriMerkleProof {
|
||||
n := len(merkleProofRaw.Siblings)
|
||||
var mp common.MerkleProof
|
||||
mp.Siblings = make([]poseidon.PoseidonBN128HashOut, n)
|
||||
var mp types.FriMerkleProof
|
||||
mp.Siblings = make([]poseidon.BN254HashOut, n)
|
||||
for i := 0; i < n; i++ {
|
||||
element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 })
|
||||
mp.Siblings[i] = utils.Uint64ArrayToFArray(element.Elements)
|
||||
mp.Siblings[i] = gl.Uint64ArrayToVariableArray(element.Elements)
|
||||
}
|
||||
return mp
|
||||
}
|
||||
@@ -176,25 +175,25 @@ func DeserializeOpeningSet(openingSetRaw struct {
|
||||
PlonkZsNext [][]uint64
|
||||
PartialProducts [][]uint64
|
||||
QuotientPolys [][]uint64
|
||||
}) common.OpeningSet {
|
||||
return common.OpeningSet{
|
||||
Constants: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants),
|
||||
PlonkSigmas: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas),
|
||||
Wires: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires),
|
||||
PlonkZs: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs),
|
||||
PlonkZsNext: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext),
|
||||
PartialProducts: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts),
|
||||
QuotientPolys: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys),
|
||||
}) types.OpeningSet {
|
||||
return types.OpeningSet{
|
||||
Constants: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants),
|
||||
PlonkSigmas: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas),
|
||||
Wires: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires),
|
||||
PlonkZs: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs),
|
||||
PlonkZsNext: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext),
|
||||
PartialProducts: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts),
|
||||
QuotientPolys: gl.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys),
|
||||
}
|
||||
}
|
||||
|
||||
func StringArrayToHashBN128Array(rawHashes []string) []poseidon.PoseidonBN128HashOut {
|
||||
hashes := []poseidon.PoseidonBN128HashOut{}
|
||||
func StringArrayToHashBN254Array(rawHashes []string) []poseidon.BN254HashOut {
|
||||
hashes := []poseidon.BN254HashOut{}
|
||||
|
||||
for i := 0; i < len(rawHashes); i++ {
|
||||
hashBigInt, _ := new(big.Int).SetString(rawHashes[i], 10)
|
||||
hashVar := frontend.Variable(hashBigInt)
|
||||
hashes = append(hashes, poseidon.PoseidonBN128HashOut(hashVar))
|
||||
hashes = append(hashes, poseidon.BN254HashOut(hashVar))
|
||||
}
|
||||
|
||||
return hashes
|
||||
@@ -217,39 +216,39 @@ func DeserializeFriProof(openingProofRaw struct {
|
||||
Coeffs [][]uint64
|
||||
}
|
||||
PowWitness uint64
|
||||
}) common.FriProof {
|
||||
var openingProof common.FriProof
|
||||
openingProof.PowWitness = field.NewFieldConst(openingProofRaw.PowWitness)
|
||||
openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
|
||||
}) types.FriProof {
|
||||
var openingProof types.FriProof
|
||||
openingProof.PowWitness = gl.NewVariable(openingProofRaw.PowWitness)
|
||||
openingProof.FinalPoly.Coeffs = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
|
||||
|
||||
openingProof.CommitPhaseMerkleCaps = make([]common.MerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps))
|
||||
openingProof.CommitPhaseMerkleCaps = make([]types.FriMerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps))
|
||||
for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ {
|
||||
openingProof.CommitPhaseMerkleCaps[i] = StringArrayToHashBN128Array(openingProofRaw.CommitPhaseMerkleCaps[i])
|
||||
openingProof.CommitPhaseMerkleCaps[i] = StringArrayToHashBN254Array(openingProofRaw.CommitPhaseMerkleCaps[i])
|
||||
}
|
||||
|
||||
numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs)
|
||||
openingProof.QueryRoundProofs = make([]common.FriQueryRound, numQueryRoundProofs)
|
||||
openingProof.QueryRoundProofs = make([]types.FriQueryRound, numQueryRoundProofs)
|
||||
|
||||
for i := 0; i < numQueryRoundProofs; i++ {
|
||||
numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs)
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]common.EvalProof, numEvalProofs)
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]types.FriEvalProof, numEvalProofs)
|
||||
for j := 0; j < numEvalProofs; j++ {
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = utils.Uint64ArrayToFArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].LeafElements)
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = StringArrayToHashBN128Array(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Hash)
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = gl.Uint64ArrayToVariableArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].LeafElements)
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Hash)
|
||||
}
|
||||
|
||||
numSteps := len(openingProofRaw.QueryRoundProofs[i].Steps)
|
||||
openingProof.QueryRoundProofs[i].Steps = make([]common.FriQueryStep, numSteps)
|
||||
openingProof.QueryRoundProofs[i].Steps = make([]types.FriQueryStep, numSteps)
|
||||
for j := 0; j < numSteps; j++ {
|
||||
openingProof.QueryRoundProofs[i].Steps[j].Evals = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.QueryRoundProofs[i].Steps[j].Evals)
|
||||
openingProof.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings = StringArrayToHashBN128Array(openingProofRaw.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings)
|
||||
openingProof.QueryRoundProofs[i].Steps[j].Evals = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.QueryRoundProofs[i].Steps[j].Evals)
|
||||
openingProof.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings = StringArrayToHashBN254Array(openingProofRaw.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings)
|
||||
}
|
||||
}
|
||||
|
||||
return openingProof
|
||||
}
|
||||
|
||||
func DeserializeProofWithPublicInputs(path string) common.ProofWithPublicInputs {
|
||||
func DeserializeProofWithPublicInputs(path string) types.ProofWithPublicInputs {
|
||||
jsonFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -264,7 +263,7 @@ func DeserializeProofWithPublicInputs(path string) common.ProofWithPublicInputs
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var proofWithPis common.ProofWithPublicInputs
|
||||
var proofWithPis types.ProofWithPublicInputs
|
||||
proofWithPis.Proof.WiresCap = DeserializeMerkleCap(raw.Proof.WiresCap)
|
||||
proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap(raw.Proof.PlonkZsPartialProductsCap)
|
||||
proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap(raw.Proof.QuotientPolysCap)
|
||||
@@ -293,12 +292,12 @@ func DeserializeProofWithPublicInputs(path string) common.ProofWithPublicInputs
|
||||
FinalPoly struct{ Coeffs [][]uint64 }
|
||||
PowWitness uint64
|
||||
}(raw.Proof.OpeningProof))
|
||||
proofWithPis.PublicInputs = utils.Uint64ArrayToFArray(raw.PublicInputs)
|
||||
proofWithPis.PublicInputs = gl.Uint64ArrayToVariableArray(raw.PublicInputs)
|
||||
|
||||
return proofWithPis
|
||||
}
|
||||
|
||||
func DeserializeProofChallenges(path string) common.ProofChallenges {
|
||||
func DeserializeProofChallenges(path string) types.ProofChallenges {
|
||||
jsonFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -313,15 +312,15 @@ func DeserializeProofChallenges(path string) common.ProofChallenges {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var proofChallenges common.ProofChallenges
|
||||
proofChallenges.PlonkBetas = utils.Uint64ArrayToFArray(raw.PlonkBetas)
|
||||
proofChallenges.PlonkGammas = utils.Uint64ArrayToFArray(raw.PlonkGammas)
|
||||
proofChallenges.PlonkAlphas = utils.Uint64ArrayToFArray(raw.PlonkAlphas)
|
||||
proofChallenges.PlonkZeta = utils.Uint64ArrayToQuadraticExtension(raw.PlonkZeta)
|
||||
proofChallenges.FriChallenges.FriAlpha = utils.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha)
|
||||
proofChallenges.FriChallenges.FriBetas = utils.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas)
|
||||
proofChallenges.FriChallenges.FriPowResponse = field.NewFieldConst(raw.FriChallenges.FriPowResponse)
|
||||
proofChallenges.FriChallenges.FriQueryIndices = utils.Uint64ArrayToFArray(raw.FriChallenges.FriQueryIndices)
|
||||
var proofChallenges types.ProofChallenges
|
||||
proofChallenges.PlonkBetas = gl.Uint64ArrayToVariableArray(raw.PlonkBetas)
|
||||
proofChallenges.PlonkGammas = gl.Uint64ArrayToVariableArray(raw.PlonkGammas)
|
||||
proofChallenges.PlonkAlphas = gl.Uint64ArrayToVariableArray(raw.PlonkAlphas)
|
||||
proofChallenges.PlonkZeta = gl.Uint64ArrayToQuadraticExtension(raw.PlonkZeta)
|
||||
proofChallenges.FriChallenges.FriAlpha = gl.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha)
|
||||
proofChallenges.FriChallenges.FriBetas = gl.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas)
|
||||
proofChallenges.FriChallenges.FriPowResponse = gl.NewVariable(raw.FriChallenges.FriPowResponse)
|
||||
proofChallenges.FriChallenges.FriQueryIndices = gl.Uint64ArrayToVariableArray(raw.FriChallenges.FriQueryIndices)
|
||||
|
||||
return proofChallenges
|
||||
}
|
||||
@@ -346,7 +345,7 @@ func ReductionArityBits(
|
||||
return returnArr
|
||||
}
|
||||
|
||||
func DeserializeCommonCircuitData(path string) common.CommonCircuitData {
|
||||
func DeserializeCommonCircuitData(path string) types.CommonCircuitData {
|
||||
jsonFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -361,7 +360,7 @@ func DeserializeCommonCircuitData(path string) common.CommonCircuitData {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var commonCircuitData common.CommonCircuitData
|
||||
var commonCircuitData types.CommonCircuitData
|
||||
commonCircuitData.Config.NumWires = raw.Config.NumWires
|
||||
commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires
|
||||
commonCircuitData.Config.NumConstants = raw.Config.NumConstants
|
||||
@@ -406,13 +405,13 @@ func DeserializeCommonCircuitData(path string) common.CommonCircuitData {
|
||||
commonCircuitData.NumGateConstraints = raw.NumGateConstraints
|
||||
commonCircuitData.NumConstants = raw.NumConstants
|
||||
commonCircuitData.NumPublicInputs = raw.NumPublicInputs
|
||||
commonCircuitData.KIs = utils.Uint64ArrayToFArray(raw.KIs)
|
||||
commonCircuitData.KIs = gl.Uint64ArrayToVariableArray(raw.KIs)
|
||||
commonCircuitData.NumPartialProducts = raw.NumPartialProducts
|
||||
|
||||
return commonCircuitData
|
||||
}
|
||||
|
||||
func DeserializeVerifierOnlyCircuitData(path string) common.VerifierOnlyCircuitData {
|
||||
func DeserializeVerifierOnlyCircuitData(path string) types.VerifierOnlyCircuitData {
|
||||
jsonFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -427,10 +426,10 @@ func DeserializeVerifierOnlyCircuitData(path string) common.VerifierOnlyCircuitD
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var verifierOnlyCircuitData common.VerifierOnlyCircuitData
|
||||
var verifierOnlyCircuitData types.VerifierOnlyCircuitData
|
||||
verifierOnlyCircuitData.ConstantSigmasCap = DeserializeMerkleCap(raw.ConstantsSigmasCap)
|
||||
circuitDigestBigInt, _ := new(big.Int).SetString(raw.CircuitDigest, 10)
|
||||
circuitDigestVar := frontend.Variable(circuitDigestBigInt)
|
||||
verifierOnlyCircuitData.CircuitDigest = poseidon.PoseidonBN128HashOut(circuitDigestVar)
|
||||
verifierOnlyCircuitData.CircuitDigest = poseidon.BN254HashOut(circuitDigestVar)
|
||||
return verifierOnlyCircuitData
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package utils
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,519 +0,0 @@
|
||||
package fri
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"math/bits"
|
||||
|
||||
"github.com/consensys/gnark-crypto/field/goldilocks"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
)
|
||||
|
||||
type FriChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
fieldAPI field.FieldAPI `gnark:"-"`
|
||||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
|
||||
|
||||
poseidonBN128Chip *poseidon.PoseidonBN128Chip
|
||||
|
||||
friParams *common.FriParams `gnark:"-"`
|
||||
}
|
||||
|
||||
func NewFriChip(
|
||||
api frontend.API,
|
||||
fieldAPI field.FieldAPI,
|
||||
qeAPI *field.QuadraticExtensionAPI,
|
||||
poseidonBN128Chip *poseidon.PoseidonBN128Chip,
|
||||
friParams *common.FriParams,
|
||||
) *FriChip {
|
||||
return &FriChip{
|
||||
api: api,
|
||||
fieldAPI: fieldAPI,
|
||||
qeAPI: qeAPI,
|
||||
poseidonBN128Chip: poseidonBN128Chip,
|
||||
friParams: friParams,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FriChip) assertLeadingZeros(powWitness field.F, friConfig common.FriConfig) {
|
||||
// Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros.
|
||||
// Note that this is assuming that the Goldilocks field is being used. Specfically that the
|
||||
// field is 64 bits long
|
||||
maxPowWitness := uint64(math.Pow(2, float64(64-friConfig.ProofOfWorkBits))) - 1
|
||||
reducedPOWWitness := f.fieldAPI.Reduce(powWitness)
|
||||
f.fieldAPI.AssertIsLessOrEqual(reducedPOWWitness, field.NewFieldConst(maxPowWitness))
|
||||
}
|
||||
|
||||
func (f *FriChip) fromOpeningsAndAlpha(openings *FriOpenings, alpha field.QuadraticExtension) []field.QuadraticExtension {
|
||||
// One reduced opening for all openings evaluated at point Zeta.
|
||||
// Another one for all openings evaluated at point Zeta * Omega (which is only PlonkZsNext polynomial)
|
||||
|
||||
reducedOpenings := make([]field.QuadraticExtension, 0, 2)
|
||||
for _, batch := range openings.Batches {
|
||||
reducedOpenings = append(reducedOpenings, f.qeAPI.ReduceWithPowers(batch.Values, alpha))
|
||||
}
|
||||
|
||||
return reducedOpenings
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyMerkleProofToCapWithCapIndex(leafData []field.F, leafIndexBits []frontend.Variable, capIndexBits []frontend.Variable, merkleCap common.MerkleCap, proof *common.MerkleProof) {
|
||||
currentDigest := f.poseidonBN128Chip.HashOrNoop(leafData)
|
||||
for i, sibling := range proof.Siblings {
|
||||
bit := leafIndexBits[i]
|
||||
// TODO: Don't need to do two hashes by using a trick that the plonky2 verifier circuit does
|
||||
// https://github.com/mir-protocol/plonky2/blob/973624f12d2d12d74422b3ea051358b9eaacb050/plonky2/src/gates/poseidon.rs#L298
|
||||
leftHash := f.poseidonBN128Chip.TwoToOne(sibling, currentDigest)
|
||||
rightHash := f.poseidonBN128Chip.TwoToOne(currentDigest, sibling)
|
||||
currentDigest = f.api.Select(bit, leftHash, rightHash)
|
||||
}
|
||||
|
||||
// We assume that the cap_height is 4. Create two levels of the Lookup2 circuit
|
||||
if len(capIndexBits) != 4 || len(merkleCap) != 16 {
|
||||
errorMsg, _ := fmt.Printf(
|
||||
"capIndexBits length should be 4 and the merkleCap length should be 16. Actual values (capIndexBits: %d, merkleCap: %d)\n",
|
||||
len(capIndexBits),
|
||||
len(merkleCap),
|
||||
)
|
||||
panic(errorMsg)
|
||||
}
|
||||
|
||||
const NUM_LEAF_LOOKUPS = 4
|
||||
var leafLookups [NUM_LEAF_LOOKUPS]poseidon.PoseidonBN128HashOut
|
||||
// First create the "leaf" lookup2 circuits
|
||||
// The will use the least significant bits of the capIndexBits array
|
||||
for i := 0; i < NUM_LEAF_LOOKUPS; i++ {
|
||||
leafLookups[i] = f.api.Lookup2(
|
||||
capIndexBits[0], capIndexBits[1],
|
||||
merkleCap[i*NUM_LEAF_LOOKUPS], merkleCap[i*NUM_LEAF_LOOKUPS+1], merkleCap[i*NUM_LEAF_LOOKUPS+2], merkleCap[i*NUM_LEAF_LOOKUPS+3],
|
||||
)
|
||||
}
|
||||
|
||||
// Use the most 2 significant bits of the capIndexBits array for the "root" lookup
|
||||
merkleCapEntry := f.api.Lookup2(capIndexBits[2], capIndexBits[3], leafLookups[0], leafLookups[1], leafLookups[2], leafLookups[3])
|
||||
f.api.AssertIsEqual(currentDigest, merkleCapEntry)
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyInitialProof(xIndexBits []frontend.Variable, proof *common.FriInitialTreeProof, initialMerkleCaps []common.MerkleCap, capIndexBits []frontend.Variable) {
|
||||
if len(proof.EvalsProofs) != len(initialMerkleCaps) {
|
||||
panic("length of eval proofs in fri proof should equal length of initial merkle caps")
|
||||
}
|
||||
|
||||
for i := 0; i < len(initialMerkleCaps); i++ {
|
||||
evals := proof.EvalsProofs[i].Elements
|
||||
merkleProof := proof.EvalsProofs[i].MerkleProof
|
||||
cap := initialMerkleCaps[i]
|
||||
f.verifyMerkleProofToCapWithCapIndex(evals, xIndexBits, capIndexBits, cap, &merkleProof)
|
||||
}
|
||||
}
|
||||
|
||||
// / We decompose FRI query indices into bits without verifying that the decomposition given by
|
||||
// / the prover is the canonical one. In particular, if `x_index < 2^field_bits - p`, then the
|
||||
// / prover could supply the binary encoding of either `x_index` or `x_index + p`, since they are
|
||||
// / congruent mod `p`. However, this only occurs with probability
|
||||
// / p_ambiguous = (2^field_bits - p) / p
|
||||
// / which is small for the field that we use in practice.
|
||||
// /
|
||||
// / In particular, the soundness error of one FRI query is roughly the codeword rate, which
|
||||
// / is much larger than this ambiguous-element probability given any reasonable parameters.
|
||||
// / Thus ambiguous elements contribute a negligible amount to soundness error.
|
||||
// /
|
||||
// / Here we compare the probabilities as a sanity check, to verify the claim above.
|
||||
func (f *FriChip) assertNoncanonicalIndicesOK() {
|
||||
numAmbiguousElems := uint64(math.MaxUint64) - goldilocks.Modulus().Uint64() + 1
|
||||
queryError := f.friParams.Config.Rate()
|
||||
pAmbiguous := float64(numAmbiguousElems) / float64(goldilocks.Modulus().Uint64())
|
||||
|
||||
// TODO: Check that pAmbiguous value is the same as the one in plonky2 verifier
|
||||
if pAmbiguous >= queryError*1e-5 {
|
||||
panic("A non-negligible portion of field elements are in the range that permits non-canonical encodings. Need to do more analysis or enforce canonical encodings.")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FriChip) expFromBitsConstBase(
|
||||
base goldilocks.Element,
|
||||
exponentBits []frontend.Variable,
|
||||
) field.F {
|
||||
product := field.ONE_F
|
||||
for i, bit := range exponentBits {
|
||||
pow := int64(1 << i)
|
||||
// If the bit is on, we multiply product by base^pow.
|
||||
// We can arithmetize this as:
|
||||
// product *= 1 + bit (base^pow - 1)
|
||||
// product = (base^pow - 1) product bit + product
|
||||
basePow := goldilocks.NewElement(0)
|
||||
basePow.Exp(base, big.NewInt(pow))
|
||||
|
||||
basePowElement := field.NewFieldConst(basePow.Uint64() - 1)
|
||||
|
||||
product = f.fieldAPI.Add(
|
||||
f.fieldAPI.Mul(
|
||||
f.fieldAPI.Mul(
|
||||
basePowElement,
|
||||
product),
|
||||
f.fieldAPI.NewElement(bit)),
|
||||
product,
|
||||
)
|
||||
}
|
||||
|
||||
return product
|
||||
}
|
||||
|
||||
func (f *FriChip) calculateSubgroupX(
|
||||
xIndexBits []frontend.Variable,
|
||||
nLog uint64,
|
||||
) field.F {
|
||||
// Compute x from its index
|
||||
// `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
|
||||
// TODO - Make these as global values
|
||||
g := field.NewFieldConst(field.GOLDILOCKS_MULTIPLICATIVE_GROUP_GENERATOR.Uint64())
|
||||
base := field.GoldilocksPrimitiveRootOfUnity(nLog)
|
||||
|
||||
// Create a reverse list of xIndexBits
|
||||
xIndexBitsRev := make([]frontend.Variable, 0)
|
||||
for i := len(xIndexBits) - 1; i >= 0; i-- {
|
||||
xIndexBitsRev = append(xIndexBitsRev, xIndexBits[i])
|
||||
}
|
||||
|
||||
product := f.expFromBitsConstBase(base, xIndexBitsRev)
|
||||
|
||||
return f.fieldAPI.Mul(g, product)
|
||||
}
|
||||
|
||||
func (f *FriChip) friCombineInitial(
|
||||
instance FriInstanceInfo,
|
||||
proof common.FriInitialTreeProof,
|
||||
friAlpha field.QuadraticExtension,
|
||||
subgroupX_QE field.QuadraticExtension,
|
||||
precomputedReducedEval []field.QuadraticExtension,
|
||||
) field.QuadraticExtension {
|
||||
sum := f.qeAPI.ZERO_QE
|
||||
|
||||
if len(instance.Batches) != len(precomputedReducedEval) {
|
||||
panic("len(openings) != len(precomputedReducedEval)")
|
||||
}
|
||||
|
||||
for i := 0; i < len(instance.Batches); i++ {
|
||||
batch := instance.Batches[i]
|
||||
reducedOpenings := precomputedReducedEval[i]
|
||||
|
||||
point := batch.Point
|
||||
evals := make([]field.QuadraticExtension, 0)
|
||||
for _, polynomial := range batch.Polynomials {
|
||||
evals = append(
|
||||
evals,
|
||||
field.QuadraticExtension{proof.EvalsProofs[polynomial.OracleIndex].Elements[polynomial.PolynomialInfo], field.ZERO_F},
|
||||
)
|
||||
}
|
||||
|
||||
reducedEvals := f.qeAPI.ReduceWithPowers(evals, friAlpha)
|
||||
numerator := f.qeAPI.SubExtension(reducedEvals, reducedOpenings)
|
||||
denominator := f.qeAPI.SubExtension(subgroupX_QE, point)
|
||||
sum = f.qeAPI.MulExtension(f.qeAPI.ExpU64Extension(friAlpha, uint64(len(evals))), sum)
|
||||
sum = f.qeAPI.AddExtension(
|
||||
f.qeAPI.DivExtension(
|
||||
numerator,
|
||||
denominator,
|
||||
),
|
||||
sum,
|
||||
)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
func (f *FriChip) finalPolyEval(finalPoly common.PolynomialCoeffs, point field.QuadraticExtension) field.QuadraticExtension {
|
||||
ret := f.qeAPI.ZERO_QE
|
||||
for i := len(finalPoly.Coeffs) - 1; i >= 0; i-- {
|
||||
ret = f.qeAPI.AddExtension(
|
||||
f.qeAPI.MulExtension(
|
||||
ret,
|
||||
point,
|
||||
),
|
||||
finalPoly.Coeffs[i],
|
||||
)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *FriChip) interpolate(x field.QuadraticExtension, xPoints []field.QuadraticExtension, yPoints []field.QuadraticExtension, barycentricWeights []field.QuadraticExtension) field.QuadraticExtension {
|
||||
if len(xPoints) != len(yPoints) || len(xPoints) != len(barycentricWeights) {
|
||||
panic("length of xPoints, yPoints, and barycentricWeights are inconsistent")
|
||||
}
|
||||
|
||||
lX := f.qeAPI.ONE_QE
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
lX = f.qeAPI.MulExtension(
|
||||
lX,
|
||||
f.qeAPI.SubExtension(
|
||||
x,
|
||||
xPoints[i],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sum := f.qeAPI.ZERO_QE
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
sum = f.qeAPI.AddExtension(
|
||||
f.qeAPI.MulExtension(
|
||||
f.qeAPI.DivExtension(
|
||||
barycentricWeights[i],
|
||||
f.qeAPI.SubExtension(
|
||||
x,
|
||||
xPoints[i],
|
||||
),
|
||||
),
|
||||
yPoints[i],
|
||||
),
|
||||
sum,
|
||||
)
|
||||
}
|
||||
|
||||
interpolation := f.qeAPI.MulExtension(lX, sum)
|
||||
|
||||
returnField := interpolation
|
||||
// Now check if x is already within the xPoints
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
returnField = f.qeAPI.Select(
|
||||
f.qeAPI.IsZero(f.qeAPI.SubExtension(x, xPoints[i])),
|
||||
yPoints[i],
|
||||
returnField,
|
||||
)
|
||||
}
|
||||
|
||||
return returnField
|
||||
}
|
||||
|
||||
func (f *FriChip) computeEvaluation(
|
||||
x field.F,
|
||||
xIndexWithinCosetBits []frontend.Variable,
|
||||
arityBits uint64,
|
||||
evals []field.QuadraticExtension,
|
||||
beta field.QuadraticExtension,
|
||||
) field.QuadraticExtension {
|
||||
arity := 1 << arityBits
|
||||
if (len(evals)) != arity {
|
||||
panic("len(evals) ! arity")
|
||||
}
|
||||
if arityBits > 8 {
|
||||
panic("currently assuming that arityBits is <= 8")
|
||||
}
|
||||
|
||||
g := field.GoldilocksPrimitiveRootOfUnity(arityBits)
|
||||
gInv := goldilocks.NewElement(0)
|
||||
gInv.Exp(g, big.NewInt(int64(arity-1)))
|
||||
|
||||
// The evaluation vector needs to be reordered first. Permute the evals array such that each
|
||||
// element's new index is the bit reverse of it's original index.
|
||||
// TODO: Optimization - Since the size of the evals array should be constant (e.g. 2^arityBits),
|
||||
// we can just hard code the permutation.
|
||||
permutedEvals := make([]field.QuadraticExtension, len(evals))
|
||||
for i := uint8(0); i < uint8(len(evals)); i++ {
|
||||
newIndex := bits.Reverse8(i) >> arityBits
|
||||
permutedEvals[newIndex] = evals[i]
|
||||
}
|
||||
|
||||
// Want `g^(arity - rev_x_index_within_coset)` as in the out-of-circuit version. Compute it
|
||||
// as `(g^-1)^rev_x_index_within_coset`.
|
||||
revXIndexWithinCosetBits := make([]frontend.Variable, len(xIndexWithinCosetBits))
|
||||
for i := 0; i < len(xIndexWithinCosetBits); i++ {
|
||||
revXIndexWithinCosetBits[len(xIndexWithinCosetBits)-1-i] = xIndexWithinCosetBits[i]
|
||||
}
|
||||
start := f.expFromBitsConstBase(gInv, revXIndexWithinCosetBits)
|
||||
cosetStart := f.fieldAPI.Mul(start, x)
|
||||
|
||||
xPoints := make([]field.QuadraticExtension, len(evals))
|
||||
yPoints := permutedEvals
|
||||
|
||||
// TODO: Make g_F a constant
|
||||
g_F := f.qeAPI.FieldToQE(field.NewFieldConst(g.Uint64()))
|
||||
xPoints[0] = f.qeAPI.FieldToQE(cosetStart)
|
||||
for i := 1; i < len(evals); i++ {
|
||||
xPoints[i] = f.qeAPI.MulExtension(xPoints[i-1], g_F)
|
||||
}
|
||||
|
||||
// TODO: This is n^2. Is there a way to do this better?
|
||||
// Compute the barycentric weights
|
||||
barycentricWeights := make([]field.QuadraticExtension, len(xPoints))
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
barycentricWeights[i] = f.qeAPI.ONE_QE
|
||||
for j := 0; j < len(xPoints); j++ {
|
||||
if i != j {
|
||||
barycentricWeights[i] = f.qeAPI.MulExtension(
|
||||
f.qeAPI.SubExtension(xPoints[i], xPoints[j]),
|
||||
barycentricWeights[i],
|
||||
)
|
||||
}
|
||||
}
|
||||
// Take the inverse of the barycentric weights
|
||||
// TODO: Can provide a witness to this value
|
||||
barycentricWeights[i] = f.qeAPI.InverseExtension(barycentricWeights[i])
|
||||
}
|
||||
|
||||
return f.interpolate(beta, xPoints, yPoints, barycentricWeights)
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyQueryRound(
|
||||
instance FriInstanceInfo,
|
||||
challenges *common.FriChallenges,
|
||||
precomputedReducedEval []field.QuadraticExtension,
|
||||
initialMerkleCaps []common.MerkleCap,
|
||||
proof *common.FriProof,
|
||||
xIndex field.F,
|
||||
n uint64,
|
||||
nLog uint64,
|
||||
roundProof *common.FriQueryRound,
|
||||
) {
|
||||
f.assertNoncanonicalIndicesOK()
|
||||
xIndex = f.fieldAPI.Reduce(xIndex)
|
||||
xIndexBits := f.fieldAPI.ToBits(xIndex)[0 : f.friParams.DegreeBits+f.friParams.Config.RateBits]
|
||||
capIndexBits := xIndexBits[len(xIndexBits)-int(f.friParams.Config.CapHeight):]
|
||||
|
||||
f.verifyInitialProof(xIndexBits, &roundProof.InitialTreesProof, initialMerkleCaps, capIndexBits)
|
||||
|
||||
subgroupX := f.calculateSubgroupX(
|
||||
xIndexBits,
|
||||
nLog,
|
||||
)
|
||||
|
||||
subgroupX_QE := field.QuadraticExtension{subgroupX, field.ZERO_F}
|
||||
|
||||
oldEval := f.friCombineInitial(
|
||||
instance,
|
||||
roundProof.InitialTreesProof,
|
||||
challenges.FriAlpha,
|
||||
subgroupX_QE,
|
||||
precomputedReducedEval,
|
||||
)
|
||||
|
||||
for i, arityBits := range f.friParams.ReductionArityBits {
|
||||
evals := roundProof.Steps[i].Evals
|
||||
|
||||
cosetIndexBits := xIndexBits[arityBits:]
|
||||
xIndexWithinCosetBits := xIndexBits[:arityBits]
|
||||
|
||||
// Assumes that the arity bits will be 4. That means that the range of
|
||||
// xIndexWithCoset is [0,2^4-1]. This is based on plonky2's circuit recursive
|
||||
// config: https://github.com/mir-protocol/plonky2/blob/main/plonky2/src/plonk/circuit_data.rs#L63
|
||||
// Will use a two levels tree of 4-selector gadgets.
|
||||
if arityBits != 4 {
|
||||
panic("assuming arity bits is 4")
|
||||
}
|
||||
|
||||
const NUM_LEAF_LOOKUPS = 4
|
||||
var leafLookups [NUM_LEAF_LOOKUPS]field.QuadraticExtension
|
||||
// First create the "leaf" lookup2 circuits
|
||||
// The will use the least significant bits of the xIndexWithCosetBits array
|
||||
for i := 0; i < NUM_LEAF_LOOKUPS; i++ {
|
||||
leafLookups[i] = f.qeAPI.Lookup2(
|
||||
xIndexWithinCosetBits[0],
|
||||
xIndexWithinCosetBits[1],
|
||||
evals[i*NUM_LEAF_LOOKUPS],
|
||||
evals[i*NUM_LEAF_LOOKUPS+1],
|
||||
evals[i*NUM_LEAF_LOOKUPS+2],
|
||||
evals[i*NUM_LEAF_LOOKUPS+3],
|
||||
)
|
||||
}
|
||||
|
||||
// Use the most 2 significant bits of the xIndexWithCosetBits array for the "root" lookup
|
||||
newEval := f.qeAPI.Lookup2(
|
||||
xIndexWithinCosetBits[2],
|
||||
xIndexWithinCosetBits[3],
|
||||
leafLookups[0],
|
||||
leafLookups[1],
|
||||
leafLookups[2],
|
||||
leafLookups[3],
|
||||
)
|
||||
|
||||
f.qeAPI.AssertIsEqual(newEval, oldEval)
|
||||
|
||||
oldEval = f.computeEvaluation(
|
||||
subgroupX,
|
||||
xIndexWithinCosetBits,
|
||||
arityBits,
|
||||
evals,
|
||||
challenges.FriBetas[i],
|
||||
)
|
||||
|
||||
// Convert evals (array of QE) to fields by taking their 0th degree coefficients
|
||||
fieldEvals := make([]field.F, 0, 2*len(evals))
|
||||
for j := 0; j < len(evals); j++ {
|
||||
fieldEvals = append(fieldEvals, evals[j][0])
|
||||
fieldEvals = append(fieldEvals, evals[j][1])
|
||||
}
|
||||
f.verifyMerkleProofToCapWithCapIndex(
|
||||
fieldEvals,
|
||||
cosetIndexBits,
|
||||
capIndexBits,
|
||||
proof.CommitPhaseMerkleCaps[i],
|
||||
&roundProof.Steps[i].MerkleProof,
|
||||
)
|
||||
|
||||
// Update the point x to x^arity.
|
||||
for j := uint64(0); j < arityBits; j++ {
|
||||
subgroupX = f.fieldAPI.Mul(subgroupX, subgroupX)
|
||||
}
|
||||
|
||||
xIndexBits = cosetIndexBits
|
||||
}
|
||||
|
||||
subgroupX_QE = f.qeAPI.FieldToQE(subgroupX)
|
||||
finalPolyEval := f.finalPolyEval(proof.FinalPoly, subgroupX_QE)
|
||||
|
||||
f.qeAPI.AssertIsEqual(oldEval, finalPolyEval)
|
||||
}
|
||||
|
||||
func (f *FriChip) VerifyFriProof(
|
||||
instance FriInstanceInfo,
|
||||
openings FriOpenings,
|
||||
friChallenges *common.FriChallenges,
|
||||
initialMerkleCaps []common.MerkleCap,
|
||||
friProof *common.FriProof,
|
||||
) {
|
||||
// TODO: Check fri config
|
||||
/* if let Some(max_arity_bits) = params.max_arity_bits() {
|
||||
self.check_recursion_config::<C>(max_arity_bits);
|
||||
}
|
||||
|
||||
debug_assert_eq!(
|
||||
params.final_poly_len(),
|
||||
proof.final_poly.len(),
|
||||
"Final polynomial has wrong degree."
|
||||
); */
|
||||
|
||||
// Check POW
|
||||
f.assertLeadingZeros(friChallenges.FriPowResponse, f.friParams.Config)
|
||||
|
||||
precomputedReducedEvals := f.fromOpeningsAndAlpha(&openings, friChallenges.FriAlpha)
|
||||
|
||||
// Size of the LDE domain.
|
||||
nLog := f.friParams.DegreeBits + f.friParams.Config.RateBits
|
||||
n := uint64(math.Pow(2, float64(nLog)))
|
||||
|
||||
if len(friChallenges.FriQueryIndices) != len(friProof.QueryRoundProofs) {
|
||||
panic(fmt.Sprintf(
|
||||
"Number of query indices (%d) should equal number of query round proofs (%d)",
|
||||
len(friChallenges.FriQueryIndices),
|
||||
len(friProof.QueryRoundProofs),
|
||||
))
|
||||
}
|
||||
|
||||
for idx, xIndex := range friChallenges.FriQueryIndices {
|
||||
roundProof := friProof.QueryRoundProofs[idx]
|
||||
|
||||
f.verifyQueryRound(
|
||||
instance,
|
||||
friChallenges,
|
||||
precomputedReducedEvals,
|
||||
initialMerkleCaps,
|
||||
friProof,
|
||||
xIndex,
|
||||
n,
|
||||
nLog,
|
||||
&roundProof,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package fri_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestFriCircuit struct {
|
||||
proofWithPIsFilename string `gnark:"-"`
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
verifierOnlyCircuitDataFilename string `gnark:"-"`
|
||||
}
|
||||
|
||||
func (circuit *TestFriCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename)
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename)
|
||||
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename)
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI)
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
|
||||
poseidonBN128Chip := poseidon.NewPoseidonBN128Chip(api, fieldAPI)
|
||||
friChip := fri.NewFriChip(api, fieldAPI, qeAPI, poseidonBN128Chip, &commonCircuitData.FriParams)
|
||||
challengerChip := plonk.NewChallengerChip(api, fieldAPI, poseidonChip, poseidonBN128Chip)
|
||||
|
||||
challengerChip.ObserveBN128Hash(verifierOnlyCircuitData.CircuitDigest)
|
||||
challengerChip.ObserveHash(poseidonChip.HashNoPad(proofWithPis.PublicInputs))
|
||||
challengerChip.ObserveCap(proofWithPis.Proof.WiresCap)
|
||||
plonkBetas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk betas
|
||||
fieldAPI.AssertIsEqual(plonkBetas[0], field.NewFieldConst(17615363392879944733))
|
||||
plonkGammas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk gammas
|
||||
fieldAPI.AssertIsEqual(plonkGammas[0], field.NewFieldConst(15174493176564484303))
|
||||
|
||||
challengerChip.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap)
|
||||
plonkAlphas := challengerChip.GetNChallenges(commonCircuitData.Config.NumChallenges) // For plonk alphas
|
||||
fieldAPI.AssertIsEqual(plonkAlphas[0], field.NewFieldConst(9276470834414745550))
|
||||
|
||||
challengerChip.ObserveCap(proofWithPis.Proof.QuotientPolysCap)
|
||||
plonkZeta := challengerChip.GetExtensionChallenge()
|
||||
fieldAPI.AssertIsEqual(plonkZeta[0], field.NewFieldConst(3892795992421241388))
|
||||
|
||||
challengerChip.ObserveOpenings(fri.ToFriOpenings(proofWithPis.Proof.Openings))
|
||||
|
||||
friChallenges := challengerChip.GetFriChallenges(
|
||||
proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||
proofWithPis.Proof.OpeningProof.PowWitness,
|
||||
commonCircuitData.DegreeBits,
|
||||
commonCircuitData.Config.FriConfig,
|
||||
)
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriAlpha[0], field.NewFieldConst(885535811531859621))
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriBetas[0][0], field.NewFieldConst(5231781384587895507))
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriPowResponse, field.NewFieldConst(70715523064019))
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriQueryIndices[0], field.NewFieldConst(11890500485816111017))
|
||||
|
||||
initialMerkleCaps := []common.MerkleCap{
|
||||
verifierOnlyCircuitData.ConstantSigmasCap,
|
||||
proofWithPis.Proof.WiresCap,
|
||||
proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
proofWithPis.Proof.QuotientPolysCap,
|
||||
}
|
||||
|
||||
// Seems like there is a bug in the emulated field code.
|
||||
// Add ZERO to all of the fri challenges values to reduce them.
|
||||
plonkZeta[0] = fieldAPI.Add(plonkZeta[0], field.ZERO_F)
|
||||
plonkZeta[1] = fieldAPI.Add(plonkZeta[1], field.ZERO_F)
|
||||
|
||||
friChallenges.FriAlpha[0] = fieldAPI.Add(friChallenges.FriAlpha[0], field.ZERO_F)
|
||||
friChallenges.FriAlpha[1] = fieldAPI.Add(friChallenges.FriAlpha[1], field.ZERO_F)
|
||||
|
||||
for i := 0; i < len(friChallenges.FriBetas); i++ {
|
||||
friChallenges.FriBetas[i][0] = fieldAPI.Add(friChallenges.FriBetas[i][0], field.ZERO_F)
|
||||
friChallenges.FriBetas[i][1] = fieldAPI.Add(friChallenges.FriBetas[i][1], field.ZERO_F)
|
||||
}
|
||||
|
||||
friChallenges.FriPowResponse = fieldAPI.Add(friChallenges.FriPowResponse, field.ZERO_F)
|
||||
|
||||
for i := 0; i < len(friChallenges.FriQueryIndices); i++ {
|
||||
friChallenges.FriQueryIndices[i] = fieldAPI.Add(friChallenges.FriQueryIndices[i], field.ZERO_F)
|
||||
}
|
||||
|
||||
friChip.VerifyFriProof(
|
||||
fri.GetFriInstance(&commonCircuitData, qeAPI, plonkZeta, commonCircuitData.DegreeBits),
|
||||
fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
&friChallenges,
|
||||
initialMerkleCaps,
|
||||
&proofWithPis.Proof.OpeningProof,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDecodeBlockFriVerification(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestFriCircuit{
|
||||
proofWithPIsFilename: "../../data/decode_block/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "../../data/decode_block//common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "../../data/decode_block//verifier_only_circuit_data.json",
|
||||
}
|
||||
witness := TestFriCircuit{
|
||||
proofWithPIsFilename: "../../data/dummy_2^14_gates/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "../../data/dummy_2^14_gates/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: ".../../data/dummy_2^14_gates/verifier_only_circuit_data.json",
|
||||
}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
package fri
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
)
|
||||
|
||||
type FriOpeningBatch struct {
|
||||
Values []field.QuadraticExtension
|
||||
}
|
||||
|
||||
type FriOpenings struct {
|
||||
Batches []FriOpeningBatch
|
||||
}
|
||||
|
||||
func ToFriOpenings(c common.OpeningSet) FriOpenings {
|
||||
values := c.Constants // num_constants + 1
|
||||
values = append(values, c.PlonkSigmas...) // num_routed_wires
|
||||
values = append(values, c.Wires...) // num_wires
|
||||
values = append(values, c.PlonkZs...) // num_challenges
|
||||
values = append(values, c.PartialProducts...) // num_challenges * num_partial_products
|
||||
values = append(values, c.QuotientPolys...) // num_challenges * quotient_degree_factor
|
||||
zetaBatch := FriOpeningBatch{Values: values}
|
||||
zetaNextBatch := FriOpeningBatch{Values: c.PlonkZsNext}
|
||||
return FriOpenings{Batches: []FriOpeningBatch{zetaBatch, zetaNextBatch}}
|
||||
}
|
||||
|
||||
type FriPolynomialInfo struct {
|
||||
OracleIndex uint64
|
||||
PolynomialInfo uint64
|
||||
}
|
||||
|
||||
type FriOracleInfo struct {
|
||||
NumPolys uint64
|
||||
Blinding bool
|
||||
}
|
||||
|
||||
type FriBatchInfo struct {
|
||||
Point field.QuadraticExtension
|
||||
Polynomials []FriPolynomialInfo
|
||||
}
|
||||
|
||||
type FriInstanceInfo struct {
|
||||
Oracles []FriOracleInfo
|
||||
Batches []FriBatchInfo
|
||||
}
|
||||
|
||||
type PlonkOracle struct {
|
||||
index uint64
|
||||
blinding bool
|
||||
}
|
||||
|
||||
var CONSTANTS_SIGMAS = PlonkOracle{
|
||||
index: 0,
|
||||
blinding: false,
|
||||
}
|
||||
|
||||
var WIRES = PlonkOracle{
|
||||
index: 1,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
var ZS_PARTIAL_PRODUCTS = PlonkOracle{
|
||||
index: 2,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
var QUOTIENT = PlonkOracle{
|
||||
index: 3,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
func polynomialInfoFromRange(c *common.CommonCircuitData, oracleIdx uint64, startPolyIdx uint64, endPolyIdx uint64) []FriPolynomialInfo {
|
||||
returnArr := make([]FriPolynomialInfo, 0)
|
||||
for i := startPolyIdx; i < endPolyIdx; i++ {
|
||||
returnArr = append(returnArr,
|
||||
FriPolynomialInfo{
|
||||
OracleIndex: oracleIdx,
|
||||
PolynomialInfo: i,
|
||||
})
|
||||
}
|
||||
|
||||
return returnArr
|
||||
}
|
||||
|
||||
// Range of the sigma polynomials in the `constants_sigmas_commitment`.
|
||||
func sigmasRange(c *common.CommonCircuitData) []uint64 {
|
||||
returnArr := make([]uint64, 0)
|
||||
for i := c.NumConstants; i <= c.NumConstants+c.Config.NumRoutedWires; i++ {
|
||||
returnArr = append(returnArr, i)
|
||||
}
|
||||
|
||||
return returnArr
|
||||
}
|
||||
|
||||
func numPreprocessedPolys(c *common.CommonCircuitData) uint64 {
|
||||
sigmasRange := sigmasRange(c)
|
||||
return sigmasRange[len(sigmasRange)-1]
|
||||
}
|
||||
|
||||
func numZSPartialProductsPolys(c *common.CommonCircuitData) uint64 {
|
||||
return c.Config.NumChallenges * (1 + c.NumPartialProducts)
|
||||
}
|
||||
|
||||
func numQuotientPolys(c *common.CommonCircuitData) uint64 {
|
||||
return c.Config.NumChallenges * c.QuotientDegreeFactor
|
||||
}
|
||||
|
||||
func friPreprocessedPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
CONSTANTS_SIGMAS.index,
|
||||
0,
|
||||
numPreprocessedPolys(c),
|
||||
)
|
||||
}
|
||||
|
||||
func friWirePolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
numWirePolys := c.Config.NumWires
|
||||
return polynomialInfoFromRange(c, WIRES.index, 0, numWirePolys)
|
||||
}
|
||||
|
||||
func friZSPartialProductsPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
ZS_PARTIAL_PRODUCTS.index,
|
||||
0,
|
||||
numZSPartialProductsPolys(c),
|
||||
)
|
||||
}
|
||||
|
||||
func friQuotientPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
QUOTIENT.index,
|
||||
0,
|
||||
numQuotientPolys(c),
|
||||
)
|
||||
}
|
||||
|
||||
func friZSPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
ZS_PARTIAL_PRODUCTS.index,
|
||||
0,
|
||||
c.Config.NumChallenges,
|
||||
)
|
||||
}
|
||||
|
||||
func friOracles(c *common.CommonCircuitData) []FriOracleInfo {
|
||||
return []FriOracleInfo{
|
||||
{
|
||||
NumPolys: numPreprocessedPolys(c),
|
||||
Blinding: CONSTANTS_SIGMAS.blinding,
|
||||
},
|
||||
{
|
||||
NumPolys: c.Config.NumWires,
|
||||
Blinding: WIRES.blinding,
|
||||
},
|
||||
{
|
||||
NumPolys: numZSPartialProductsPolys(c),
|
||||
Blinding: ZS_PARTIAL_PRODUCTS.blinding,
|
||||
},
|
||||
{
|
||||
NumPolys: numQuotientPolys(c),
|
||||
Blinding: QUOTIENT.blinding,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func friAllPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
returnArr := make([]FriPolynomialInfo, 0)
|
||||
returnArr = append(returnArr, friPreprocessedPolys(c)...)
|
||||
returnArr = append(returnArr, friWirePolys(c)...)
|
||||
returnArr = append(returnArr, friZSPartialProductsPolys(c)...)
|
||||
returnArr = append(returnArr, friQuotientPolys(c)...)
|
||||
|
||||
return returnArr
|
||||
}
|
||||
|
||||
func GetFriInstance(c *common.CommonCircuitData, qeAPI *field.QuadraticExtensionAPI, zeta field.QuadraticExtension, degreeBits uint64) FriInstanceInfo {
|
||||
zetaBatch := FriBatchInfo{
|
||||
Point: zeta,
|
||||
Polynomials: friAllPolys(c),
|
||||
}
|
||||
|
||||
g := field.GoldilocksPrimitiveRootOfUnity(degreeBits)
|
||||
zetaNext := qeAPI.MulExtension(qeAPI.FieldToQE(field.NewFieldConst(g.Uint64())), zeta)
|
||||
|
||||
zetaNextBath := FriBatchInfo{
|
||||
Point: zetaNext,
|
||||
Polynomials: friZSPolys(c),
|
||||
}
|
||||
|
||||
return FriInstanceInfo{
|
||||
Oracles: friOracles(c),
|
||||
Batches: []FriBatchInfo{zetaBatch, zetaNextBath},
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var aritheticExtensionGateRegex = regexp.MustCompile("ArithmeticExtensionGate { num_ops: (?P<numOps>[0-9]+) }")
|
||||
|
||||
func deserializeExtensionArithmeticGate(parameters map[string]string) Gate {
|
||||
// Has the format "ArithmeticExtensionGate { num_ops: 10 }"
|
||||
numOps, hasNumOps := parameters["numOps"]
|
||||
if !hasNumOps {
|
||||
panic("Missing field num_ops in ArithmeticExtensionGate")
|
||||
}
|
||||
|
||||
numOpsInt, err := strconv.Atoi(numOps)
|
||||
if err != nil {
|
||||
panic("Invalid num_ops field in ArithmeticExtensionGate")
|
||||
}
|
||||
|
||||
return NewArithmeticExtensionGate(uint64(numOpsInt))
|
||||
}
|
||||
|
||||
type ArithmeticExtensionGate struct {
|
||||
numOps uint64
|
||||
}
|
||||
|
||||
func NewArithmeticExtensionGate(numOps uint64) *ArithmeticExtensionGate {
|
||||
return &ArithmeticExtensionGate{
|
||||
numOps: numOps,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) Id() string {
|
||||
return fmt.Sprintf("ArithmeticExtensionGate { num_ops: %d }", g.numOps)
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthMultiplicand0(i uint64) Range {
|
||||
return Range{4 * field.D * i, 4*field.D*i + field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthMultiplicand1(i uint64) Range {
|
||||
return Range{4*field.D*i + field.D, 4*field.D*i + 2*field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthAddend(i uint64) Range {
|
||||
return Range{4*field.D*i + 2*field.D, 4*field.D*i + 3*field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthOutput(i uint64) Range {
|
||||
return Range{4*field.D*i + 3*field.D, 4*field.D*i + 4*field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
const0 := vars.localConstants[0]
|
||||
const1 := vars.localConstants[1]
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.numOps; i++ {
|
||||
multiplicand0 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand0(i))
|
||||
multiplicand1 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand1(i))
|
||||
addend := vars.GetLocalExtAlgebra(g.wiresIthAddend(i))
|
||||
output := vars.GetLocalExtAlgebra(g.wiresIthOutput(i))
|
||||
|
||||
mul := qeAPI.MulExtensionAlgebra(multiplicand0, multiplicand1)
|
||||
scaled_mul := qeAPI.ScalarMulExtensionAlgebra(const0, mul)
|
||||
computed_output := qeAPI.ScalarMulExtensionAlgebra(const1, addend)
|
||||
computed_output = qeAPI.AddExtensionAlgebra(computed_output, scaled_mul)
|
||||
|
||||
diff := qeAPI.SubExtensionAlgebra(output, computed_output)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, diff[j])
|
||||
}
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var aritheticGateRegex = regexp.MustCompile("ArithmeticGate { num_ops: (?P<numOps>[0-9]+) }")
|
||||
|
||||
func deserializeArithmeticGate(parameters map[string]string) Gate {
|
||||
// Has the format "ArithmeticGate { num_ops: 10 }"
|
||||
|
||||
numOps, hasNumOps := parameters["numOps"]
|
||||
if !hasNumOps {
|
||||
panic("no num_ops field in ArithmeticGate")
|
||||
}
|
||||
|
||||
numOpsInt, err := strconv.Atoi(numOps)
|
||||
if err != nil {
|
||||
panic("Invalid num_ops field in ArithmeticGate")
|
||||
}
|
||||
|
||||
return NewArithmeticGate(uint64(numOpsInt))
|
||||
}
|
||||
|
||||
type ArithmeticGate struct {
|
||||
numOps uint64
|
||||
}
|
||||
|
||||
func NewArithmeticGate(numOps uint64) *ArithmeticGate {
|
||||
return &ArithmeticGate{
|
||||
numOps: numOps,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) Id() string {
|
||||
return fmt.Sprintf("ArithmeticGate { num_ops: %d }", g.numOps)
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthMultiplicand0(i uint64) uint64 {
|
||||
return 4 * i
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthMultiplicand1(i uint64) uint64 {
|
||||
return 4*i + 1
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthAddend(i uint64) uint64 {
|
||||
return 4*i + 2
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthOutput(i uint64) uint64 {
|
||||
return 4*i + 3
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
const0 := vars.localConstants[0]
|
||||
const1 := vars.localConstants[1]
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.numOps; i++ {
|
||||
multiplicand0 := vars.localWires[g.WireIthMultiplicand0(i)]
|
||||
multiplicand1 := vars.localWires[g.WireIthMultiplicand1(i)]
|
||||
addend := vars.localWires[g.WireIthAddend(i)]
|
||||
output := vars.localWires[g.WireIthOutput(i)]
|
||||
|
||||
computedOutput := qeAPI.AddExtension(
|
||||
qeAPI.MulExtension(qeAPI.MulExtension(multiplicand0, multiplicand1), const0),
|
||||
qeAPI.MulExtension(addend, const1),
|
||||
)
|
||||
|
||||
constraints = append(constraints, qeAPI.SubExtension(output, computedOutput))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var baseSumGateRegex = regexp.MustCompile(`BaseSumGate { num_limbs: (?P<numLimbs>[0-9]+) } \+ Base: (?P<base>[0-9]+)`)
|
||||
|
||||
func deserializeBaseSumGate(parameters map[string]string) Gate {
|
||||
|
||||
// Has the format "BaseSumGate { num_limbs: 32 } + Base: 2"
|
||||
numLimbs, hasNumLimbs := parameters["numLimbs"]
|
||||
base, hasBase := parameters["base"]
|
||||
if !hasNumLimbs || !hasBase {
|
||||
panic("Missing field num_limbs or base in BaseSumGate")
|
||||
}
|
||||
|
||||
numLimbsInt, err := strconv.Atoi(numLimbs)
|
||||
if err != nil {
|
||||
panic("Invalid num_limbs field in BaseSumGate")
|
||||
}
|
||||
|
||||
baseInt, err := strconv.Atoi(base)
|
||||
if err != nil {
|
||||
panic("Invalid base field in BaseSumGate")
|
||||
}
|
||||
|
||||
return NewBaseSumGate(uint64(numLimbsInt), uint64(baseInt))
|
||||
}
|
||||
|
||||
const (
|
||||
BASESUM_GATE_WIRE_SUM = 0
|
||||
BASESUM_GATE_START_LIMBS = 1
|
||||
)
|
||||
|
||||
type BaseSumGate struct {
|
||||
numLimbs uint64
|
||||
base uint64
|
||||
}
|
||||
|
||||
func NewBaseSumGate(numLimbs uint64, base uint64) *BaseSumGate {
|
||||
return &BaseSumGate{
|
||||
numLimbs: numLimbs,
|
||||
base: base,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *BaseSumGate) Id() string {
|
||||
return fmt.Sprintf("BaseSumGate { num_ops: %d } + Base: %d", g.numLimbs, g.base)
|
||||
}
|
||||
|
||||
func (g *BaseSumGate) limbs() []uint64 {
|
||||
limbIndices := make([]uint64, g.numLimbs)
|
||||
for i := uint64(0); i < g.numLimbs; i++ {
|
||||
limbIndices[i] = uint64(BASESUM_GATE_START_LIMBS + i)
|
||||
}
|
||||
|
||||
return limbIndices
|
||||
}
|
||||
|
||||
func (g *BaseSumGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
sum := vars.localWires[BASESUM_GATE_WIRE_SUM]
|
||||
limbs := make([]field.QuadraticExtension, g.numLimbs)
|
||||
limbIndices := g.limbs()
|
||||
for i, limbIdx := range limbIndices {
|
||||
limbs[i] = vars.localWires[limbIdx]
|
||||
}
|
||||
|
||||
base_qe := qeAPI.FieldToQE(field.NewFieldConst(g.base))
|
||||
computedSum := qeAPI.ReduceWithPowers(
|
||||
limbs,
|
||||
base_qe,
|
||||
)
|
||||
|
||||
var constraints []field.QuadraticExtension
|
||||
constraints = append(constraints, qeAPI.SubExtension(computedSum, sum))
|
||||
for _, limb := range limbs {
|
||||
acc := qeAPI.ONE_QE
|
||||
for i := uint64(0); i < g.base; i++ {
|
||||
difference := qeAPI.SubExtension(limb, qeAPI.FieldToQE(field.NewFieldConst(i)))
|
||||
acc = qeAPI.MulExtension(acc, difference)
|
||||
}
|
||||
constraints = append(constraints, acc)
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var constantGateRegex = regexp.MustCompile("ConstantGate { num_consts: (?P<numConsts>[0-9]+) }")
|
||||
|
||||
func deserializeConstantGate(parameters map[string]string) Gate {
|
||||
// Has the format "ConstantGate { num_consts: 2 }"
|
||||
numConsts, hasNumConsts := parameters["numConsts"]
|
||||
if !hasNumConsts {
|
||||
panic("Missing field num_consts in ConstantGate")
|
||||
}
|
||||
|
||||
numConstsInt, err := strconv.Atoi(numConsts)
|
||||
if err != nil {
|
||||
panic("Invalid num_consts field in ConstantGate")
|
||||
}
|
||||
|
||||
return NewConstantGate(uint64(numConstsInt))
|
||||
}
|
||||
|
||||
type ConstantGate struct {
|
||||
numConsts uint64
|
||||
}
|
||||
|
||||
func NewConstantGate(numConsts uint64) *ConstantGate {
|
||||
return &ConstantGate{
|
||||
numConsts: numConsts,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ConstantGate) Id() string {
|
||||
return fmt.Sprintf("ConstantGate { num_consts: %d }", g.numConsts)
|
||||
}
|
||||
|
||||
func (g *ConstantGate) ConstInput(i uint64) uint64 {
|
||||
if i > g.numConsts {
|
||||
panic("Invalid constant index")
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func (g *ConstantGate) WireOutput(i uint64) uint64 {
|
||||
if i > g.numConsts {
|
||||
panic("Invalid wire index")
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func (g *ConstantGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
for i := uint64(0); i < g.numConsts; i++ {
|
||||
constraints = append(constraints, qeAPI.SubExtension(vars.localConstants[g.ConstInput(i)], vars.localWires[g.WireOutput(i)]))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/consensys/gnark-crypto/field/goldilocks"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var cosetInterpolationGateRegex = regexp.MustCompile(`CosetInterpolationGate { subgroup_bits: (?P<subgroupBits>[0-9]+), degree: (?P<degree>[0-9]+), barycentric_weights: \[(?P<barycentricWeights>[0-9, ]+)\], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>`)
|
||||
|
||||
func deserializeCosetInterpolationGate(parameters map[string]string) Gate {
|
||||
// Has the format CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
||||
subgroupBits, hasSubgroupBits := parameters["subgroupBits"]
|
||||
degree, hasDegree := parameters["degree"]
|
||||
barycentricWeights, hasBarycentricWeights := parameters["barycentricWeights"]
|
||||
|
||||
if !hasSubgroupBits || !hasDegree || !hasBarycentricWeights {
|
||||
panic("missing subgroupBits, degree or barycentricWeights in CosetInterpolationGate")
|
||||
}
|
||||
|
||||
subgroupBitsInt, err := strconv.ParseUint(subgroupBits, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid subgroupBits in CosetInterpolationGate")
|
||||
}
|
||||
|
||||
degreeInt, err := strconv.ParseUint(degree, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid degree in CosetInterpolationGate")
|
||||
}
|
||||
|
||||
barycentricWeightsStr := strings.Split(barycentricWeights, ",")
|
||||
barycentricWeightsInt := make([]goldilocks.Element, len(barycentricWeightsStr))
|
||||
for i, barycentricWeightStr := range barycentricWeightsStr {
|
||||
barycentricWeightStr = strings.TrimSpace(barycentricWeightStr)
|
||||
barycentricWeightInt, err := strconv.ParseUint(barycentricWeightStr, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid barycentricWeights in CosetInterpolationGate")
|
||||
}
|
||||
barycentricWeightsInt[i].SetUint64(barycentricWeightInt)
|
||||
}
|
||||
|
||||
return NewCosetInterpolationGate(subgroupBitsInt, degreeInt, barycentricWeightsInt)
|
||||
}
|
||||
|
||||
type CosetInterpolationGate struct {
|
||||
subgroupBits uint64
|
||||
degree uint64
|
||||
barycentricWeights []goldilocks.Element
|
||||
}
|
||||
|
||||
func NewCosetInterpolationGate(subgroupBits uint64, degree uint64, barycentricWeights []goldilocks.Element) *CosetInterpolationGate {
|
||||
return &CosetInterpolationGate{
|
||||
subgroupBits: subgroupBits,
|
||||
degree: degree,
|
||||
barycentricWeights: barycentricWeights,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) Id() string {
|
||||
|
||||
return fmt.Sprintf(
|
||||
"CosetInterpolationGate { subgroup_bits: %d, degree: %d, barycentric_weights: %s }",
|
||||
g.subgroupBits,
|
||||
g.degree,
|
||||
fmt.Sprint(g.barycentricWeights),
|
||||
)
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) numPoints() uint64 {
|
||||
return 1 << g.subgroupBits
|
||||
}
|
||||
|
||||
// Wire index of the coset shift.
|
||||
func (g *CosetInterpolationGate) wireShift() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startValues() uint64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Wire indices of the `i`th interpolant value.
|
||||
func (g *CosetInterpolationGate) wiresValue(i uint64) Range {
|
||||
if i >= g.numPoints() {
|
||||
panic("Invalid point index")
|
||||
}
|
||||
start := g.startValues() + i*field.D
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startEvaluationPoint() uint64 {
|
||||
return g.startValues() + g.numPoints()*field.D
|
||||
}
|
||||
|
||||
// Wire indices of the point to evaluate the interpolant at.
|
||||
func (g *CosetInterpolationGate) wiresEvaluationPoint() Range {
|
||||
start := g.startEvaluationPoint()
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startEvaluationValue() uint64 {
|
||||
return g.startEvaluationPoint() + field.D
|
||||
}
|
||||
|
||||
// Wire indices of the interpolated value.
|
||||
func (g *CosetInterpolationGate) wiresEvaluationValue() Range {
|
||||
start := g.startEvaluationValue()
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startIntermediates() uint64 {
|
||||
return g.startEvaluationValue() + field.D
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) numIntermediates() uint64 {
|
||||
return (g.numPoints() - 2) / (g.degree - 1)
|
||||
}
|
||||
|
||||
// The wires corresponding to the i'th intermediate evaluation.
|
||||
func (g *CosetInterpolationGate) wiresIntermediateEval(i uint64) Range {
|
||||
if i >= g.numIntermediates() {
|
||||
panic("Invalid intermediate index")
|
||||
}
|
||||
start := g.startIntermediates() + field.D*i
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
// The wires corresponding to the i'th intermediate product.
|
||||
func (g *CosetInterpolationGate) wiresIntermediateProd(i uint64) Range {
|
||||
if i >= g.numIntermediates() {
|
||||
panic("Invalid intermediate index")
|
||||
}
|
||||
start := g.startIntermediates() + field.D*(g.numIntermediates()+i)
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
// Wire indices of the shifted point to evaluate the interpolant at.
|
||||
func (g *CosetInterpolationGate) wiresShiftedEvaluationPoint() Range {
|
||||
start := g.startIntermediates() + field.D*2*g.numIntermediates()
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
shift := vars.localWires[g.wireShift()]
|
||||
evaluationPoint := vars.GetLocalExtAlgebra(g.wiresEvaluationPoint())
|
||||
shiftedEvaluationPoint := vars.GetLocalExtAlgebra(g.wiresShiftedEvaluationPoint())
|
||||
|
||||
negShift := qeAPI.ScalarMulExtension(shift, field.NEG_ONE_F)
|
||||
|
||||
tmp := qeAPI.ScalarMulExtensionAlgebra(negShift, shiftedEvaluationPoint)
|
||||
tmp = qeAPI.AddExtensionAlgebra(tmp, evaluationPoint)
|
||||
|
||||
for i := 0; i < field.D; i++ {
|
||||
constraints = append(constraints, tmp[i])
|
||||
}
|
||||
|
||||
domain := field.TwoAdicSubgroup(g.subgroupBits)
|
||||
values := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numPoints(); i++ {
|
||||
values = append(values, vars.GetLocalExtAlgebra(g.wiresValue(i)))
|
||||
}
|
||||
weights := g.barycentricWeights
|
||||
|
||||
initialEval := qeAPI.ZERO_QE_ALGEBRA
|
||||
initialProd := field.QEAlgebra{qeAPI.ONE_QE, qeAPI.ZERO_QE}
|
||||
computedEval, computedProd := qeAPI.PartialInterpolateExtAlgebra(
|
||||
domain[:g.degree],
|
||||
values[:g.degree],
|
||||
weights[:g.degree],
|
||||
shiftedEvaluationPoint,
|
||||
initialEval,
|
||||
initialProd,
|
||||
)
|
||||
|
||||
for i := uint64(0); i < g.numIntermediates(); i++ {
|
||||
intermediateEval := vars.GetLocalExtAlgebra(g.wiresIntermediateEval(i))
|
||||
intermediateProd := vars.GetLocalExtAlgebra(g.wiresIntermediateProd(i))
|
||||
|
||||
evalDiff := qeAPI.SubExtensionAlgebra(intermediateEval, computedEval)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, evalDiff[j])
|
||||
}
|
||||
|
||||
prodDiff := qeAPI.SubExtensionAlgebra(intermediateProd, computedProd)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, prodDiff[j])
|
||||
}
|
||||
|
||||
startIndex := 1 + (g.degree-1)*(i+1)
|
||||
endIndex := startIndex + g.degree - 1
|
||||
computedEval, computedProd = qeAPI.PartialInterpolateExtAlgebra(
|
||||
domain[startIndex:endIndex],
|
||||
values[startIndex:endIndex],
|
||||
weights[startIndex:endIndex],
|
||||
shiftedEvaluationPoint,
|
||||
intermediateEval,
|
||||
intermediateProd,
|
||||
)
|
||||
}
|
||||
|
||||
evaluationValue := vars.GetLocalExtAlgebra(g.wiresEvaluationValue())
|
||||
evalDiff := qeAPI.SubExtensionAlgebra(evaluationValue, computedEval)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, evalDiff[j])
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
type EvaluateGatesChip struct {
|
||||
api frontend.API
|
||||
qeAPI *field.QuadraticExtensionAPI
|
||||
|
||||
gates []Gate
|
||||
numGateConstraints uint64
|
||||
|
||||
selectorsInfo SelectorsInfo
|
||||
}
|
||||
|
||||
func NewEvaluateGatesChip(
|
||||
api frontend.API,
|
||||
qeAPI *field.QuadraticExtensionAPI,
|
||||
gates []Gate,
|
||||
numGateConstraints uint64,
|
||||
selectorsInfo SelectorsInfo,
|
||||
) *EvaluateGatesChip {
|
||||
return &EvaluateGatesChip{
|
||||
api: api,
|
||||
qeAPI: qeAPI,
|
||||
|
||||
gates: gates,
|
||||
numGateConstraints: numGateConstraints,
|
||||
|
||||
selectorsInfo: selectorsInfo,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *EvaluateGatesChip) computeFilter(
|
||||
row uint64,
|
||||
groupRange Range,
|
||||
s field.QuadraticExtension,
|
||||
manySelector bool,
|
||||
) field.QuadraticExtension {
|
||||
product := g.qeAPI.ONE_QE
|
||||
for i := groupRange.start; i < groupRange.end; i++ {
|
||||
if i == uint64(row) {
|
||||
continue
|
||||
}
|
||||
|
||||
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldConst(i)), s))
|
||||
}
|
||||
|
||||
if manySelector {
|
||||
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldConst(UNUSED_SELECTOR)), s))
|
||||
}
|
||||
|
||||
return product
|
||||
}
|
||||
|
||||
func (g *EvaluateGatesChip) evalFiltered(
|
||||
gate Gate,
|
||||
vars EvaluationVars,
|
||||
row uint64,
|
||||
selectorIndex uint64,
|
||||
groupRange Range,
|
||||
numSelectors uint64,
|
||||
) []field.QuadraticExtension {
|
||||
filter := g.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1)
|
||||
|
||||
vars.RemovePrefix(numSelectors)
|
||||
|
||||
unfiltered := gate.EvalUnfiltered(g.api, g.qeAPI, vars)
|
||||
for i := range unfiltered {
|
||||
unfiltered[i] = g.qeAPI.MulExtension(unfiltered[i], filter)
|
||||
}
|
||||
return unfiltered
|
||||
}
|
||||
|
||||
func (g *EvaluateGatesChip) EvaluateGateConstraints(vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := make([]field.QuadraticExtension, g.numGateConstraints)
|
||||
for i := range constraints {
|
||||
constraints[i] = g.qeAPI.ZERO_QE
|
||||
}
|
||||
|
||||
for i, gate := range g.gates {
|
||||
selectorIndex := g.selectorsInfo.selectorIndices[i]
|
||||
|
||||
gateConstraints := g.evalFiltered(
|
||||
gate,
|
||||
vars,
|
||||
uint64(i),
|
||||
selectorIndex,
|
||||
g.selectorsInfo.groups[selectorIndex],
|
||||
g.selectorsInfo.NumSelectors(),
|
||||
)
|
||||
|
||||
for i, constraint := range gateConstraints {
|
||||
if uint64(i) >= g.numGateConstraints {
|
||||
panic("num_constraints() gave too low of a number")
|
||||
}
|
||||
constraints[i] = g.qeAPI.AddExtension(constraints[i], constraint)
|
||||
}
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var exponentiationGateRegex = regexp.MustCompile("ExponentiationGate { num_power_bits: (?P<numPowerBits>[0-9]+), _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=(?P<base>[0-9]+)>")
|
||||
|
||||
func deserializeExponentiationGate(parameters map[string]string) Gate {
|
||||
// Has the format "ExponentiationGate { num_power_bits: 67, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
|
||||
numPowerBits, hasNumPowerBits := parameters["numPowerBits"]
|
||||
if !hasNumPowerBits {
|
||||
panic("Missing field num_power_bits in ExponentiationGate")
|
||||
}
|
||||
|
||||
numPowerBitsInt, err := strconv.Atoi(numPowerBits)
|
||||
if err != nil {
|
||||
panic("Invalid num_power_bits field in ExponentiationGate")
|
||||
}
|
||||
|
||||
return NewExponentiationGate(uint64(numPowerBitsInt))
|
||||
}
|
||||
|
||||
type ExponentiationGate struct {
|
||||
numPowerBits uint64
|
||||
}
|
||||
|
||||
func NewExponentiationGate(numPowerBits uint64) *ExponentiationGate {
|
||||
return &ExponentiationGate{
|
||||
numPowerBits: numPowerBits,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) Id() string {
|
||||
return fmt.Sprintf("ExponentiationGate { num_power_bits: %d }", g.numPowerBits)
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) wireBase() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// / The `i`th bit of the exponent, in little-endian order.
|
||||
func (g *ExponentiationGate) wirePowerBit(i uint64) uint64 {
|
||||
if i >= g.numPowerBits {
|
||||
panic("Invalid power bit index")
|
||||
}
|
||||
return 1 + i
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) wireOutput() uint64 {
|
||||
return 1 + g.numPowerBits
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) wireIntermediateValue(i uint64) uint64 {
|
||||
if i >= g.numPowerBits {
|
||||
panic("Invalid intermediate value index")
|
||||
}
|
||||
return 2 + g.numPowerBits + i
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
base := vars.localWires[g.wireBase()]
|
||||
|
||||
var powerBits []field.QuadraticExtension
|
||||
for i := uint64(0); i < g.numPowerBits; i++ {
|
||||
powerBits = append(powerBits, vars.localWires[g.wirePowerBit(i)])
|
||||
}
|
||||
|
||||
var intermediateValues []field.QuadraticExtension
|
||||
for i := uint64(0); i < g.numPowerBits; i++ {
|
||||
intermediateValues = append(intermediateValues, vars.localWires[g.wireIntermediateValue(i)])
|
||||
}
|
||||
|
||||
output := vars.localWires[g.wireOutput()]
|
||||
|
||||
var constraints []field.QuadraticExtension
|
||||
|
||||
for i := uint64(0); i < g.numPowerBits; i++ {
|
||||
var prevIntermediateValue field.QuadraticExtension
|
||||
if i == 0 {
|
||||
prevIntermediateValue = qeAPI.ONE_QE
|
||||
} else {
|
||||
prevIntermediateValue = qeAPI.SquareExtension(intermediateValues[i-1])
|
||||
}
|
||||
|
||||
// powerBits is in LE order, but we accumulate in BE order.
|
||||
curBit := powerBits[g.numPowerBits-i-1]
|
||||
|
||||
// Do a polynomial representation of generaized select (where the selector variable doesn't have to be binary)
|
||||
// if b { x } else { y }
|
||||
// i.e. `bx - (by-y)`.
|
||||
tmp := qeAPI.MulExtension(curBit, qeAPI.ONE_QE)
|
||||
tmp = qeAPI.SubExtension(tmp, qeAPI.ONE_QE)
|
||||
mulBy := qeAPI.MulExtension(curBit, base)
|
||||
mulBy = qeAPI.SubExtension(mulBy, tmp)
|
||||
intermediateValueDiff := qeAPI.MulExtension(prevIntermediateValue, mulBy)
|
||||
intermediateValueDiff = qeAPI.SubExtension(intermediateValueDiff, intermediateValues[i])
|
||||
constraints = append(constraints, intermediateValueDiff)
|
||||
}
|
||||
|
||||
outputDiff := qeAPI.SubExtension(output, intermediateValues[g.numPowerBits-1])
|
||||
constraints = append(constraints, outputDiff)
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
type Gate interface {
|
||||
Id() string
|
||||
EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension
|
||||
}
|
||||
|
||||
var gateRegexHandlers = map[*regexp.Regexp]func(parameters map[string]string) Gate{
|
||||
aritheticGateRegex: deserializeArithmeticGate,
|
||||
aritheticExtensionGateRegex: deserializeExtensionArithmeticGate,
|
||||
baseSumGateRegex: deserializeBaseSumGate,
|
||||
constantGateRegex: deserializeConstantGate,
|
||||
cosetInterpolationGateRegex: deserializeCosetInterpolationGate,
|
||||
exponentiationGateRegex: deserializeExponentiationGate,
|
||||
mulExtensionGateRegex: deserializeMulExtensionGate,
|
||||
noopGateRegex: deserializeNoopGate,
|
||||
poseidonGateRegex: deserializePoseidonGate,
|
||||
poseidonMdsGateRegex: deserializePoseidonMdsGate,
|
||||
publicInputGateRegex: deserializePublicInputGate,
|
||||
randomAccessGateRegex: deserializeRandomAccessGate,
|
||||
reducingExtensionGateRegex: deserializeReducingExtensionGate,
|
||||
reducingGateRegex: deserializeReducingGate,
|
||||
}
|
||||
|
||||
func GateInstanceFromId(gateId string) Gate {
|
||||
for regex, handler := range gateRegexHandlers {
|
||||
matches := regex.FindStringSubmatch(gateId)
|
||||
if matches != nil {
|
||||
parameters := make(map[string]string)
|
||||
for i, name := range regex.SubexpNames() {
|
||||
if i != 0 && name != "" {
|
||||
parameters[name] = matches[i]
|
||||
}
|
||||
}
|
||||
|
||||
if matches != nil {
|
||||
return handler(parameters)
|
||||
}
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf("Unknown gate ID %s", gateId))
|
||||
}
|
||||
@@ -1,763 +0,0 @@
|
||||
package gates_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark-crypto/field/goldilocks"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
// From recursive_step circuit
|
||||
var localConstants = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(4962976205186800892), field.NewFieldConst(6982360466972099197)},
|
||||
{field.NewFieldConst(3587364333101709084), field.NewFieldConst(17496916837371484700)},
|
||||
{field.NewFieldConst(17287374881609559799), field.NewFieldConst(3152841633956965234)},
|
||||
{field.NewFieldConst(8531030241248616826), field.NewFieldConst(7753678118587211959)},
|
||||
{field.NewFieldConst(7622109056373824903), field.NewFieldConst(6523636236475969621)},
|
||||
}
|
||||
|
||||
var localWires = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(5101665081776077058), field.NewFieldConst(13601771238484783081)},
|
||||
{field.NewFieldConst(13763997788502656587), field.NewFieldConst(6068443864169526207)},
|
||||
{field.NewFieldConst(10492880302699453810), field.NewFieldConst(11304418575668616669)},
|
||||
{field.NewFieldConst(2175168501339052813), field.NewFieldConst(3658211467579027796)},
|
||||
{field.NewFieldConst(11342710587435471757), field.NewFieldConst(658078906333318768)},
|
||||
{field.NewFieldConst(16590262768413671742), field.NewFieldConst(4678191900868819358)},
|
||||
{field.NewFieldConst(18412513594273328173), field.NewFieldConst(3981245463942959904)},
|
||||
{field.NewFieldConst(18150166316938544267), field.NewFieldConst(6968565044901838140)},
|
||||
{field.NewFieldConst(1048835939602984673), field.NewFieldConst(3511920575130606798)},
|
||||
{field.NewFieldConst(13693300152826538654), field.NewFieldConst(5872314861500881782)},
|
||||
{field.NewFieldConst(6394696263219721312), field.NewFieldConst(92364988976021720)},
|
||||
{field.NewFieldConst(468193345380249942), field.NewFieldConst(4951036536117371576)},
|
||||
{field.NewFieldConst(9660006729985637684), field.NewFieldConst(14762789799642492635)},
|
||||
{field.NewFieldConst(10091149087332313493), field.NewFieldConst(13279468039286967053)},
|
||||
{field.NewFieldConst(12007469191150580744), field.NewFieldConst(2495445179052731885)},
|
||||
{field.NewFieldConst(14225726459587943147), field.NewFieldConst(13484648741862607201)},
|
||||
{field.NewFieldConst(15365400400136175672), field.NewFieldConst(12227857303059870833)},
|
||||
{field.NewFieldConst(1717742269682481687), field.NewFieldConst(14319701537357602192)},
|
||||
{field.NewFieldConst(2130805637557027375), field.NewFieldConst(9674794597783493233)},
|
||||
{field.NewFieldConst(4200526016516623452), field.NewFieldConst(1757832412907480092)},
|
||||
{field.NewFieldConst(4159226258922372229), field.NewFieldConst(2121976810680943769)},
|
||||
{field.NewFieldConst(2887943290582259162), field.NewFieldConst(10337505797799617185)},
|
||||
{field.NewFieldConst(14760843822980496189), field.NewFieldConst(16331301823872182680)},
|
||||
{field.NewFieldConst(14715580754822129725), field.NewFieldConst(13761736659446638375)},
|
||||
{field.NewFieldConst(6925818640561435525), field.NewFieldConst(14142327999826777974)},
|
||||
{field.NewFieldConst(14048060513252076245), field.NewFieldConst(14860933194240516940)},
|
||||
{field.NewFieldConst(3928889853630846436), field.NewFieldConst(16211791673476822740)},
|
||||
{field.NewFieldConst(15980387576926781891), field.NewFieldConst(6238947314711778055)},
|
||||
{field.NewFieldConst(15694939331980119296), field.NewFieldConst(8708301222382733590)},
|
||||
{field.NewFieldConst(192757930858294268), field.NewFieldConst(5400388905722847256)},
|
||||
{field.NewFieldConst(17614358883814855964), field.NewFieldConst(11499208634388453518)},
|
||||
{field.NewFieldConst(9523994443422431577), field.NewFieldConst(6835394446482946098)},
|
||||
{field.NewFieldConst(10096606893378243201), field.NewFieldConst(8982086840326369907)},
|
||||
{field.NewFieldConst(7328922720001507777), field.NewFieldConst(17298728994563323488)},
|
||||
{field.NewFieldConst(7038859554184407337), field.NewFieldConst(6498153778103681368)},
|
||||
{field.NewFieldConst(10610651604960433540), field.NewFieldConst(18240735600936975661)},
|
||||
{field.NewFieldConst(4310901749476028644), field.NewFieldConst(17813866938235850894)},
|
||||
{field.NewFieldConst(12456949458361594924), field.NewFieldConst(16541357680870686003)},
|
||||
{field.NewFieldConst(13986559680062429806), field.NewFieldConst(14210541290696888125)},
|
||||
{field.NewFieldConst(10299578396192380820), field.NewFieldConst(18011235767871391546)},
|
||||
{field.NewFieldConst(747566550336808782), field.NewFieldConst(5892109075601553099)},
|
||||
{field.NewFieldConst(11613383633841665100), field.NewFieldConst(3562006923196410047)},
|
||||
{field.NewFieldConst(14971867523312360339), field.NewFieldConst(9835080574905235511)},
|
||||
{field.NewFieldConst(5487884847548072736), field.NewFieldConst(17112808386797082519)},
|
||||
{field.NewFieldConst(1687420180518659740), field.NewFieldConst(14003627304711288225)},
|
||||
{field.NewFieldConst(6760442482244819429), field.NewFieldConst(15796493945480647537)},
|
||||
{field.NewFieldConst(2639939427088481105), field.NewFieldConst(16213109089273184951)},
|
||||
{field.NewFieldConst(6186345082501710713), field.NewFieldConst(2529053005908871239)},
|
||||
{field.NewFieldConst(16270115914931256348), field.NewFieldConst(2789355919627681645)},
|
||||
{field.NewFieldConst(4586999018177783314), field.NewFieldConst(2427837399215959725)},
|
||||
{field.NewFieldConst(18143358622388343317), field.NewFieldConst(2145167333845152043)},
|
||||
{field.NewFieldConst(20367062449222124), field.NewFieldConst(14939961527015734373)},
|
||||
{field.NewFieldConst(16851694158642043266), field.NewFieldConst(5250789952541240163)},
|
||||
{field.NewFieldConst(273375074794411822), field.NewFieldConst(16211897175907793903)},
|
||||
{field.NewFieldConst(8905927930385832568), field.NewFieldConst(6540262589846603524)},
|
||||
{field.NewFieldConst(9283781971254844102), field.NewFieldConst(15115068064900745758)},
|
||||
{field.NewFieldConst(16002987404851668189), field.NewFieldConst(15226686847545140008)},
|
||||
{field.NewFieldConst(17201679792194997813), field.NewFieldConst(589849108691638964)},
|
||||
{field.NewFieldConst(13270753269614250355), field.NewFieldConst(13858862497673084592)},
|
||||
{field.NewFieldConst(3679908279346826560), field.NewFieldConst(10125726541855725943)},
|
||||
{field.NewFieldConst(9493227554592600240), field.NewFieldConst(13229107531594530196)},
|
||||
{field.NewFieldConst(10072423214517113799), field.NewFieldConst(1877804054697703518)},
|
||||
{field.NewFieldConst(9351494680554520560), field.NewFieldConst(12930187723253788505)},
|
||||
{field.NewFieldConst(9537056082833040850), field.NewFieldConst(3947445714701039423)},
|
||||
{field.NewFieldConst(978662253133020143), field.NewFieldConst(17432233037279205717)},
|
||||
{field.NewFieldConst(13408331971471826902), field.NewFieldConst(8338873650278204671)},
|
||||
{field.NewFieldConst(10455530172494355126), field.NewFieldConst(14614842120953588617)},
|
||||
{field.NewFieldConst(3066054670984065145), field.NewFieldConst(11061840675948823020)},
|
||||
{field.NewFieldConst(1215442291812236170), field.NewFieldConst(6970679356502977963)},
|
||||
{field.NewFieldConst(16254140688845356393), field.NewFieldConst(16413217415268481315)},
|
||||
{field.NewFieldConst(5571707217813279614), field.NewFieldConst(2506082641312169038)},
|
||||
{field.NewFieldConst(18179591596294163519), field.NewFieldConst(16131760445397495720)},
|
||||
{field.NewFieldConst(9500821197677833979), field.NewFieldConst(14137570623214003877)},
|
||||
{field.NewFieldConst(18159279414894480072), field.NewFieldConst(316120438770524969)},
|
||||
{field.NewFieldConst(18164288455905080997), field.NewFieldConst(12889510574086616078)},
|
||||
{field.NewFieldConst(7158952489901063870), field.NewFieldConst(8855957421923524202)},
|
||||
{field.NewFieldConst(11785615172910130564), field.NewFieldConst(13242859272114186921)},
|
||||
{field.NewFieldConst(7978627011292316159), field.NewFieldConst(12030929068833787030)},
|
||||
{field.NewFieldConst(5676253512795062173), field.NewFieldConst(9401396509276686822)},
|
||||
{field.NewFieldConst(13934555872940874542), field.NewFieldConst(12262482935570269103)},
|
||||
{field.NewFieldConst(17018864997992880664), field.NewFieldConst(8399037137658253821)},
|
||||
{field.NewFieldConst(1846702834278938262), field.NewFieldConst(13210394651984411322)},
|
||||
{field.NewFieldConst(18406563809882201846), field.NewFieldConst(15807625126691296911)},
|
||||
{field.NewFieldConst(16192554501791210701), field.NewFieldConst(15105514277710825451)},
|
||||
{field.NewFieldConst(16115514979166385045), field.NewFieldConst(5618092869410987045)},
|
||||
{field.NewFieldConst(9816852940756124129), field.NewFieldConst(1617435612712694609)},
|
||||
{field.NewFieldConst(15012743324956680415), field.NewFieldConst(11098953448520716956)},
|
||||
{field.NewFieldConst(7370750057902285338), field.NewFieldConst(15456123684241865136)},
|
||||
{field.NewFieldConst(14924801177398773859), field.NewFieldConst(1116868612459919368)},
|
||||
{field.NewFieldConst(509701279674911901), field.NewFieldConst(8606220700917290973)},
|
||||
{field.NewFieldConst(256371784527067555), field.NewFieldConst(18023759020251995084)},
|
||||
{field.NewFieldConst(4027645791496469270), field.NewFieldConst(6446906876250510281)},
|
||||
{field.NewFieldConst(8190141658485644545), field.NewFieldConst(3259909135802998300)},
|
||||
{field.NewFieldConst(11270185749533517292), field.NewFieldConst(7032460358965516338)},
|
||||
{field.NewFieldConst(12112891112487601597), field.NewFieldConst(3686732542066412082)},
|
||||
{field.NewFieldConst(18143522178445971138), field.NewFieldConst(6066438010126851248)},
|
||||
{field.NewFieldConst(16109160830754618815), field.NewFieldConst(2728516440557525242)},
|
||||
{field.NewFieldConst(14634072837475699881), field.NewFieldConst(423778353213757146)},
|
||||
{field.NewFieldConst(10421081673554059162), field.NewFieldConst(10142208889746521219)},
|
||||
{field.NewFieldConst(12957639310809930956), field.NewFieldConst(1709286023553869935)},
|
||||
{field.NewFieldConst(16217923109113456531), field.NewFieldConst(3257438610376598615)},
|
||||
{field.NewFieldConst(14024104132094810570), field.NewFieldConst(6065015478137587430)},
|
||||
{field.NewFieldConst(7972303368219061571), field.NewFieldConst(5413678307283424945)},
|
||||
{field.NewFieldConst(10367882107777269226), field.NewFieldConst(9366367173763419226)},
|
||||
{field.NewFieldConst(11506720810821148150), field.NewFieldConst(15210537421649867625)},
|
||||
{field.NewFieldConst(10979917526797364486), field.NewFieldConst(3365843489182711842)},
|
||||
{field.NewFieldConst(9176981360155624350), field.NewFieldConst(7315956459698675112)},
|
||||
{field.NewFieldConst(3964217770504101577), field.NewFieldConst(9088242192411952739)},
|
||||
{field.NewFieldConst(16243289324567090937), field.NewFieldConst(13379263550784156456)},
|
||||
{field.NewFieldConst(18105277122985331384), field.NewFieldConst(13639149553905751132)},
|
||||
{field.NewFieldConst(11145583988660932112), field.NewFieldConst(16125114195985557867)},
|
||||
{field.NewFieldConst(18437667738670181477), field.NewFieldConst(8593343353929068644)},
|
||||
{field.NewFieldConst(15549894364614350199), field.NewFieldConst(6234736889764963090)},
|
||||
{field.NewFieldConst(17753837009416762390), field.NewFieldConst(15297774054893249240)},
|
||||
{field.NewFieldConst(1465043006528110247), field.NewFieldConst(11029942851654974974)},
|
||||
{field.NewFieldConst(14312704742949520917), field.NewFieldConst(17324353686056674958)},
|
||||
{field.NewFieldConst(8078333430227959261), field.NewFieldConst(14797545414164578336)},
|
||||
{field.NewFieldConst(3544997838139687150), field.NewFieldConst(8846840377946705678)},
|
||||
{field.NewFieldConst(9981846866090807073), field.NewFieldConst(18142560414179130259)},
|
||||
{field.NewFieldConst(1256577435119993994), field.NewFieldConst(155745544208227129)},
|
||||
{field.NewFieldConst(6040293874299819317), field.NewFieldConst(10483265617246740662)},
|
||||
{field.NewFieldConst(976159477616343697), field.NewFieldConst(6356544693059700239)},
|
||||
{field.NewFieldConst(4771747444846377672), field.NewFieldConst(2466985401424965488)},
|
||||
{field.NewFieldConst(9549711421417753693), field.NewFieldConst(9543806479040458857)},
|
||||
{field.NewFieldConst(5277199124405775998), field.NewFieldConst(6251037001966593402)},
|
||||
{field.NewFieldConst(13103543598051591262), field.NewFieldConst(2001921170471454234)},
|
||||
{field.NewFieldConst(1254878001165263070), field.NewFieldConst(17587272030879777460)},
|
||||
{field.NewFieldConst(2300344156307624878), field.NewFieldConst(14356513038946626528)},
|
||||
{field.NewFieldConst(2482567400777596327), field.NewFieldConst(3314129985687795881)},
|
||||
{field.NewFieldConst(16492046206730922155), field.NewFieldConst(1312905854247159931)},
|
||||
{field.NewFieldConst(3061501132630116372), field.NewFieldConst(13315665946615810001)},
|
||||
{field.NewFieldConst(16415932954051444990), field.NewFieldConst(925217124969456536)},
|
||||
{field.NewFieldConst(9764657158286137619), field.NewFieldConst(16039332713210679567)},
|
||||
{field.NewFieldConst(14993545086997628961), field.NewFieldConst(18010329211070748489)},
|
||||
{field.NewFieldConst(17327862012036619887), field.NewFieldConst(16962349802452905993)},
|
||||
{field.NewFieldConst(4826313026336060985), field.NewFieldConst(3597777099127511952)},
|
||||
}
|
||||
|
||||
var publicInputsHash = poseidon.PoseidonHashOut{field.ZERO_F, field.ZERO_F, field.ZERO_F, field.ZERO_F}
|
||||
|
||||
var publicInputGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(5101665081776077058), field.NewFieldConst(13601771238484783081)},
|
||||
{field.NewFieldConst(13763997788502656587), field.NewFieldConst(6068443864169526207)},
|
||||
{field.NewFieldConst(10492880302699453810), field.NewFieldConst(11304418575668616669)},
|
||||
{field.NewFieldConst(2175168501339052813), field.NewFieldConst(3658211467579027796)},
|
||||
}
|
||||
|
||||
// BaseSumGate { num_limbs: 63 }), (Base: 2)
|
||||
var baseSumGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(9928715244459351681), field.NewFieldConst(5344081500364361215)},
|
||||
{field.NewFieldConst(10167164649082076581), field.NewFieldConst(15450889555489725096)},
|
||||
{field.NewFieldConst(3546584706462116594), field.NewFieldConst(1476426705388693036)},
|
||||
{field.NewFieldConst(12648634003162244983), field.NewFieldConst(2239452344495239178)},
|
||||
{field.NewFieldConst(2301087631440580451), field.NewFieldConst(11975672920337250307)},
|
||||
{field.NewFieldConst(14001554463269171732), field.NewFieldConst(6953207277617809048)},
|
||||
{field.NewFieldConst(9895590040747031510), field.NewFieldConst(1356956949635190505)},
|
||||
{field.NewFieldConst(14939964178677988571), field.NewFieldConst(454717738260444218)},
|
||||
{field.NewFieldConst(12201660109699192297), field.NewFieldConst(12502457673278583036)},
|
||||
{field.NewFieldConst(1175543972635147885), field.NewFieldConst(11103026408792334489)},
|
||||
{field.NewFieldConst(3384025741923988904), field.NewFieldConst(2656764746353452717)},
|
||||
{field.NewFieldConst(10849522185534943138), field.NewFieldConst(13172212508084788997)},
|
||||
{field.NewFieldConst(10509522572526523739), field.NewFieldConst(2090707475955491976)},
|
||||
{field.NewFieldConst(13692600715410336206), field.NewFieldConst(7227633217973806771)},
|
||||
{field.NewFieldConst(8471053080480597138), field.NewFieldConst(2646922138422495173)},
|
||||
{field.NewFieldConst(555344530120410083), field.NewFieldConst(13860459564781531385)},
|
||||
{field.NewFieldConst(8748801107049442833), field.NewFieldConst(9263752460533085733)},
|
||||
{field.NewFieldConst(13633964398888639692), field.NewFieldConst(10068133633095351031)},
|
||||
{field.NewFieldConst(6911322073377914708), field.NewFieldConst(17978361073083837803)},
|
||||
{field.NewFieldConst(11223090828346729804), field.NewFieldConst(5006610230932979596)},
|
||||
{field.NewFieldConst(11581626217660221266), field.NewFieldConst(16347470001077006094)},
|
||||
{field.NewFieldConst(2924189901864366701), field.NewFieldConst(4309265474738828848)},
|
||||
{field.NewFieldConst(7275314468944461178), field.NewFieldConst(3109308884739285751)},
|
||||
{field.NewFieldConst(12416988612575693809), field.NewFieldConst(13772367397588066248)},
|
||||
{field.NewFieldConst(15438805794425696237), field.NewFieldConst(5809350894111990599)},
|
||||
{field.NewFieldConst(4275145128501503120), field.NewFieldConst(13230668146909969114)},
|
||||
{field.NewFieldConst(15244699495724739585), field.NewFieldConst(7672322205441472064)},
|
||||
{field.NewFieldConst(5429809680618805220), field.NewFieldConst(3153880467220264060)},
|
||||
{field.NewFieldConst(14715345489518514160), field.NewFieldConst(2246036712337629635)},
|
||||
{field.NewFieldConst(9359342125434211935), field.NewFieldConst(7844760208539761732)},
|
||||
{field.NewFieldConst(17550561700498841003), field.NewFieldConst(10851755490050776878)},
|
||||
{field.NewFieldConst(12192385328855013814), field.NewFieldConst(6629056869404844416)},
|
||||
{field.NewFieldConst(3424745785197724925), field.NewFieldConst(9833599393425172230)},
|
||||
{field.NewFieldConst(8602078107149096927), field.NewFieldConst(6592109323720773368)},
|
||||
{field.NewFieldConst(4109716921881297082), field.NewFieldConst(4396469548700606105)},
|
||||
{field.NewFieldConst(10400304110319417426), field.NewFieldConst(1229823145437740976)},
|
||||
{field.NewFieldConst(14853277673343952974), field.NewFieldConst(7653131044140686982)},
|
||||
{field.NewFieldConst(15831955783787857197), field.NewFieldConst(16541106185743830609)},
|
||||
{field.NewFieldConst(16097830673407036871), field.NewFieldConst(917501749911433098)},
|
||||
{field.NewFieldConst(6819428296662518848), field.NewFieldConst(15325182544903569500)},
|
||||
{field.NewFieldConst(3554857310728040215), field.NewFieldConst(17540168721765377170)},
|
||||
{field.NewFieldConst(7246216899469226885), field.NewFieldConst(3184709231158489554)},
|
||||
{field.NewFieldConst(3462793508732024933), field.NewFieldConst(13410498916934897793)},
|
||||
{field.NewFieldConst(784714181705176804), field.NewFieldConst(8079390288171846846)},
|
||||
{field.NewFieldConst(4592501261546923410), field.NewFieldConst(6046244648190342248)},
|
||||
{field.NewFieldConst(14100558314779073910), field.NewFieldConst(9589305391181830029)},
|
||||
{field.NewFieldConst(7208216654581381179), field.NewFieldConst(16662177305876430630)},
|
||||
{field.NewFieldConst(13442246990998561849), field.NewFieldConst(6359024918649040199)},
|
||||
{field.NewFieldConst(16196376030005699590), field.NewFieldConst(5656446490425854681)},
|
||||
{field.NewFieldConst(16279173216505198700), field.NewFieldConst(6278440230935274234)},
|
||||
{field.NewFieldConst(9299204333782277508), field.NewFieldConst(5539548698065086849)},
|
||||
{field.NewFieldConst(531539748103362347), field.NewFieldConst(17008402782657673980)},
|
||||
{field.NewFieldConst(11956287871118080485), field.NewFieldConst(17776888431041950837)},
|
||||
{field.NewFieldConst(16795401491637949606), field.NewFieldConst(12112971435724505573)},
|
||||
{field.NewFieldConst(10141270150228316653), field.NewFieldConst(8738825159351228227)},
|
||||
{field.NewFieldConst(4249416130151320263), field.NewFieldConst(4171109024390883108)},
|
||||
{field.NewFieldConst(13565954345346642147), field.NewFieldConst(11300077318998472624)},
|
||||
{field.NewFieldConst(6006413348327738680), field.NewFieldConst(17429146764001291339)},
|
||||
{field.NewFieldConst(3009379005164242386), field.NewFieldConst(17911649148503516453)},
|
||||
{field.NewFieldConst(4172202865347441020), field.NewFieldConst(6700979848078030374)},
|
||||
{field.NewFieldConst(9692174554453081047), field.NewFieldConst(16461309050820528716)},
|
||||
{field.NewFieldConst(16012555505188709835), field.NewFieldConst(875036531415994728)},
|
||||
{field.NewFieldConst(14527388813134058525), field.NewFieldConst(13371873777459370318)},
|
||||
{field.NewFieldConst(6493493657980111839), field.NewFieldConst(14874520839734823069)},
|
||||
}
|
||||
|
||||
// ArithmeticGate { num_ops: 20 }
|
||||
var arithmeticGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(8251494922795803874), field.NewFieldConst(7884328911897949424)},
|
||||
{field.NewFieldConst(17545754596575389449), field.NewFieldConst(15111927979676704385)},
|
||||
{field.NewFieldConst(10052040965126353731), field.NewFieldConst(1448153912054014611)},
|
||||
{field.NewFieldConst(3878848318701063854), field.NewFieldConst(15999854355391952993)},
|
||||
{field.NewFieldConst(2194699804496089007), field.NewFieldConst(7489112350095609056)},
|
||||
{field.NewFieldConst(666656317372820215), field.NewFieldConst(8333111246649438880)},
|
||||
{field.NewFieldConst(15500013716804095980), field.NewFieldConst(7739144386812042617)},
|
||||
{field.NewFieldConst(2815612394018416154), field.NewFieldConst(15839168197108305099)},
|
||||
{field.NewFieldConst(12980309813768330187), field.NewFieldConst(12446111953378048591)},
|
||||
{field.NewFieldConst(1389916348936822477), field.NewFieldConst(2080258147396834809)},
|
||||
{field.NewFieldConst(3676770229830052631), field.NewFieldConst(8984521981419906260)},
|
||||
{field.NewFieldConst(4759606161035299488), field.NewFieldConst(18415228017149216426)},
|
||||
{field.NewFieldConst(6849567585629675684), field.NewFieldConst(15231001333591586187)},
|
||||
{field.NewFieldConst(17831496121270832947), field.NewFieldConst(1868580989876710210)},
|
||||
{field.NewFieldConst(12226832860244216901), field.NewFieldConst(12352098694767236965)},
|
||||
{field.NewFieldConst(9795530155924375772), field.NewFieldConst(4833402654226660686)},
|
||||
{field.NewFieldConst(7421277748600887772), field.NewFieldConst(16979590244320625600)},
|
||||
{field.NewFieldConst(4212532134312824848), field.NewFieldConst(7938725153260099101)},
|
||||
{field.NewFieldConst(17718231164451799422), field.NewFieldConst(13363195988334771788)},
|
||||
{field.NewFieldConst(5414385531680474153), field.NewFieldConst(13600409983387272243)},
|
||||
}
|
||||
|
||||
// RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
||||
var randomAccessGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(18367067186009695282), field.NewFieldConst(6227937229941915629)},
|
||||
{field.NewFieldConst(342627832935644960), field.NewFieldConst(11262336464371657587)},
|
||||
{field.NewFieldConst(7711502047853221895), field.NewFieldConst(9814305320358879113)},
|
||||
{field.NewFieldConst(2436675870898619939), field.NewFieldConst(12171743011114835714)},
|
||||
{field.NewFieldConst(9224796650008092960), field.NewFieldConst(197827193844666436)},
|
||||
{field.NewFieldConst(7661651717350955969), field.NewFieldConst(3929163527437938921)},
|
||||
{field.NewFieldConst(11994613277879586781), field.NewFieldConst(2918199453077793278)},
|
||||
{field.NewFieldConst(2133315582796573410), field.NewFieldConst(9920472598641951727)},
|
||||
{field.NewFieldConst(5763420675219782924), field.NewFieldConst(193200772658790662)},
|
||||
{field.NewFieldConst(14322103909897767697), field.NewFieldConst(2455403487869979318)},
|
||||
{field.NewFieldConst(3583177870835306708), field.NewFieldConst(15956920993825363087)},
|
||||
{field.NewFieldConst(15767764327818217757), field.NewFieldConst(17814936958431909187)},
|
||||
{field.NewFieldConst(7224551806569620055), field.NewFieldConst(1191241782303323453)},
|
||||
{field.NewFieldConst(3994846439282900915), field.NewFieldConst(16007298430807731888)},
|
||||
{field.NewFieldConst(1904864531973789879), field.NewFieldConst(9374437322489636375)},
|
||||
{field.NewFieldConst(17617411600595291430), field.NewFieldConst(11804426503917788826)},
|
||||
{field.NewFieldConst(5010213812557284606), field.NewFieldConst(8276410914978849008)},
|
||||
{field.NewFieldConst(13701536021647106057), field.NewFieldConst(5043776904396037625)},
|
||||
{field.NewFieldConst(4336267979289896624), field.NewFieldConst(8771134635816393433)},
|
||||
{field.NewFieldConst(17885926480537171976), field.NewFieldConst(9644095314646547597)},
|
||||
{field.NewFieldConst(17179233085824331332), field.NewFieldConst(6950525108693323209)},
|
||||
{field.NewFieldConst(9461258042008745175), field.NewFieldConst(6766975264204597922)},
|
||||
{field.NewFieldConst(10838154179711471883), field.NewFieldConst(16554457937262927355)},
|
||||
{field.NewFieldConst(5823858951686479642), field.NewFieldConst(10171201631442530906)},
|
||||
{field.NewFieldConst(17476953112985367168), field.NewFieldConst(12062851564787792403)},
|
||||
{field.NewFieldConst(7909573710893929152), field.NewFieldConst(6207515797705444652)},
|
||||
}
|
||||
|
||||
// PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>
|
||||
var poseidonGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(15438805794425696237), field.NewFieldConst(5809350894111990599)},
|
||||
{field.NewFieldConst(105238306594298866), field.NewFieldConst(6398155585902798861)},
|
||||
{field.NewFieldConst(5256232026568856387), field.NewFieldConst(9253448664982005262)},
|
||||
{field.NewFieldConst(6559974022172208218), field.NewFieldConst(14478753759394222537)},
|
||||
{field.NewFieldConst(7036928093413865537), field.NewFieldConst(895644692646980845)},
|
||||
{field.NewFieldConst(6350074916129003337), field.NewFieldConst(10418298512623677843)},
|
||||
{field.NewFieldConst(6618288817893266284), field.NewFieldConst(17565920952415773065)},
|
||||
{field.NewFieldConst(7214268149308735221), field.NewFieldConst(17797640553663908886)},
|
||||
{field.NewFieldConst(17038147867485750883), field.NewFieldConst(10766691853641769251)},
|
||||
{field.NewFieldConst(1228066111137794024), field.NewFieldConst(1267834319488006514)},
|
||||
{field.NewFieldConst(15317834050441961579), field.NewFieldConst(13280896488837969140)},
|
||||
{field.NewFieldConst(10135227968960430585), field.NewFieldConst(7096433509203324519)},
|
||||
{field.NewFieldConst(10733417635899979276), field.NewFieldConst(16819459255105516700)},
|
||||
{field.NewFieldConst(4231839251429338586), field.NewFieldConst(3213678047797020863)},
|
||||
{field.NewFieldConst(16271445286187692537), field.NewFieldConst(15377656608157234934)},
|
||||
{field.NewFieldConst(9356442829698587975), field.NewFieldConst(14633910545825415036)},
|
||||
{field.NewFieldConst(13952390018297698734), field.NewFieldConst(16325393355066618599)},
|
||||
{field.NewFieldConst(11399251131586292643), field.NewFieldConst(16257107051968717815)},
|
||||
{field.NewFieldConst(4274092107872068929), field.NewFieldConst(15550597684938436610)},
|
||||
{field.NewFieldConst(13076618331457049912), field.NewFieldConst(4958059540220054374)},
|
||||
{field.NewFieldConst(11650097218963026123), field.NewFieldConst(12070947109214611020)},
|
||||
{field.NewFieldConst(2700303408109034014), field.NewFieldConst(5968338348636871194)},
|
||||
{field.NewFieldConst(11508005723655482353), field.NewFieldConst(15224088756564969467)},
|
||||
{field.NewFieldConst(9328231423353697829), field.NewFieldConst(10577349809783627634)},
|
||||
{field.NewFieldConst(556544259468984890), field.NewFieldConst(13376447539117215836)},
|
||||
{field.NewFieldConst(17319865455991589647), field.NewFieldConst(588985536671201497)},
|
||||
{field.NewFieldConst(9528470026616131077), field.NewFieldConst(7257040911301352274)},
|
||||
{field.NewFieldConst(14316182132889623635), field.NewFieldConst(9589165219691594711)},
|
||||
{field.NewFieldConst(10405802815809041956), field.NewFieldConst(13917007789819955074)},
|
||||
{field.NewFieldConst(12560668105252495616), field.NewFieldConst(3591188232548111694)},
|
||||
{field.NewFieldConst(14765117357942682611), field.NewFieldConst(10757853341059462467)},
|
||||
{field.NewFieldConst(6099902163260965551), field.NewFieldConst(11343816861356056114)},
|
||||
{field.NewFieldConst(1083174255539258286), field.NewFieldConst(7587979659522435417)},
|
||||
{field.NewFieldConst(2882552180249608570), field.NewFieldConst(7966658657757662554)},
|
||||
{field.NewFieldConst(13490914415473336227), field.NewFieldConst(63845168436289811)},
|
||||
{field.NewFieldConst(9459794640071212413), field.NewFieldConst(13417331052474309186)},
|
||||
{field.NewFieldConst(18328090807516092318), field.NewFieldConst(11807085063599693782)},
|
||||
{field.NewFieldConst(281059606944328759), field.NewFieldConst(13352248056867426135)},
|
||||
{field.NewFieldConst(10905177588660050370), field.NewFieldConst(6597328385789442670)},
|
||||
{field.NewFieldConst(8426356906491012567), field.NewFieldConst(17214424336396001022)},
|
||||
{field.NewFieldConst(15696035667318839817), field.NewFieldConst(13285870048485492127)},
|
||||
{field.NewFieldConst(6110244444680672193), field.NewFieldConst(17558548349689468031)},
|
||||
{field.NewFieldConst(14614078615782659381), field.NewFieldConst(13184024850613726857)},
|
||||
{field.NewFieldConst(1541592450520953410), field.NewFieldConst(18339388388315914026)},
|
||||
{field.NewFieldConst(8059386643769157052), field.NewFieldConst(10208764910817462305)},
|
||||
{field.NewFieldConst(7612459820354975117), field.NewFieldConst(7582060685277695926)},
|
||||
{field.NewFieldConst(12515587043516861064), field.NewFieldConst(16099239041553682288)},
|
||||
{field.NewFieldConst(14269196473871652102), field.NewFieldConst(1225067220600668761)},
|
||||
{field.NewFieldConst(12691255077510636187), field.NewFieldConst(14147201911063761532)},
|
||||
{field.NewFieldConst(3001134598446056765), field.NewFieldConst(14313090483058155636)},
|
||||
{field.NewFieldConst(13964993951988177315), field.NewFieldConst(17731737838539414275)},
|
||||
{field.NewFieldConst(2686259154263524343), field.NewFieldConst(12198712301337570859)},
|
||||
{field.NewFieldConst(6730431920128908773), field.NewFieldConst(4325394084875720868)},
|
||||
{field.NewFieldConst(988774723104779817), field.NewFieldConst(8388266879854983623)},
|
||||
{field.NewFieldConst(8233087560647959985), field.NewFieldConst(7751837576340060020)},
|
||||
{field.NewFieldConst(9546113779017699592), field.NewFieldConst(4049920632309298778)},
|
||||
{field.NewFieldConst(3283837251411237060), field.NewFieldConst(13560940050752580093)},
|
||||
{field.NewFieldConst(10388838746951897109), field.NewFieldConst(454393475113110282)},
|
||||
{field.NewFieldConst(2208016536897042313), field.NewFieldConst(17105586471193083308)},
|
||||
{field.NewFieldConst(17683990802267567604), field.NewFieldConst(15398473956537380705)},
|
||||
{field.NewFieldConst(70612752050386177), field.NewFieldConst(12349994002954022957)},
|
||||
{field.NewFieldConst(13794244952989612728), field.NewFieldConst(15888581169565306348)},
|
||||
{field.NewFieldConst(8270800566553141412), field.NewFieldConst(1516938823651329185)},
|
||||
{field.NewFieldConst(643507941153616368), field.NewFieldConst(3893451216814345882)},
|
||||
{field.NewFieldConst(16464837166410943694), field.NewFieldConst(11108183142967610977)},
|
||||
{field.NewFieldConst(9748621820629198396), field.NewFieldConst(3766489907402036319)},
|
||||
{field.NewFieldConst(3115179618981245947), field.NewFieldConst(10160994694067456423)},
|
||||
{field.NewFieldConst(4497210741038443097), field.NewFieldConst(6445446770984515259)},
|
||||
{field.NewFieldConst(5470898125882256227), field.NewFieldConst(8249357863801204908)},
|
||||
{field.NewFieldConst(16762380205819269382), field.NewFieldConst(172510727904060494)},
|
||||
{field.NewFieldConst(7920011253931301350), field.NewFieldConst(9681193995678483756)},
|
||||
{field.NewFieldConst(8258951043315574232), field.NewFieldConst(13137471323476190588)},
|
||||
{field.NewFieldConst(4339364527801481944), field.NewFieldConst(16862579756243326257)},
|
||||
{field.NewFieldConst(8980029737458438570), field.NewFieldConst(14651625524257781922)},
|
||||
{field.NewFieldConst(17935993907375677671), field.NewFieldConst(5318319737405476029)},
|
||||
{field.NewFieldConst(716791501623731831), field.NewFieldConst(18425818060734993303)},
|
||||
{field.NewFieldConst(601549076806364660), field.NewFieldConst(12303919727550310013)},
|
||||
{field.NewFieldConst(18026376178895562118), field.NewFieldConst(14687420532194520529)},
|
||||
{field.NewFieldConst(16943892475592026666), field.NewFieldConst(7451688507369746594)},
|
||||
{field.NewFieldConst(8724072308842121373), field.NewFieldConst(11662986251379699921)},
|
||||
{field.NewFieldConst(3201079129905071298), field.NewFieldConst(11542621183935331871)},
|
||||
{field.NewFieldConst(9889739070824270529), field.NewFieldConst(3891825006545095657)},
|
||||
{field.NewFieldConst(15538978715382418651), field.NewFieldConst(2419672705453973015)},
|
||||
{field.NewFieldConst(3001525234835174062), field.NewFieldConst(17115969716224377534)},
|
||||
{field.NewFieldConst(18001237923148428045), field.NewFieldConst(2198015511953873786)},
|
||||
{field.NewFieldConst(14186741561112601666), field.NewFieldConst(13156405199205086627)},
|
||||
{field.NewFieldConst(10166592177477126663), field.NewFieldConst(13586051001537885658)},
|
||||
{field.NewFieldConst(8678352780562557555), field.NewFieldConst(1968366090049630482)},
|
||||
{field.NewFieldConst(5627999915794840395), field.NewFieldConst(13597556392696072088)},
|
||||
{field.NewFieldConst(9291327714650886898), field.NewFieldConst(2411361999629511024)},
|
||||
{field.NewFieldConst(6824943761729555359), field.NewFieldConst(7484507209360908175)},
|
||||
{field.NewFieldConst(6276580084700132178), field.NewFieldConst(6246691657613415035)},
|
||||
{field.NewFieldConst(10736230409698057656), field.NewFieldConst(7306720219045064925)},
|
||||
{field.NewFieldConst(15442170485732017109), field.NewFieldConst(1739984147692575725)},
|
||||
{field.NewFieldConst(4448878124301402845), field.NewFieldConst(18436455114977877323)},
|
||||
{field.NewFieldConst(638012599023653143), field.NewFieldConst(16265955502846626936)},
|
||||
{field.NewFieldConst(6793907577559820653), field.NewFieldConst(15343551069946118619)},
|
||||
{field.NewFieldConst(17903286158968614509), field.NewFieldConst(9559701571149911252)},
|
||||
{field.NewFieldConst(14652006464960400785), field.NewFieldConst(50421020503848143)},
|
||||
{field.NewFieldConst(9452858006432860845), field.NewFieldConst(2625726945677447428)},
|
||||
{field.NewFieldConst(853640589013584892), field.NewFieldConst(14655161412118141649)},
|
||||
{field.NewFieldConst(12863832006745352780), field.NewFieldConst(14564189651136231029)},
|
||||
{field.NewFieldConst(8551517270810530438), field.NewFieldConst(10859465327758962622)},
|
||||
{field.NewFieldConst(10113468436120661191), field.NewFieldConst(16040944006557911589)},
|
||||
{field.NewFieldConst(4921439225277518643), field.NewFieldConst(8399175422965154512)},
|
||||
{field.NewFieldConst(13068240354812957183), field.NewFieldConst(8520393046894990946)},
|
||||
{field.NewFieldConst(1189183420107219532), field.NewFieldConst(18066897627856601789)},
|
||||
{field.NewFieldConst(3997900004790871153), field.NewFieldConst(1269718920871578117)},
|
||||
{field.NewFieldConst(15438784576472256462), field.NewFieldConst(9577304425687441047)},
|
||||
{field.NewFieldConst(17158083218962275971), field.NewFieldConst(17379790274576244684)},
|
||||
{field.NewFieldConst(3470452736936929010), field.NewFieldConst(12769555113044633230)},
|
||||
{field.NewFieldConst(18389243269515626865), field.NewFieldConst(8023737530782576805)},
|
||||
{field.NewFieldConst(3529213023405995549), field.NewFieldConst(8829896701928525938)},
|
||||
{field.NewFieldConst(14072413770981804653), field.NewFieldConst(9660693090213237836)},
|
||||
{field.NewFieldConst(14369435038913678671), field.NewFieldConst(7659129852562422871)},
|
||||
{field.NewFieldConst(6779301728445724040), field.NewFieldConst(18290152515233036523)},
|
||||
{field.NewFieldConst(8113954200727174254), field.NewFieldConst(16490002532983549952)},
|
||||
{field.NewFieldConst(11465655095604389561), field.NewFieldConst(9066100972825318010)},
|
||||
{field.NewFieldConst(15998691377748321442), field.NewFieldConst(16970045124898180365)},
|
||||
{field.NewFieldConst(8424730626816696233), field.NewFieldConst(17168184083072399403)},
|
||||
{field.NewFieldConst(1941959246552302666), field.NewFieldConst(6751013195867127440)},
|
||||
{field.NewFieldConst(1907519456922228224), field.NewFieldConst(689311996911195932)},
|
||||
{field.NewFieldConst(16277197060525435740), field.NewFieldConst(12018417724719716072)},
|
||||
}
|
||||
|
||||
var reducingExtensionGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(12832102811425062912), field.NewFieldConst(2979695993654444095)},
|
||||
{field.NewFieldConst(4822478941232734654), field.NewFieldConst(2600327308894333341)},
|
||||
{field.NewFieldConst(12450653411048814602), field.NewFieldConst(1161667420593062956)},
|
||||
{field.NewFieldConst(3145631295867407955), field.NewFieldConst(1702059944088737075)},
|
||||
{field.NewFieldConst(4597190091407364771), field.NewFieldConst(4257077286672555409)},
|
||||
{field.NewFieldConst(10177664366491925772), field.NewFieldConst(10489575701186298604)},
|
||||
{field.NewFieldConst(2754621968864722399), field.NewFieldConst(12087963411706301871)},
|
||||
{field.NewFieldConst(534408217555793149), field.NewFieldConst(12559345737194357169)},
|
||||
{field.NewFieldConst(9508765820222303634), field.NewFieldConst(14102461861317982082)},
|
||||
{field.NewFieldConst(15070954032232801974), field.NewFieldConst(2078249670161696735)},
|
||||
{field.NewFieldConst(10465809629504954691), field.NewFieldConst(16223748685835312497)},
|
||||
{field.NewFieldConst(10957196413441800202), field.NewFieldConst(3841214025425953691)},
|
||||
{field.NewFieldConst(18438848195188240825), field.NewFieldConst(5697684145424680565)},
|
||||
{field.NewFieldConst(565455534266129104), field.NewFieldConst(12543354947937779806)},
|
||||
{field.NewFieldConst(16376588778962418386), field.NewFieldConst(1273250903423198860)},
|
||||
{field.NewFieldConst(4128104469872810921), field.NewFieldConst(1433037233801071123)},
|
||||
{field.NewFieldConst(6011337242244377340), field.NewFieldConst(16068106780789397185)},
|
||||
{field.NewFieldConst(4741354504248328629), field.NewFieldConst(3000853646720964165)},
|
||||
{field.NewFieldConst(13064594310789140866), field.NewFieldConst(10950406741883971259)},
|
||||
{field.NewFieldConst(17079026691450750925), field.NewFieldConst(6522027970928818261)},
|
||||
{field.NewFieldConst(13158136237489326416), field.NewFieldConst(7677629162183242732)},
|
||||
{field.NewFieldConst(14741398060174921234), field.NewFieldConst(2960243215156352194)},
|
||||
{field.NewFieldConst(9111161782199179468), field.NewFieldConst(8010960876261510099)},
|
||||
{field.NewFieldConst(1404837029582986528), field.NewFieldConst(9377230983302764181)},
|
||||
{field.NewFieldConst(7086781234814455260), field.NewFieldConst(7571558192372650697)},
|
||||
{field.NewFieldConst(5627013434503229817), field.NewFieldConst(14984048934926143304)},
|
||||
{field.NewFieldConst(2115495655441739405), field.NewFieldConst(1656704965110317534)},
|
||||
{field.NewFieldConst(2311846135199651566), field.NewFieldConst(17438437808346967358)},
|
||||
{field.NewFieldConst(8679806319651401773), field.NewFieldConst(3278538718508560579)},
|
||||
{field.NewFieldConst(7897681105604536660), field.NewFieldConst(10966573925848082711)},
|
||||
{field.NewFieldConst(5451958405177630542), field.NewFieldConst(9207735009647199721)},
|
||||
{field.NewFieldConst(8825486358121162697), field.NewFieldConst(15997852519026522914)},
|
||||
{field.NewFieldConst(475225211669491693), field.NewFieldConst(1907827506180042626)},
|
||||
{field.NewFieldConst(16033031089519343732), field.NewFieldConst(15009948832718035672)},
|
||||
{field.NewFieldConst(5048598591200038865), field.NewFieldConst(156574475928756206)},
|
||||
{field.NewFieldConst(3580311624647961767), field.NewFieldConst(6084715537433906996)},
|
||||
{field.NewFieldConst(9121009921295095324), field.NewFieldConst(18407759801432275235)},
|
||||
{field.NewFieldConst(16569013039730214123), field.NewFieldConst(3930908108224055041)},
|
||||
{field.NewFieldConst(13844066138909451365), field.NewFieldConst(6585754647203519368)},
|
||||
{field.NewFieldConst(14133345335167543367), field.NewFieldConst(3946807387480232364)},
|
||||
{field.NewFieldConst(9876285028806980582), field.NewFieldConst(40898067822033734)},
|
||||
{field.NewFieldConst(6293483059765701407), field.NewFieldConst(16009270905706605849)},
|
||||
{field.NewFieldConst(11635947241393753594), field.NewFieldConst(5053395178858294866)},
|
||||
{field.NewFieldConst(16062194595705166277), field.NewFieldConst(752574348595159408)},
|
||||
{field.NewFieldConst(15607597716340375230), field.NewFieldConst(10428583315124220143)},
|
||||
{field.NewFieldConst(6975301479426228318), field.NewFieldConst(16528136630898216147)},
|
||||
{field.NewFieldConst(16312827398430223622), field.NewFieldConst(17909475722464415780)},
|
||||
{field.NewFieldConst(2273087545743905667), field.NewFieldConst(12405446777919046866)},
|
||||
{field.NewFieldConst(14781933506876191161), field.NewFieldConst(4464109151368149713)},
|
||||
{field.NewFieldConst(4226716729950095934), field.NewFieldConst(8908251769229049654)},
|
||||
{field.NewFieldConst(8310476487592089883), field.NewFieldConst(3834672170570438819)},
|
||||
{field.NewFieldConst(4285568636604940795), field.NewFieldConst(7183765355016179794)},
|
||||
{field.NewFieldConst(14300853697824059506), field.NewFieldConst(16287477445929928328)},
|
||||
{field.NewFieldConst(1238186507267033247), field.NewFieldConst(12357102109973664962)},
|
||||
{field.NewFieldConst(15607388919140050768), field.NewFieldConst(15421065238069253306)},
|
||||
{field.NewFieldConst(12418734453826432586), field.NewFieldConst(12072056126139297564)},
|
||||
{field.NewFieldConst(3924467115116313620), field.NewFieldConst(1212362379653628161)},
|
||||
{field.NewFieldConst(8252514850759544679), field.NewFieldConst(7893938436444134034)},
|
||||
{field.NewFieldConst(711675815009325200), field.NewFieldConst(15678724077367989757)},
|
||||
{field.NewFieldConst(10920573406841924033), field.NewFieldConst(8189696933773246220)},
|
||||
{field.NewFieldConst(9737295100232588618), field.NewFieldConst(13383462338120177171)},
|
||||
{field.NewFieldConst(8983013033045953935), field.NewFieldConst(5301160793103788033)},
|
||||
{field.NewFieldConst(2086512740154274197), field.NewFieldConst(9511985884344255651)},
|
||||
{field.NewFieldConst(7404726366142548080), field.NewFieldConst(11257391295697140486)},
|
||||
{field.NewFieldConst(10045968629671906256), field.NewFieldConst(10721172752468420959)},
|
||||
{field.NewFieldConst(9499240237398016191), field.NewFieldConst(17996498955496851489)},
|
||||
}
|
||||
|
||||
// ReducingGate { num_coeffs: 44 }
|
||||
var reducingGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(4189565386714553574), field.NewFieldConst(14972099283023295929)},
|
||||
{field.NewFieldConst(4811224976739448335), field.NewFieldConst(17901409314576454439)},
|
||||
{field.NewFieldConst(5140059407491502784), field.NewFieldConst(1144330742785924570)},
|
||||
{field.NewFieldConst(7077436393778991453), field.NewFieldConst(13398199711778224412)},
|
||||
{field.NewFieldConst(11213768990622043903), field.NewFieldConst(3886053425349218150)},
|
||||
{field.NewFieldConst(2946099412905029571), field.NewFieldConst(16515307040211357295)},
|
||||
{field.NewFieldConst(11766152895257088950), field.NewFieldConst(12561350435611412995)},
|
||||
{field.NewFieldConst(15559670172179416359), field.NewFieldConst(14246884723129607378)},
|
||||
{field.NewFieldConst(5240707719525548158), field.NewFieldConst(1640773599873992510)},
|
||||
{field.NewFieldConst(14358821079049832289), field.NewFieldConst(2746855687282611080)},
|
||||
{field.NewFieldConst(3214086216088588558), field.NewFieldConst(1520697626094905530)},
|
||||
{field.NewFieldConst(9834748172213967248), field.NewFieldConst(13487010468070558667)},
|
||||
{field.NewFieldConst(1423442768503334248), field.NewFieldConst(10945790255819476518)},
|
||||
{field.NewFieldConst(2308372186436983690), field.NewFieldConst(8803174935784778070)},
|
||||
{field.NewFieldConst(9995833078447025147), field.NewFieldConst(9074310518079663649)},
|
||||
{field.NewFieldConst(14149697874498108875), field.NewFieldConst(15875817120435194028)},
|
||||
{field.NewFieldConst(14564758547073982656), field.NewFieldConst(13386335755835868953)},
|
||||
{field.NewFieldConst(6432745607675418074), field.NewFieldConst(8030247499566565321)},
|
||||
{field.NewFieldConst(17308235779926438117), field.NewFieldConst(16843697410674499818)},
|
||||
{field.NewFieldConst(15507223129386571868), field.NewFieldConst(3935281607585552366)},
|
||||
{field.NewFieldConst(16041402982622709805), field.NewFieldConst(12432717078068957835)},
|
||||
{field.NewFieldConst(6455955094164032063), field.NewFieldConst(2435635342699968412)},
|
||||
{field.NewFieldConst(9814981570869789379), field.NewFieldConst(5009257884262115226)},
|
||||
{field.NewFieldConst(9452031978763862902), field.NewFieldConst(15609083603899848676)},
|
||||
{field.NewFieldConst(13532623109002857304), field.NewFieldConst(7324541443245949391)},
|
||||
{field.NewFieldConst(7899075212455453622), field.NewFieldConst(14276489152002439614)},
|
||||
{field.NewFieldConst(2403019844704266911), field.NewFieldConst(5922544710604013781)},
|
||||
{field.NewFieldConst(9709471021111675830), field.NewFieldConst(5538539165068927028)},
|
||||
{field.NewFieldConst(15700585567216041265), field.NewFieldConst(17893894492159337326)},
|
||||
{field.NewFieldConst(8890003199638063977), field.NewFieldConst(17726621767321974437)},
|
||||
{field.NewFieldConst(389239919653982052), field.NewFieldConst(3497778410650283061)},
|
||||
{field.NewFieldConst(845227572644858827), field.NewFieldConst(7040344997713673855)},
|
||||
{field.NewFieldConst(9861253052349275208), field.NewFieldConst(1880449137233040023)},
|
||||
{field.NewFieldConst(9239454143759318515), field.NewFieldConst(7968256557482935820)},
|
||||
{field.NewFieldConst(12576879243038758854), field.NewFieldConst(9784626207087825707)},
|
||||
{field.NewFieldConst(14811673587164089973), field.NewFieldConst(10785522535030299714)},
|
||||
{field.NewFieldConst(696437091186897361), field.NewFieldConst(13293602092569033065)},
|
||||
{field.NewFieldConst(1240161179290551759), field.NewFieldConst(9542275505416038259)},
|
||||
{field.NewFieldConst(5298553932515957396), field.NewFieldConst(14597738151157731445)},
|
||||
{field.NewFieldConst(8472517818840783225), field.NewFieldConst(7685861056688910111)},
|
||||
{field.NewFieldConst(10067665523858551777), field.NewFieldConst(13019870415534016025)},
|
||||
{field.NewFieldConst(3030966178198674680), field.NewFieldConst(10107838846102885642)},
|
||||
{field.NewFieldConst(6762889891370677550), field.NewFieldConst(16151528872832782368)},
|
||||
{field.NewFieldConst(17207754552662723664), field.NewFieldConst(15168039969859158460)},
|
||||
{field.NewFieldConst(9111161782199179468), field.NewFieldConst(8010960876261510099)},
|
||||
{field.NewFieldConst(1212079098724692260), field.NewFieldConst(3976842077579916925)},
|
||||
{field.NewFieldConst(8111924351272477885), field.NewFieldConst(1472738463707044435)},
|
||||
{field.NewFieldConst(14549763060495382561), field.NewFieldConst(8148654488443197206)},
|
||||
{field.NewFieldConst(9633247645878352168), field.NewFieldConst(4173826759172401145)},
|
||||
{field.NewFieldConst(13429667484612728110), field.NewFieldConst(139708813783643870)},
|
||||
{field.NewFieldConst(11164941208889426013), field.NewFieldConst(3615779386887825309)},
|
||||
{field.NewFieldConst(15733773570058687441), field.NewFieldConst(11172582394325691371)},
|
||||
{field.NewFieldConst(11237663549079845099), field.NewFieldConst(375954911737718734)},
|
||||
{field.NewFieldConst(14815280969174152094), field.NewFieldConst(17903238907570421232)},
|
||||
{field.NewFieldConst(12264332321023153985), field.NewFieldConst(4996015210046477989)},
|
||||
{field.NewFieldConst(5733452693326962912), field.NewFieldConst(15445457134261228447)},
|
||||
{field.NewFieldConst(11339891595047637420), field.NewFieldConst(762619178430884475)},
|
||||
{field.NewFieldConst(10413672060220880988), field.NewFieldConst(2522708614237496949)},
|
||||
{field.NewFieldConst(4759794002943168525), field.NewFieldConst(8366670758049431064)},
|
||||
{field.NewFieldConst(11081128192182141387), field.NewFieldConst(5264843790841556843)},
|
||||
{field.NewFieldConst(16467547707866820269), field.NewFieldConst(10395994280728082037)},
|
||||
{field.NewFieldConst(7372902852922723938), field.NewFieldConst(6597057511414169148)},
|
||||
{field.NewFieldConst(1246550990665510080), field.NewFieldConst(369146659419534786)},
|
||||
{field.NewFieldConst(107137977263990694), field.NewFieldConst(13480217899797734610)},
|
||||
{field.NewFieldConst(9352391006524927052), field.NewFieldConst(16474580549927501346)},
|
||||
{field.NewFieldConst(11475195577527382963), field.NewFieldConst(16771481018793784004)},
|
||||
{field.NewFieldConst(7763817490144412733), field.NewFieldConst(7847907679735875325)},
|
||||
{field.NewFieldConst(6954934416977006194), field.NewFieldConst(1588175103882481774)},
|
||||
{field.NewFieldConst(208699790124989138), field.NewFieldConst(104050776110144395)},
|
||||
{field.NewFieldConst(1999712470949493845), field.NewFieldConst(14640293671425837284)},
|
||||
{field.NewFieldConst(17489389210332023693), field.NewFieldConst(1485853484717956236)},
|
||||
{field.NewFieldConst(13389678828109836153), field.NewFieldConst(12239927773742888217)},
|
||||
{field.NewFieldConst(7279356606052782033), field.NewFieldConst(16889809967345118643)},
|
||||
{field.NewFieldConst(5530632913824527303), field.NewFieldConst(6593916246324540830)},
|
||||
{field.NewFieldConst(6517985275757881887), field.NewFieldConst(1094679265639341934)},
|
||||
{field.NewFieldConst(16005022297334791008), field.NewFieldConst(2231375568117939019)},
|
||||
{field.NewFieldConst(7801581545066110268), field.NewFieldConst(16195585011186011335)},
|
||||
{field.NewFieldConst(2346311239309318787), field.NewFieldConst(10194252071441594046)},
|
||||
{field.NewFieldConst(1333414916806612489), field.NewFieldConst(4078668601880487193)},
|
||||
{field.NewFieldConst(17162202837341088150), field.NewFieldConst(3946492721743094611)},
|
||||
{field.NewFieldConst(2372952988964786162), field.NewFieldConst(14459600129361968991)},
|
||||
{field.NewFieldConst(15958985504784681452), field.NewFieldConst(18297567352909625870)},
|
||||
{field.NewFieldConst(5468110010239944205), field.NewFieldConst(1297673223075459793)},
|
||||
{field.NewFieldConst(5916958362061888790), field.NewFieldConst(12686064186569549334)},
|
||||
{field.NewFieldConst(17141186363273294375), field.NewFieldConst(5330662447468959333)},
|
||||
{field.NewFieldConst(9597329746711776008), field.NewFieldConst(13290917949843243492)},
|
||||
{field.NewFieldConst(9061260430036409956), field.NewFieldConst(10642927510372211646)},
|
||||
{field.NewFieldConst(9766392710518436993), field.NewFieldConst(1864738510099355769)},
|
||||
}
|
||||
|
||||
// ArithmeticExtensionGate { num_ops: 10 }
|
||||
var arithmeticExtensionGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(14556369430662721230), field.NewFieldConst(4131185000258568561)},
|
||||
{field.NewFieldConst(16378466706564867046), field.NewFieldConst(1439052841211884527)},
|
||||
{field.NewFieldConst(8231479592213172392), field.NewFieldConst(8409169031581010782)},
|
||||
{field.NewFieldConst(5465959779370835700), field.NewFieldConst(17016702720873000919)},
|
||||
{field.NewFieldConst(10611951970626560747), field.NewFieldConst(11015475306668399283)},
|
||||
{field.NewFieldConst(6566683434087540889), field.NewFieldConst(7528162900166069532)},
|
||||
{field.NewFieldConst(13167150559619768862), field.NewFieldConst(15618445283750881414)},
|
||||
{field.NewFieldConst(14768578132422983729), field.NewFieldConst(13938407401080069149)},
|
||||
{field.NewFieldConst(18415232841919605685), field.NewFieldConst(15088528771916927003)},
|
||||
{field.NewFieldConst(1305736199568141897), field.NewFieldConst(16885250849392919438)},
|
||||
{field.NewFieldConst(1425549592953864549), field.NewFieldConst(1074162823816629148)},
|
||||
{field.NewFieldConst(12616210534513128803), field.NewFieldConst(8618852250387339753)},
|
||||
{field.NewFieldConst(16775588216530426832), field.NewFieldConst(16358913853138883160)},
|
||||
{field.NewFieldConst(236831045676808583), field.NewFieldConst(16231688985959438642)},
|
||||
{field.NewFieldConst(264831195814170716), field.NewFieldConst(9852325877887114505)},
|
||||
{field.NewFieldConst(14065541678187010167), field.NewFieldConst(5594602585697559035)},
|
||||
{field.NewFieldConst(2354884863196165822), field.NewFieldConst(12715102096346587892)},
|
||||
{field.NewFieldConst(5881791209743274427), field.NewFieldConst(1913490798645218291)},
|
||||
{field.NewFieldConst(3621056055759314065), field.NewFieldConst(15076066883455218113)},
|
||||
{field.NewFieldConst(15382741815013668685), field.NewFieldConst(5674166256062091576)},
|
||||
}
|
||||
|
||||
// MulExtensionGate { num_ops: 13 }
|
||||
var mulExtensionGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(14558272317822654580), field.NewFieldConst(833215892324477732)},
|
||||
{field.NewFieldConst(9214806296346539012), field.NewFieldConst(7798842673847612486)},
|
||||
{field.NewFieldConst(4933313819253472884), field.NewFieldConst(17115399133104593821)},
|
||||
{field.NewFieldConst(6382294466663581729), field.NewFieldConst(8863722647290983592)},
|
||||
{field.NewFieldConst(5274430631758054179), field.NewFieldConst(1761561038204031519)},
|
||||
{field.NewFieldConst(6975818216493368257), field.NewFieldConst(3643153118790582585)},
|
||||
{field.NewFieldConst(9382708770545050748), field.NewFieldConst(2040988809014144797)},
|
||||
{field.NewFieldConst(7526300035416853327), field.NewFieldConst(8692405747344509879)},
|
||||
{field.NewFieldConst(6092157877842311771), field.NewFieldConst(5767914690949635280)},
|
||||
{field.NewFieldConst(3636879736078164520), field.NewFieldConst(454792903724498694)},
|
||||
{field.NewFieldConst(5982213211108308130), field.NewFieldConst(3906161453783544349)},
|
||||
{field.NewFieldConst(1353999567434327832), field.NewFieldConst(3912356165392315450)},
|
||||
{field.NewFieldConst(3866250282554618990), field.NewFieldConst(14215790041865539111)},
|
||||
{field.NewFieldConst(16972659905821970574), field.NewFieldConst(2550277288305104044)},
|
||||
{field.NewFieldConst(6739526869755283609), field.NewFieldConst(4676222628249438354)},
|
||||
{field.NewFieldConst(18314541579046409607), field.NewFieldConst(13871312232745645647)},
|
||||
{field.NewFieldConst(13309435341537760906), field.NewFieldConst(10879629980202564460)},
|
||||
{field.NewFieldConst(8149445702527176593), field.NewFieldConst(12079787385488004774)},
|
||||
{field.NewFieldConst(141936326832390573), field.NewFieldConst(9852981409020916366)},
|
||||
{field.NewFieldConst(1174277439708011834), field.NewFieldConst(11084240604056156653)},
|
||||
{field.NewFieldConst(3890191667424476902), field.NewFieldConst(1428130379783403165)},
|
||||
{field.NewFieldConst(18264002552181363059), field.NewFieldConst(17855293364353531924)},
|
||||
{field.NewFieldConst(1657518282890904146), field.NewFieldConst(14874491364689193658)},
|
||||
{field.NewFieldConst(9091236796792826297), field.NewFieldConst(18232800981045995203)},
|
||||
{field.NewFieldConst(7965395014621568897), field.NewFieldConst(15643014489741966811)},
|
||||
{field.NewFieldConst(14048129594584036134), field.NewFieldConst(8880723489474532129)},
|
||||
}
|
||||
|
||||
// CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
||||
var cosetInterpolationGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(4489474937116132272), field.NewFieldConst(17966585078409280607)},
|
||||
{field.NewFieldConst(6284821823752419954), field.NewFieldConst(15732864946173560339)},
|
||||
{field.NewFieldConst(12879723719779486283), field.NewFieldConst(983649133858104142)},
|
||||
{field.NewFieldConst(17293136937393925432), field.NewFieldConst(4033193666483141970)},
|
||||
{field.NewFieldConst(10809912963683055710), field.NewFieldConst(3166226310305151244)},
|
||||
{field.NewFieldConst(13051854837169808452), field.NewFieldConst(12636844243964449888)},
|
||||
{field.NewFieldConst(15180422697988222141), field.NewFieldConst(3172471974421734205)},
|
||||
{field.NewFieldConst(7715327263429433235), field.NewFieldConst(14269461688353925342)},
|
||||
{field.NewFieldConst(7348198793616724228), field.NewFieldConst(11426363269581761252)},
|
||||
{field.NewFieldConst(6529761710182712179), field.NewFieldConst(15370899814178958348)},
|
||||
{field.NewFieldConst(1312640305437468539), field.NewFieldConst(7416725026793550034)},
|
||||
{field.NewFieldConst(7435934314089172319), field.NewFieldConst(8931511780309647479)},
|
||||
}
|
||||
|
||||
// PoseidonMdsGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
||||
var poseidonMdsGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldConst(7821764612044984890), field.NewFieldConst(11645399715550800761)},
|
||||
{field.NewFieldConst(7054686226368496581), field.NewFieldConst(3456599659382547499)},
|
||||
{field.NewFieldConst(9932401212201586910), field.NewFieldConst(15935184283784595275)},
|
||||
{field.NewFieldConst(14850232436396031573), field.NewFieldConst(10054869170615550942)},
|
||||
{field.NewFieldConst(17859784214232634920), field.NewFieldConst(3141019307077014353)},
|
||||
{field.NewFieldConst(1316926243065869924), field.NewFieldConst(5447399801288094074)},
|
||||
{field.NewFieldConst(12198784876096903918), field.NewFieldConst(10976551553233951532)},
|
||||
{field.NewFieldConst(3280500541526908156), field.NewFieldConst(1813330468204166522)},
|
||||
{field.NewFieldConst(6788483962196012692), field.NewFieldConst(15983747071745976199)},
|
||||
{field.NewFieldConst(3372073447943379816), field.NewFieldConst(9356836818900551936)},
|
||||
{field.NewFieldConst(13834815153351545489), field.NewFieldConst(1073963211629459057)},
|
||||
{field.NewFieldConst(15376716257200419051), field.NewFieldConst(16044430964768811142)},
|
||||
{field.NewFieldConst(16752138206727891451), field.NewFieldConst(6303059651352280564)},
|
||||
{field.NewFieldConst(17195959285241102556), field.NewFieldConst(10990140109461952122)},
|
||||
{field.NewFieldConst(16812594260057394716), field.NewFieldConst(5841834090350584793)},
|
||||
{field.NewFieldConst(17706037262140285164), field.NewFieldConst(8626184557677598926)},
|
||||
{field.NewFieldConst(6826825357492466350), field.NewFieldConst(17865947929743097490)},
|
||||
{field.NewFieldConst(13679887869755160737), field.NewFieldConst(16481628195512675795)},
|
||||
{field.NewFieldConst(7881296289635150478), field.NewFieldConst(15368930380652981390)},
|
||||
{field.NewFieldConst(12075171536836315078), field.NewFieldConst(12900345753644751245)},
|
||||
{field.NewFieldConst(11461113822534614109), field.NewFieldConst(2937306395206947398)},
|
||||
{field.NewFieldConst(18365572828001780476), field.NewFieldConst(4309067613742479326)},
|
||||
{field.NewFieldConst(9460729461000852035), field.NewFieldConst(9232487430983842586)},
|
||||
{field.NewFieldConst(9920817005263779727), field.NewFieldConst(16326126591726196229)},
|
||||
}
|
||||
|
||||
type TestGateCircuit struct {
|
||||
testGate gates.Gate
|
||||
ExpectedConstraints []field.QuadraticExtension
|
||||
}
|
||||
|
||||
func (circuit *TestGateCircuit) Define(api frontend.API) error {
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData("../../data/decode_block/common_circuit_data.json")
|
||||
numSelectors := commonCircuitData.SelectorsInfo.NumSelectors()
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI)
|
||||
|
||||
vars := gates.NewEvaluationVars(localConstants[numSelectors:], localWires, publicInputsHash)
|
||||
|
||||
constraints := circuit.testGate.EvalUnfiltered(api, qeAPI, *vars)
|
||||
|
||||
if len(constraints) != len(circuit.ExpectedConstraints) {
|
||||
return errors.New("gate constraints length mismatch")
|
||||
}
|
||||
for i := 0; i < len(constraints); i++ {
|
||||
qeAPI.AssertIsEqual(constraints[i], circuit.ExpectedConstraints[i])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestGates(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func(testGate gates.Gate, expectedConstraints []field.QuadraticExtension) {
|
||||
circuit := &TestGateCircuit{testGate: testGate, ExpectedConstraints: expectedConstraints}
|
||||
witness := &TestGateCircuit{testGate: testGate, ExpectedConstraints: expectedConstraints}
|
||||
err := test.IsSolved(circuit, witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
type gateTest struct {
|
||||
testGate gates.Gate
|
||||
expectedConstraints []field.QuadraticExtension
|
||||
}
|
||||
|
||||
gateTests := []gateTest{
|
||||
{gates.NewPublicInputGate(), publicInputGateExpectedConstraints},
|
||||
{gates.NewBaseSumGate(63, 2), baseSumGateExpectedConstraints},
|
||||
{gates.NewArithmeticGate(20), arithmeticGateExpectedConstraints},
|
||||
{gates.NewRandomAccessGate(4, 4, 2), randomAccessGateExpectedConstraints},
|
||||
{gates.NewPoseidonGate(), poseidonGateExpectedConstraints},
|
||||
{gates.NewArithmeticExtensionGate(10), arithmeticExtensionGateExpectedConstraints},
|
||||
{gates.NewMultiplicationExtensionGate(13), mulExtensionGateExpectedConstraints},
|
||||
{gates.NewReducingExtensionGate(33), reducingExtensionGateExpectedConstraints},
|
||||
{gates.NewReducingGate(44), reducingGateExpectedConstraints},
|
||||
{gates.NewCosetInterpolationGate(
|
||||
4,
|
||||
6,
|
||||
[]goldilocks.Element{
|
||||
goldilocks.NewElement(17293822565076172801),
|
||||
goldilocks.NewElement(18374686475376656385),
|
||||
goldilocks.NewElement(18446744069413535745),
|
||||
goldilocks.NewElement(281474976645120),
|
||||
goldilocks.NewElement(17592186044416),
|
||||
goldilocks.NewElement(18446744069414584577),
|
||||
goldilocks.NewElement(18446744000695107601),
|
||||
goldilocks.NewElement(18446744065119617025),
|
||||
goldilocks.NewElement(1152921504338411520),
|
||||
goldilocks.NewElement(72057594037927936),
|
||||
goldilocks.NewElement(18446744069415632897),
|
||||
goldilocks.NewElement(18446462594437939201),
|
||||
goldilocks.NewElement(18446726477228539905),
|
||||
goldilocks.NewElement(18446744069414584065),
|
||||
goldilocks.NewElement(68719476720),
|
||||
goldilocks.NewElement(4294967296),
|
||||
},
|
||||
), cosetInterpolationGateExpectedConstraints},
|
||||
{&gates.PoseidonMdsGate{}, poseidonMdsGateExpectedConstraints},
|
||||
}
|
||||
|
||||
for _, test := range gateTests {
|
||||
testCase(
|
||||
test.testGate,
|
||||
test.expectedConstraints,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var mulExtensionGateRegex = regexp.MustCompile("MulExtensionGate { num_ops: (?P<numOps>[0-9]+) }")
|
||||
|
||||
func deserializeMulExtensionGate(parameters map[string]string) Gate {
|
||||
// Has the format "MulExtensionGate { num_ops: 13 }"
|
||||
numOps, hasNumOps := parameters["numOps"]
|
||||
if !hasNumOps {
|
||||
panic("Missing field num_ops in MulExtensionGate")
|
||||
}
|
||||
|
||||
numOpsInt, err := strconv.Atoi(numOps)
|
||||
if err != nil {
|
||||
panic("Invalid num_ops field in MulExtensionGate")
|
||||
}
|
||||
|
||||
return NewMultiplicationExtensionGate(uint64(numOpsInt))
|
||||
}
|
||||
|
||||
type MultiplicationExtensionGate struct {
|
||||
numOps uint64
|
||||
}
|
||||
|
||||
func NewMultiplicationExtensionGate(numOps uint64) *MultiplicationExtensionGate {
|
||||
return &MultiplicationExtensionGate{
|
||||
numOps: numOps,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) Id() string {
|
||||
return fmt.Sprintf("ArithmeticExtensionGate { num_ops: %d }", g.numOps)
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) wiresIthMultiplicand0(i uint64) Range {
|
||||
return Range{3 * field.D * i, 3*field.D*i + field.D}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) wiresIthMultiplicand1(i uint64) Range {
|
||||
return Range{3*field.D*i + field.D, 3*field.D*i + 2*field.D}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) wiresIthOutput(i uint64) Range {
|
||||
return Range{3*field.D*i + 2*field.D, 3*field.D*i + 3*field.D}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
const0 := vars.localConstants[0]
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.numOps; i++ {
|
||||
multiplicand0 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand0(i))
|
||||
multiplicand1 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand1(i))
|
||||
output := vars.GetLocalExtAlgebra(g.wiresIthOutput(i))
|
||||
|
||||
mul := qeAPI.MulExtensionAlgebra(multiplicand0, multiplicand1)
|
||||
computed_output := qeAPI.ScalarMulExtensionAlgebra(const0, mul)
|
||||
|
||||
diff := qeAPI.SubExtensionAlgebra(output, computed_output)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, diff[j])
|
||||
}
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var noopGateRegex = regexp.MustCompile("NoopGate")
|
||||
|
||||
func deserializeNoopGate(parameters map[string]string) Gate {
|
||||
// Has the format "NoopGate"
|
||||
return NewNoopGate()
|
||||
}
|
||||
|
||||
type NoopGate struct {
|
||||
}
|
||||
|
||||
func NewNoopGate() *NoopGate {
|
||||
return &NoopGate{}
|
||||
}
|
||||
|
||||
func (g *NoopGate) Id() string {
|
||||
return "NoopGate"
|
||||
}
|
||||
|
||||
func (g *NoopGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
return []field.QuadraticExtension{}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
)
|
||||
|
||||
var poseidonGateRegex = regexp.MustCompile("PoseidonGate.*")
|
||||
|
||||
func deserializePoseidonGate(parameters map[string]string) Gate {
|
||||
// Has the format "PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
||||
return NewPoseidonGate()
|
||||
}
|
||||
|
||||
type PoseidonGate struct {
|
||||
}
|
||||
|
||||
func NewPoseidonGate() *PoseidonGate {
|
||||
return &PoseidonGate{}
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) Id() string {
|
||||
return "PoseidonGate"
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WireInput(i uint64) uint64 {
|
||||
return i
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WireOutput(i uint64) uint64 {
|
||||
return poseidon.SPONGE_WIDTH + i
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WireSwap() uint64 {
|
||||
return 2 * poseidon.SPONGE_WIDTH
|
||||
}
|
||||
|
||||
const START_DELTA = 2*poseidon.SPONGE_WIDTH + 1
|
||||
|
||||
func (g *PoseidonGate) WireDelta(i uint64) uint64 {
|
||||
if i >= 4 {
|
||||
panic("Delta index out of range")
|
||||
}
|
||||
return START_DELTA + i
|
||||
}
|
||||
|
||||
const START_FULL_0 = START_DELTA + 4
|
||||
|
||||
func (g *PoseidonGate) WireFullSBox0(round uint64, i uint64) uint64 {
|
||||
if round == 0 {
|
||||
panic("First-round S-box inputs are not stored as wires")
|
||||
}
|
||||
if round >= poseidon.HALF_N_FULL_ROUNDS {
|
||||
panic("S-box input round out of range")
|
||||
}
|
||||
if i >= poseidon.SPONGE_WIDTH {
|
||||
panic("S-box input index out of range")
|
||||
}
|
||||
|
||||
return START_FULL_0 + (round-1)*poseidon.SPONGE_WIDTH + i
|
||||
}
|
||||
|
||||
const START_PARTIAL = START_FULL_0 + (poseidon.HALF_N_FULL_ROUNDS-1)*poseidon.SPONGE_WIDTH
|
||||
|
||||
func (g *PoseidonGate) WirePartialSBox(round uint64) uint64 {
|
||||
if round >= poseidon.N_PARTIAL_ROUNDS {
|
||||
panic("S-box input round out of range")
|
||||
}
|
||||
return START_PARTIAL + round
|
||||
}
|
||||
|
||||
const START_FULL_1 = START_PARTIAL + poseidon.N_PARTIAL_ROUNDS
|
||||
|
||||
func (g *PoseidonGate) WireFullSBox1(round uint64, i uint64) uint64 {
|
||||
if round >= poseidon.HALF_N_FULL_ROUNDS {
|
||||
panic("S-box input round out of range")
|
||||
}
|
||||
if i >= poseidon.SPONGE_WIDTH {
|
||||
panic("S-box input index out of range")
|
||||
}
|
||||
|
||||
return START_FULL_1 + round*poseidon.SPONGE_WIDTH + i
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WiresEnd() uint64 {
|
||||
return START_FULL_1 + poseidon.HALF_N_FULL_ROUNDS*poseidon.SPONGE_WIDTH
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, field.NewFieldAPI(api), qeAPI)
|
||||
|
||||
// Assert that `swap` is binary.
|
||||
swap := vars.localWires[g.WireSwap()]
|
||||
swapMinusOne := qeAPI.SubExtension(swap, qeAPI.FieldToQE(field.ONE_F))
|
||||
constraints = append(constraints, qeAPI.MulExtension(swap, swapMinusOne))
|
||||
|
||||
// Assert that each delta wire is set properly: `delta_i = swap * (rhs - lhs)`.
|
||||
for i := uint64(0); i < 4; i++ {
|
||||
inputLhs := vars.localWires[g.WireInput(i)]
|
||||
inputRhs := vars.localWires[g.WireInput(i+4)]
|
||||
deltaI := vars.localWires[g.WireDelta(i)]
|
||||
diff := qeAPI.SubExtension(inputRhs, inputLhs)
|
||||
expectedDeltaI := qeAPI.MulExtension(swap, diff)
|
||||
constraints = append(constraints, qeAPI.SubExtension(expectedDeltaI, deltaI))
|
||||
}
|
||||
|
||||
// Compute the possibly-swapped input layer.
|
||||
var state [poseidon.SPONGE_WIDTH]field.QuadraticExtension
|
||||
for i := uint64(0); i < 4; i++ {
|
||||
deltaI := vars.localWires[g.WireDelta(i)]
|
||||
inputLhs := vars.localWires[g.WireInput(i)]
|
||||
inputRhs := vars.localWires[g.WireInput(i+4)]
|
||||
state[i] = qeAPI.AddExtension(inputLhs, deltaI)
|
||||
state[i+4] = qeAPI.SubExtension(inputRhs, deltaI)
|
||||
}
|
||||
for i := uint64(8); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
state[i] = vars.localWires[g.WireInput(i)]
|
||||
}
|
||||
|
||||
roundCounter := 0
|
||||
|
||||
// First set of full rounds.
|
||||
for r := uint64(0); r < poseidon.HALF_N_FULL_ROUNDS; r++ {
|
||||
state = poseidonChip.ConstantLayerExtension(state, &roundCounter)
|
||||
if r != 0 {
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
sBoxIn := vars.localWires[g.WireFullSBox0(r, i)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[i], sBoxIn))
|
||||
state[i] = sBoxIn
|
||||
}
|
||||
}
|
||||
state = poseidonChip.SBoxLayerExtension(state)
|
||||
state = poseidonChip.MdsLayerExtension(state)
|
||||
roundCounter++
|
||||
}
|
||||
|
||||
// Partial rounds.
|
||||
state = poseidonChip.PartialFirstConstantLayerExtension(state)
|
||||
state = poseidonChip.MdsPartialLayerInitExtension(state)
|
||||
|
||||
for r := uint64(0); r < poseidon.N_PARTIAL_ROUNDS-1; r++ {
|
||||
sBoxIn := vars.localWires[g.WirePartialSBox(r)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[0], sBoxIn))
|
||||
state[0] = poseidonChip.SBoxMonomialExtension(sBoxIn)
|
||||
state[0] = qeAPI.AddExtension(state[0], qeAPI.VarToQE(poseidon.FAST_PARTIAL_ROUND_CONSTANTS[r]))
|
||||
state = poseidonChip.MdsPartialLayerFastExtension(state, int(r))
|
||||
}
|
||||
sBoxIn := vars.localWires[g.WirePartialSBox(poseidon.N_PARTIAL_ROUNDS-1)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[0], sBoxIn))
|
||||
state[0] = poseidonChip.SBoxMonomialExtension(sBoxIn)
|
||||
state = poseidonChip.MdsPartialLayerFastExtension(state, poseidon.N_PARTIAL_ROUNDS-1)
|
||||
roundCounter += poseidon.N_PARTIAL_ROUNDS
|
||||
|
||||
// Second set of full rounds.
|
||||
for r := uint64(0); r < poseidon.HALF_N_FULL_ROUNDS; r++ {
|
||||
state = poseidonChip.ConstantLayerExtension(state, &roundCounter)
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
sBoxIn := vars.localWires[g.WireFullSBox1(r, i)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[i], sBoxIn))
|
||||
state[i] = sBoxIn
|
||||
}
|
||||
state = poseidonChip.SBoxLayerExtension(state)
|
||||
state = poseidonChip.MdsLayerExtension(state)
|
||||
roundCounter++
|
||||
}
|
||||
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[i], vars.localWires[g.WireOutput(i)]))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
)
|
||||
|
||||
var poseidonMdsGateRegex = regexp.MustCompile("PoseidonMdsGate.*")
|
||||
|
||||
func deserializePoseidonMdsGate(parameters map[string]string) Gate {
|
||||
// Has the format "PoseidonMdsGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
||||
return NewPoseidonMdsGate()
|
||||
}
|
||||
|
||||
type PoseidonMdsGate struct {
|
||||
}
|
||||
|
||||
func NewPoseidonMdsGate() *PoseidonMdsGate {
|
||||
return &PoseidonMdsGate{}
|
||||
}
|
||||
|
||||
func (g *PoseidonMdsGate) Id() string {
|
||||
return "PoseidonMdsGate"
|
||||
}
|
||||
|
||||
func (g *PoseidonMdsGate) WireInput(i uint64) Range {
|
||||
if i >= poseidon.SPONGE_WIDTH {
|
||||
panic("Input less than sponge width")
|
||||
}
|
||||
return Range{i * field.D, (i + 1) * field.D}
|
||||
}
|
||||
|
||||
func (g *PoseidonMdsGate) WireOutput(i uint64) Range {
|
||||
if i >= poseidon.SPONGE_WIDTH {
|
||||
panic("Input less than sponge width")
|
||||
}
|
||||
return Range{(poseidon.SPONGE_WIDTH + i) * field.D, (poseidon.SPONGE_WIDTH + i + 1) * field.D}
|
||||
}
|
||||
|
||||
func (g *PoseidonMdsGate) mdsRowShfAlgebra(r uint64, v [poseidon.SPONGE_WIDTH]field.QEAlgebra, qeAPI *field.QuadraticExtensionAPI) field.QEAlgebra {
|
||||
if r >= poseidon.SPONGE_WIDTH {
|
||||
panic("MDS row index out of range")
|
||||
}
|
||||
|
||||
res := qeAPI.ZERO_QE_ALGEBRA
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
coeff := qeAPI.VarToQE(poseidon.MDS_MATRIX_CIRC[i])
|
||||
res = qeAPI.AddExtensionAlgebra(res, qeAPI.ScalarMulExtensionAlgebra(coeff, v[(i+r)%poseidon.SPONGE_WIDTH]))
|
||||
}
|
||||
|
||||
coeff := qeAPI.VarToQE(poseidon.MDS_MATRIX_DIAG[r])
|
||||
res = qeAPI.AddExtensionAlgebra(res, qeAPI.ScalarMulExtensionAlgebra(coeff, v[r]))
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (g *PoseidonMdsGate) mdsLayerAlgebra(state [poseidon.SPONGE_WIDTH]field.QEAlgebra, qeAPI *field.QuadraticExtensionAPI) [poseidon.SPONGE_WIDTH]field.QEAlgebra {
|
||||
var result [poseidon.SPONGE_WIDTH]field.QEAlgebra
|
||||
for r := uint64(0); r < poseidon.SPONGE_WIDTH; r++ {
|
||||
result[r] = g.mdsRowShfAlgebra(r, state, qeAPI)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (g *PoseidonMdsGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
var inputs [poseidon.SPONGE_WIDTH]field.QEAlgebra
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
inputs[i] = vars.GetLocalExtAlgebra(g.WireInput(i))
|
||||
}
|
||||
|
||||
computed_outputs := g.mdsLayerAlgebra(inputs, qeAPI)
|
||||
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
output := vars.GetLocalExtAlgebra(g.WireOutput(i))
|
||||
diff := qeAPI.SubExtensionAlgebra(output, computed_outputs[i])
|
||||
constraints = append(constraints, diff[0], diff[1])
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var publicInputGateRegex = regexp.MustCompile("PublicInputGate")
|
||||
|
||||
func deserializePublicInputGate(parameters map[string]string) Gate {
|
||||
// Has the format "PublicInputGate"
|
||||
return NewPublicInputGate()
|
||||
}
|
||||
|
||||
type PublicInputGate struct {
|
||||
}
|
||||
|
||||
func NewPublicInputGate() *PublicInputGate {
|
||||
return &PublicInputGate{}
|
||||
}
|
||||
|
||||
func (g *PublicInputGate) Id() string {
|
||||
return "PublicInputGate"
|
||||
}
|
||||
|
||||
func (g *PublicInputGate) WiresPublicInputsHash() []uint64 {
|
||||
return []uint64{0, 1, 2, 3}
|
||||
}
|
||||
|
||||
func (g *PublicInputGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
wires := g.WiresPublicInputsHash()
|
||||
hash_parts := vars.publicInputsHash
|
||||
for i := 0; i < 4; i++ {
|
||||
wire := wires[i]
|
||||
hash_part := hash_parts[i]
|
||||
|
||||
diff := qeAPI.SubExtension(vars.localWires[wire], qeAPI.FieldToQE(hash_part))
|
||||
constraints = append(constraints, diff)
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var randomAccessGateRegex = regexp.MustCompile("RandomAccessGate { bits: (?P<bits>[0-9]+), num_copies: (?P<numCopies>[0-9]+), num_extra_constants: (?P<numExtraConstants>[0-9]+), _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=(?P<base>[0-9]+)>")
|
||||
|
||||
func deserializeRandomAccessGate(parameters map[string]string) Gate {
|
||||
// Has the format "RandomAccessGate { bits: 2, num_copies: 13, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
|
||||
bits, hasBits := parameters["bits"]
|
||||
numCopies, hasNumCopies := parameters["numCopies"]
|
||||
numExtraConstants, hasNumExtraConstants := parameters["numExtraConstants"]
|
||||
|
||||
if !hasBits || !hasNumCopies || !hasNumExtraConstants {
|
||||
panic("missing bits, numCopies, numExtraConstants or base in RandomAccessGate")
|
||||
}
|
||||
|
||||
bitsInt, err := strconv.ParseUint(bits, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid bits in RandomAccessGate")
|
||||
}
|
||||
|
||||
numCopiesInt, err := strconv.ParseUint(numCopies, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid numCopies in RandomAccessGate")
|
||||
}
|
||||
|
||||
numExtraConstantsInt, err := strconv.ParseUint(numExtraConstants, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid numExtraConstants in RandomAccessGate")
|
||||
}
|
||||
|
||||
return NewRandomAccessGate(bitsInt, numCopiesInt, numExtraConstantsInt)
|
||||
}
|
||||
|
||||
type RandomAccessGate struct {
|
||||
bits uint64
|
||||
numCopies uint64
|
||||
numExtraConstants uint64
|
||||
}
|
||||
|
||||
func NewRandomAccessGate(bits uint64, numCopies uint64, numExtraConstants uint64) *RandomAccessGate {
|
||||
return &RandomAccessGate{
|
||||
bits: bits,
|
||||
numCopies: numCopies,
|
||||
numExtraConstants: numExtraConstants,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) Id() string {
|
||||
return fmt.Sprintf("RandomAccessGate { bits: %d, num_copies: %d, num_extra_constants: %d }", g.bits, g.numCopies, g.numExtraConstants)
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) vecSize() uint64 {
|
||||
return 1 << g.bits
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireAccessIndex(copy uint64) uint64 {
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireAccessIndex called with copy >= num_copies")
|
||||
}
|
||||
return (2 + g.vecSize()) * copy
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireClaimedElement(copy uint64) uint64 {
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireClaimedElement called with copy >= num_copies")
|
||||
}
|
||||
|
||||
return (2+g.vecSize())*copy + 1
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireListItem(i uint64, copy uint64) uint64 {
|
||||
if i >= g.vecSize() {
|
||||
panic("RandomAccessGate.WireListItem called with i >= vec_size")
|
||||
}
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireListItem called with copy >= num_copies")
|
||||
}
|
||||
|
||||
return (2+g.vecSize())*copy + 2 + i
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) startExtraConstants() uint64 {
|
||||
return (2 + g.vecSize()) * g.numCopies
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) wireExtraConstant(i uint64) uint64 {
|
||||
if i >= g.numExtraConstants {
|
||||
panic("RandomAccessGate.wireExtraConstant called with i >= num_extra_constants")
|
||||
}
|
||||
|
||||
return g.startExtraConstants() + i
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) NumRoutedWires() uint64 {
|
||||
return g.startExtraConstants() + g.numExtraConstants
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireBit(i uint64, copy uint64) uint64 {
|
||||
if i >= g.bits {
|
||||
panic("RandomAccessGate.WireBit called with i >= bits")
|
||||
}
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireBit called with copy >= num_copies")
|
||||
}
|
||||
|
||||
return g.NumRoutedWires() + copy*g.bits + i
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
two := field.QuadraticExtension{field.NewFieldConst(2), field.NewFieldConst(0)}
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
for copy := uint64(0); copy < g.numCopies; copy++ {
|
||||
accessIndex := vars.localWires[g.WireAccessIndex(copy)]
|
||||
listItems := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.vecSize(); i++ {
|
||||
listItems = append(listItems, vars.localWires[g.WireListItem(i, copy)])
|
||||
}
|
||||
claimedElement := vars.localWires[g.WireClaimedElement(copy)]
|
||||
bits := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.bits; i++ {
|
||||
bits = append(bits, vars.localWires[g.WireBit(i, copy)])
|
||||
}
|
||||
|
||||
// Assert that each bit wire value is indeed boolean.
|
||||
for _, b := range bits {
|
||||
bSquared := qeAPI.MulExtension(b, b)
|
||||
constraints = append(constraints, qeAPI.SubExtension(bSquared, b))
|
||||
}
|
||||
|
||||
// Assert that the binary decomposition was correct.
|
||||
reconstructedIndex := qeAPI.ReduceWithPowers(bits, two)
|
||||
constraints = append(constraints, qeAPI.SubExtension(reconstructedIndex, accessIndex))
|
||||
|
||||
for _, b := range bits {
|
||||
listItemsTmp := []field.QuadraticExtension{}
|
||||
for i := 0; i < len(listItems); i += 2 {
|
||||
x := listItems[i]
|
||||
y := listItems[i+1]
|
||||
|
||||
// This is computing `if b { x } else { y }`
|
||||
// i.e. `bx - (by-y)`.
|
||||
mul1 := qeAPI.MulExtension(b, x)
|
||||
sub1 := qeAPI.SubExtension(mul1, x)
|
||||
|
||||
mul2 := qeAPI.MulExtension(b, y)
|
||||
sub2 := qeAPI.SubExtension(mul2, sub1)
|
||||
|
||||
listItemsTmp = append(listItemsTmp, sub2)
|
||||
}
|
||||
listItems = listItemsTmp
|
||||
}
|
||||
|
||||
if len(listItems) != 1 {
|
||||
panic("listItems(len) != 1")
|
||||
}
|
||||
|
||||
constraints = append(constraints, qeAPI.SubExtension(listItems[0], claimedElement))
|
||||
}
|
||||
|
||||
for i := uint64(0); i < g.numExtraConstants; i++ {
|
||||
constraints = append(constraints, qeAPI.SubExtension(vars.localConstants[i], vars.localWires[g.wireExtraConstant(i)]))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var reducingExtensionGateRegex = regexp.MustCompile("ReducingExtensionGate { num_coeffs: (?P<numCoeffs>[0-9]+) }")
|
||||
|
||||
func deserializeReducingExtensionGate(parameters map[string]string) Gate {
|
||||
// Has the format "ReducingGate { num_coeffs: 33 }"
|
||||
numCoeffs, hasNumCoeffs := parameters["numCoeffs"]
|
||||
if !hasNumCoeffs {
|
||||
panic("Missing field num_coeffs in ReducingExtensionGate")
|
||||
}
|
||||
|
||||
numCoeffsInt, err := strconv.Atoi(numCoeffs)
|
||||
if err != nil {
|
||||
panic("Invalid num_coeffs field in ReducingExtensionGate")
|
||||
}
|
||||
|
||||
return NewReducingExtensionGate(uint64(numCoeffsInt))
|
||||
}
|
||||
|
||||
type ReducingExtensionGate struct {
|
||||
numCoeffs uint64
|
||||
}
|
||||
|
||||
const START_COEFFS_REDUCING_EXTENSION_GATE = 3 * field.D
|
||||
|
||||
func NewReducingExtensionGate(numCoeffs uint64) *ReducingExtensionGate {
|
||||
return &ReducingExtensionGate{
|
||||
numCoeffs: numCoeffs,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) Id() string {
|
||||
return fmt.Sprintf("ReducingExtensionGate { num_ops: %d }", g.numCoeffs)
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresOutput() Range {
|
||||
return Range{0, field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresAlpha() Range {
|
||||
return Range{field.D, 2 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresOldAcc() Range {
|
||||
return Range{2 * field.D, 3 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresCoeff(i uint64) Range {
|
||||
return Range{START_COEFFS_REDUCING_EXTENSION_GATE + field.D*i, START_COEFFS_REDUCING_EXTENSION_GATE + field.D*(i+1)}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) startAccs() uint64 {
|
||||
return START_COEFFS_REDUCING_EXTENSION_GATE + g.numCoeffs*field.D
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresAccs(i uint64) Range {
|
||||
if i >= g.numCoeffs {
|
||||
panic("Accumulator index out of bounds")
|
||||
}
|
||||
|
||||
if i == g.numCoeffs-1 {
|
||||
return g.wiresOutput()
|
||||
}
|
||||
|
||||
return Range{g.startAccs() + field.D*i, g.startAccs() + field.D*(i+1)}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
alpha := vars.GetLocalExtAlgebra(g.wiresAlpha())
|
||||
oldAcc := vars.GetLocalExtAlgebra(g.wiresOldAcc())
|
||||
|
||||
coeffs := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
coeffs = append(coeffs, vars.GetLocalExtAlgebra(g.wiresCoeff(i)))
|
||||
}
|
||||
|
||||
accs := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
accs = append(accs, vars.GetLocalExtAlgebra(g.wiresAccs(i)))
|
||||
}
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
acc := oldAcc
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
coeff := coeffs[i]
|
||||
tmp := qeAPI.MulExtensionAlgebra(acc, alpha)
|
||||
tmp = qeAPI.AddExtensionAlgebra(tmp, coeff)
|
||||
tmp = qeAPI.SubExtensionAlgebra(tmp, accs[i])
|
||||
for j := uint64(0); j < field.D; j++ {
|
||||
constraints = append(constraints, tmp[j])
|
||||
}
|
||||
acc = accs[i]
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var reducingGateRegex = regexp.MustCompile("ReducingGate { num_coeffs: (?P<numCoeffs>[0-9]+) }")
|
||||
|
||||
func deserializeReducingGate(parameters map[string]string) Gate {
|
||||
// Has the format "ReducingGate { num_coeffs: 33 }"
|
||||
numCoeffs, hasNumCoeffs := parameters["numCoeffs"]
|
||||
if !hasNumCoeffs {
|
||||
panic("Missing field num_coeffs in ReducingGate")
|
||||
}
|
||||
|
||||
numCoeffsInt, err := strconv.Atoi(numCoeffs)
|
||||
if err != nil {
|
||||
panic("Invalid num_coeffs field in ReducingGate")
|
||||
}
|
||||
|
||||
return NewReducingGate(uint64(numCoeffsInt))
|
||||
}
|
||||
|
||||
type ReducingGate struct {
|
||||
numCoeffs uint64
|
||||
}
|
||||
|
||||
const START_COEFFS_REDUCING_GATE = 3 * field.D
|
||||
|
||||
func NewReducingGate(numCoeffs uint64) *ReducingGate {
|
||||
return &ReducingGate{
|
||||
numCoeffs: numCoeffs,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) Id() string {
|
||||
return fmt.Sprintf("ReducingExtensionGate { num_ops: %d }", g.numCoeffs)
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresOutput() Range {
|
||||
return Range{0, field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresAlpha() Range {
|
||||
return Range{field.D, 2 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresOldAcc() Range {
|
||||
return Range{2 * field.D, 3 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresCoeff() Range {
|
||||
return Range{START_COEFFS_REDUCING_GATE, START_COEFFS_REDUCING_GATE + g.numCoeffs}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) startAccs() uint64 {
|
||||
return START_COEFFS_REDUCING_GATE + g.numCoeffs
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresAccs(i uint64) Range {
|
||||
if i >= g.numCoeffs {
|
||||
panic("Accumulator index out of bounds")
|
||||
}
|
||||
|
||||
if i == g.numCoeffs-1 {
|
||||
return g.wiresOutput()
|
||||
}
|
||||
|
||||
return Range{g.startAccs() + field.D*i, g.startAccs() + field.D*(i+1)}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
alpha := vars.GetLocalExtAlgebra(g.wiresAlpha())
|
||||
oldAcc := vars.GetLocalExtAlgebra(g.wiresOldAcc())
|
||||
|
||||
coeffs := []field.QuadraticExtension{}
|
||||
coeffsRange := g.wiresCoeff()
|
||||
for i := coeffsRange.start; i < coeffsRange.end; i++ {
|
||||
coeffs = append(coeffs, vars.localWires[i])
|
||||
}
|
||||
|
||||
accs := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
accs = append(accs, vars.GetLocalExtAlgebra(g.wiresAccs(i)))
|
||||
}
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
acc := oldAcc
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
var coeff field.QEAlgebra
|
||||
for j := 0; j < field.D; j++ {
|
||||
coeff[j] = qeAPI.ZERO_QE
|
||||
}
|
||||
coeff[0] = coeffs[i]
|
||||
tmp := qeAPI.MulExtensionAlgebra(acc, alpha)
|
||||
tmp = qeAPI.AddExtensionAlgebra(tmp, coeff)
|
||||
tmp = qeAPI.SubExtensionAlgebra(tmp, accs[i])
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, tmp[j])
|
||||
}
|
||||
acc = accs[i]
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package gates
|
||||
|
||||
const UNUSED_SELECTOR = uint64(^uint32(0)) // max uint32
|
||||
|
||||
type Range struct {
|
||||
start uint64
|
||||
end uint64
|
||||
}
|
||||
|
||||
type SelectorsInfo struct {
|
||||
selectorIndices []uint64
|
||||
groups []Range
|
||||
}
|
||||
|
||||
func NewSelectorsInfo(selectorIndices []uint64, groupStarts []uint64, groupEnds []uint64) *SelectorsInfo {
|
||||
if len(groupStarts) != len(groupEnds) {
|
||||
panic("groupStarts and groupEnds must have the same length")
|
||||
}
|
||||
|
||||
groups := []Range{}
|
||||
for i := range groupStarts {
|
||||
groups = append(groups, Range{
|
||||
start: groupStarts[i],
|
||||
end: groupEnds[i],
|
||||
})
|
||||
}
|
||||
|
||||
return &SelectorsInfo{
|
||||
selectorIndices: selectorIndices,
|
||||
groups: groups,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SelectorsInfo) NumSelectors() uint64 {
|
||||
return uint64(len(s.groups))
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
)
|
||||
|
||||
type EvaluationVars struct {
|
||||
localConstants []field.QuadraticExtension
|
||||
localWires []field.QuadraticExtension
|
||||
publicInputsHash poseidon.PoseidonHashOut
|
||||
}
|
||||
|
||||
func NewEvaluationVars(
|
||||
localConstants []field.QuadraticExtension,
|
||||
localWires []field.QuadraticExtension,
|
||||
publicInputsHash poseidon.PoseidonHashOut,
|
||||
) *EvaluationVars {
|
||||
return &EvaluationVars{
|
||||
localConstants: localConstants,
|
||||
localWires: localWires,
|
||||
publicInputsHash: publicInputsHash,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EvaluationVars) RemovePrefix(numSelectors uint64) {
|
||||
e.localConstants = e.localConstants[numSelectors:]
|
||||
}
|
||||
|
||||
func (e *EvaluationVars) GetLocalExtAlgebra(wireRange Range) field.QEAlgebra {
|
||||
// For now, only support degree 2
|
||||
if wireRange.end-wireRange.start != field.D {
|
||||
panic("Range must be of size D")
|
||||
}
|
||||
|
||||
var ret field.QEAlgebra
|
||||
for i := wireRange.start; i < wireRange.end; i++ {
|
||||
ret[i-wireRange.start] = e.localWires[i]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package plonk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
|
||||
)
|
||||
|
||||
type ChallengerChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
field field.FieldAPI `gnark:"-"`
|
||||
poseidonChip *poseidon.PoseidonChip
|
||||
poseidonBN128Chip *poseidon.PoseidonBN128Chip
|
||||
spongeState [poseidon.SPONGE_WIDTH]frontend.Variable
|
||||
inputBuffer []field.F
|
||||
outputBuffer []field.F
|
||||
}
|
||||
|
||||
func NewChallengerChip(api frontend.API, fieldAPI field.FieldAPI, poseidonChip *poseidon.PoseidonChip, poseidonBN128Chip *poseidon.PoseidonBN128Chip) *ChallengerChip {
|
||||
var spongeState [poseidon.SPONGE_WIDTH]frontend.Variable
|
||||
var inputBuffer []field.F
|
||||
var outputBuffer []field.F
|
||||
|
||||
for i := 0; i < poseidon.SPONGE_WIDTH; i++ {
|
||||
spongeState[i] = frontend.Variable(0)
|
||||
}
|
||||
|
||||
return &ChallengerChip{
|
||||
api: api,
|
||||
field: fieldAPI,
|
||||
poseidonChip: poseidonChip,
|
||||
poseidonBN128Chip: poseidonBN128Chip,
|
||||
spongeState: spongeState,
|
||||
inputBuffer: inputBuffer,
|
||||
outputBuffer: outputBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveElement(element field.F) {
|
||||
c.outputBuffer = clearBuffer(c.outputBuffer)
|
||||
c.inputBuffer = append(c.inputBuffer, element)
|
||||
if len(c.inputBuffer) == poseidon.SPONGE_RATE {
|
||||
c.duplexing()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveElements(elements []field.F) {
|
||||
for i := 0; i < len(elements); i++ {
|
||||
c.ObserveElement(elements[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveHash(hash poseidon.PoseidonHashOut) {
|
||||
elements := c.poseidonChip.ToVec(hash)
|
||||
c.ObserveElements(elements)
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveBN128Hash(hash poseidon.PoseidonBN128HashOut) {
|
||||
elements := c.poseidonBN128Chip.ToVec(hash)
|
||||
c.ObserveElements(elements)
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveCap(cap []poseidon.PoseidonBN128HashOut) {
|
||||
for i := 0; i < len(cap); i++ {
|
||||
c.ObserveBN128Hash(cap[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveExtensionElement(element field.QuadraticExtension) {
|
||||
c.ObserveElements(element[:])
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveExtensionElements(elements []field.QuadraticExtension) {
|
||||
for i := 0; i < len(elements); i++ {
|
||||
c.ObserveExtensionElement(elements[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveOpenings(openings fri.FriOpenings) {
|
||||
for i := 0; i < len(openings.Batches); i++ {
|
||||
c.ObserveExtensionElements(openings.Batches[i].Values)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetChallenge() field.F {
|
||||
if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
|
||||
c.duplexing()
|
||||
}
|
||||
|
||||
challenge := c.outputBuffer[len(c.outputBuffer)-1]
|
||||
c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1]
|
||||
|
||||
return challenge
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetNChallenges(n uint64) []field.F {
|
||||
challenges := make([]field.F, n)
|
||||
for i := uint64(0); i < n; i++ {
|
||||
challenges[i] = c.GetChallenge()
|
||||
}
|
||||
return challenges
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetExtensionChallenge() field.QuadraticExtension {
|
||||
values := c.GetNChallenges(2)
|
||||
return field.QuadraticExtension{values[0], values[1]}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetHash() poseidon.PoseidonHashOut {
|
||||
return [4]field.F{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetFriChallenges(commitPhaseMerkleCaps []common.MerkleCap, finalPoly common.PolynomialCoeffs, powWitness field.F, degreeBits uint64, config common.FriConfig) common.FriChallenges {
|
||||
numFriQueries := config.NumQueryRounds
|
||||
friAlpha := c.GetExtensionChallenge()
|
||||
|
||||
var friBetas []field.QuadraticExtension
|
||||
for i := 0; i < len(commitPhaseMerkleCaps); i++ {
|
||||
c.ObserveCap(commitPhaseMerkleCaps[i])
|
||||
friBetas = append(friBetas, c.GetExtensionChallenge())
|
||||
}
|
||||
|
||||
c.ObserveExtensionElements(finalPoly.Coeffs)
|
||||
c.ObserveElement(powWitness)
|
||||
|
||||
friPowResponse := c.GetChallenge()
|
||||
friQueryIndices := c.GetNChallenges(numFriQueries)
|
||||
|
||||
return common.FriChallenges{
|
||||
FriAlpha: friAlpha,
|
||||
FriBetas: friBetas,
|
||||
FriPowResponse: friPowResponse,
|
||||
FriQueryIndices: friQueryIndices,
|
||||
}
|
||||
}
|
||||
|
||||
func clearBuffer(buffer []field.F) []field.F {
|
||||
return make([]field.F, 0)
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) duplexing() {
|
||||
if len(c.inputBuffer) > poseidon.SPONGE_RATE {
|
||||
fmt.Println(len(c.inputBuffer))
|
||||
panic("something went wrong")
|
||||
}
|
||||
|
||||
for i := 0; i < len(c.inputBuffer); i++ {
|
||||
c.spongeState[i] = c.field.Reduce(c.inputBuffer[i]).Limbs[0]
|
||||
}
|
||||
c.inputBuffer = clearBuffer(c.inputBuffer)
|
||||
c.spongeState = c.poseidonChip.Poseidon(c.spongeState)
|
||||
clearBuffer(c.outputBuffer)
|
||||
for i := 0; i < poseidon.SPONGE_RATE; i++ {
|
||||
c.outputBuffer = append(c.outputBuffer, c.field.NewElement(c.spongeState[i]))
|
||||
}
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
package plonk
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/backend/groth16"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/frontend/cs/r1cs"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestChallengerCircuit struct {
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
|
||||
CircuitDigest frontend.Variable `gnark:",public"`
|
||||
PublicInputs []field.F `gnark:",public"`
|
||||
WiresCap []frontend.Variable
|
||||
PlonkZsPartialProductsCap []frontend.Variable
|
||||
QuotientPolysCap []frontend.Variable
|
||||
FriOpenings fri.FriOpenings
|
||||
CommitPhaseMerkleCaps [][]frontend.Variable
|
||||
FinalPoly common.PolynomialCoeffs
|
||||
PowWitness field.F
|
||||
}
|
||||
|
||||
func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename)
|
||||
|
||||
config := commonCircuitData.Config
|
||||
numChallenges := config.NumChallenges
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI)
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
|
||||
poseidonBN128Chip := poseidon.NewPoseidonBN128Chip(api, fieldAPI)
|
||||
challenger := NewChallengerChip(api, fieldAPI, poseidonChip, poseidonBN128Chip)
|
||||
|
||||
challenger.ObserveBN128Hash(circuit.CircuitDigest)
|
||||
challenger.ObserveHash(poseidonChip.HashNoPad(circuit.PublicInputs))
|
||||
challenger.ObserveCap(circuit.WiresCap)
|
||||
plonkBetas := challenger.GetNChallenges(numChallenges)
|
||||
plonkGammas := challenger.GetNChallenges(numChallenges)
|
||||
|
||||
challenger.ObserveCap(circuit.PlonkZsPartialProductsCap)
|
||||
plonkAlphas := challenger.GetNChallenges(numChallenges)
|
||||
|
||||
challenger.ObserveCap(circuit.QuotientPolysCap)
|
||||
plonkZeta := challenger.GetExtensionChallenge()
|
||||
|
||||
challenger.ObserveOpenings(circuit.FriOpenings)
|
||||
|
||||
friChallenges := challenger.GetFriChallenges(
|
||||
circuit.CommitPhaseMerkleCaps,
|
||||
circuit.FinalPoly,
|
||||
circuit.PowWitness,
|
||||
commonCircuitData.DegreeBits,
|
||||
config.FriConfig,
|
||||
)
|
||||
|
||||
expectedPlonkBetas := [2]field.F{
|
||||
field.NewFieldConstFromString("17615363392879944733"),
|
||||
field.NewFieldConstFromString("9422446877322953047"),
|
||||
}
|
||||
|
||||
expectedPlonkGammas := [2]field.F{
|
||||
field.NewFieldConstFromString("15174493176564484303"),
|
||||
field.NewFieldConstFromString("6175150444166239851"),
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
fieldAPI.AssertIsEqual(plonkBetas[i], expectedPlonkBetas[i])
|
||||
fieldAPI.AssertIsEqual(plonkGammas[i], expectedPlonkGammas[i])
|
||||
}
|
||||
|
||||
expectedPlonkAlphas := [2]field.F{
|
||||
field.NewFieldConstFromString("9276470834414745550"),
|
||||
field.NewFieldConstFromString("5302812342351431915"),
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
fieldAPI.AssertIsEqual(plonkAlphas[i], expectedPlonkAlphas[i])
|
||||
}
|
||||
|
||||
expectedPlonkZeta := field.QuadraticExtension{
|
||||
field.NewFieldConstFromString("3892795992421241388"),
|
||||
field.NewFieldConstFromString("15786647757418200302"),
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
fieldAPI.AssertIsEqual(plonkZeta[i], expectedPlonkZeta[i])
|
||||
}
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriAlpha[0], field.NewFieldConst(885535811531859621))
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriBetas[0][0], field.NewFieldConst(5231781384587895507))
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriPowResponse, field.NewFieldConst(70715523064019))
|
||||
|
||||
fieldAPI.AssertIsEqual(friChallenges.FriQueryIndices[0], field.NewFieldConst(11890500485816111017))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func StringToBN128Hash(hashStr string) poseidon.PoseidonBN128HashOut {
|
||||
hashBigInt, ok := new(big.Int).SetString(hashStr, 10)
|
||||
if !(ok) {
|
||||
panic("Invalid hash: " + hashStr)
|
||||
}
|
||||
|
||||
hashVar := frontend.Variable(*hashBigInt)
|
||||
return poseidon.PoseidonBN128HashOut(hashVar)
|
||||
}
|
||||
|
||||
func TestChallengerWitness(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json")
|
||||
verifierData := utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json")
|
||||
|
||||
circuit := TestChallengerCircuit{
|
||||
commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json",
|
||||
|
||||
CircuitDigest: verifierData.CircuitDigest,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
WiresCap: proofWithPis.Proof.WiresCap,
|
||||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
|
||||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
|
||||
}
|
||||
witness := TestChallengerCircuit{
|
||||
CircuitDigest: verifierData.CircuitDigest,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
WiresCap: proofWithPis.Proof.WiresCap,
|
||||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
|
||||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
|
||||
}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
|
||||
func TestChallengerProver(t *testing.T) {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json")
|
||||
verifierData := utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json")
|
||||
|
||||
circuit := TestChallengerCircuit{
|
||||
commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json",
|
||||
|
||||
CircuitDigest: verifierData.CircuitDigest,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
WiresCap: proofWithPis.Proof.WiresCap,
|
||||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
|
||||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
|
||||
}
|
||||
|
||||
proofWithPis = utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json")
|
||||
verifierData = utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json")
|
||||
|
||||
assignment := TestChallengerCircuit{
|
||||
commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json",
|
||||
|
||||
CircuitDigest: verifierData.CircuitDigest,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
WiresCap: proofWithPis.Proof.WiresCap,
|
||||
PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
|
||||
FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||
PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
|
||||
}
|
||||
|
||||
r1cs, err := frontend.Compile(field.TEST_CURVE.ScalarField(), r1cs.NewBuilder, &circuit)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
println("num constraints is ", r1cs.GetNbConstraints())
|
||||
|
||||
assert := test.NewAssert(t)
|
||||
err = test.IsSolved(&circuit, &assignment, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
|
||||
witness, err := frontend.NewWitness(&assignment, field.TEST_CURVE.ScalarField())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pk, vk, err := groth16.Setup(r1cs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
proof, err := groth16.Prove(r1cs, pk, witness)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
publicWitness, err := witness.Public()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = groth16.Verify(proof, vk, publicWitness)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
package plonk
|
||||
|
||||
import (
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
)
|
||||
|
||||
type PlonkChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
|
||||
|
||||
commonData common.CommonCircuitData `gnark:"-"`
|
||||
|
||||
DEGREE field.F `gnark:"-"`
|
||||
DEGREE_BITS_F field.F `gnark:"-"`
|
||||
DEGREE_QE field.QuadraticExtension `gnark:"-"`
|
||||
|
||||
evaluateGatesChip *gates.EvaluateGatesChip
|
||||
}
|
||||
|
||||
func NewPlonkChip(api frontend.API, qeAPI *field.QuadraticExtensionAPI, commonData common.CommonCircuitData) *PlonkChip {
|
||||
// TODO: Should degreeBits be verified that it fits within the field and that degree is within uint64?
|
||||
|
||||
evaluateGatesChip := gates.NewEvaluateGatesChip(
|
||||
api,
|
||||
qeAPI,
|
||||
commonData.Gates,
|
||||
commonData.NumGateConstraints,
|
||||
commonData.SelectorsInfo,
|
||||
)
|
||||
|
||||
return &PlonkChip{
|
||||
api: api,
|
||||
qeAPI: qeAPI,
|
||||
|
||||
commonData: commonData,
|
||||
|
||||
DEGREE: field.NewFieldConst(1 << commonData.DegreeBits),
|
||||
DEGREE_BITS_F: field.NewFieldConst(commonData.DegreeBits),
|
||||
DEGREE_QE: field.QuadraticExtension{field.NewFieldConst(1 << commonData.DegreeBits), field.ZERO_F},
|
||||
|
||||
evaluateGatesChip: evaluateGatesChip,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PlonkChip) expPowerOf2Extension(x field.QuadraticExtension) field.QuadraticExtension {
|
||||
for i := uint64(0); i < p.commonData.DegreeBits; i++ {
|
||||
x = p.qeAPI.SquareExtension(x)
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
func (p *PlonkChip) evalL0(x field.QuadraticExtension, xPowN field.QuadraticExtension) field.QuadraticExtension {
|
||||
// L_0(x) = (x^n - 1) / (n * (x - 1))
|
||||
evalZeroPoly := p.qeAPI.SubExtension(
|
||||
xPowN,
|
||||
p.qeAPI.ONE_QE,
|
||||
)
|
||||
denominator := p.qeAPI.SubExtension(
|
||||
p.qeAPI.ScalarMulExtension(x, p.DEGREE),
|
||||
p.DEGREE_QE,
|
||||
)
|
||||
return p.qeAPI.DivExtension(
|
||||
evalZeroPoly,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
|
||||
func (p *PlonkChip) checkPartialProducts(
|
||||
numerators []field.QuadraticExtension,
|
||||
denominators []field.QuadraticExtension,
|
||||
challengeNum uint64,
|
||||
openings common.OpeningSet,
|
||||
) []field.QuadraticExtension {
|
||||
numPartProds := p.commonData.NumPartialProducts
|
||||
quotDegreeFactor := p.commonData.QuotientDegreeFactor
|
||||
|
||||
productAccs := make([]field.QuadraticExtension, 0, numPartProds+2)
|
||||
productAccs = append(productAccs, openings.PlonkZs[challengeNum])
|
||||
productAccs = append(productAccs, openings.PartialProducts[challengeNum*numPartProds:(challengeNum+1)*numPartProds]...)
|
||||
productAccs = append(productAccs, openings.PlonkZsNext[challengeNum])
|
||||
|
||||
partialProductChecks := make([]field.QuadraticExtension, 0, numPartProds)
|
||||
|
||||
for i := uint64(0); i <= numPartProds; i += 1 {
|
||||
ppStartIdx := i * quotDegreeFactor
|
||||
numeProduct := numerators[ppStartIdx]
|
||||
denoProduct := denominators[ppStartIdx]
|
||||
for j := uint64(1); j < quotDegreeFactor; j++ {
|
||||
numeProduct = p.qeAPI.MulExtension(numeProduct, numerators[ppStartIdx+j])
|
||||
denoProduct = p.qeAPI.MulExtension(denoProduct, denominators[ppStartIdx+j])
|
||||
}
|
||||
|
||||
partialProductCheck := p.qeAPI.SubExtension(
|
||||
p.qeAPI.MulExtension(productAccs[i], numeProduct),
|
||||
p.qeAPI.MulExtension(productAccs[i+1], denoProduct),
|
||||
)
|
||||
|
||||
partialProductChecks = append(partialProductChecks, partialProductCheck)
|
||||
}
|
||||
return partialProductChecks
|
||||
}
|
||||
|
||||
func (p *PlonkChip) evalVanishingPoly(vars gates.EvaluationVars, proofChallenges common.ProofChallenges, openings common.OpeningSet, zetaPowN field.QuadraticExtension) []field.QuadraticExtension {
|
||||
constraintTerms := p.evaluateGatesChip.EvaluateGateConstraints(vars)
|
||||
|
||||
// Calculate the k[i] * x
|
||||
sIDs := make([]field.QuadraticExtension, p.commonData.Config.NumRoutedWires)
|
||||
|
||||
for i := uint64(0); i < p.commonData.Config.NumRoutedWires; i++ {
|
||||
sIDs[i] = p.qeAPI.ScalarMulExtension(proofChallenges.PlonkZeta, p.commonData.KIs[i])
|
||||
}
|
||||
|
||||
// Calculate L_0(zeta)
|
||||
l0Zeta := p.evalL0(proofChallenges.PlonkZeta, zetaPowN)
|
||||
|
||||
vanishingZ1Terms := make([]field.QuadraticExtension, 0, p.commonData.Config.NumChallenges)
|
||||
vanishingPartialProductsTerms := make([]field.QuadraticExtension, 0, p.commonData.Config.NumChallenges*p.commonData.NumPartialProducts)
|
||||
for i := uint64(0); i < p.commonData.Config.NumChallenges; i++ {
|
||||
// L_0(zeta) (Z(zeta) - 1) = 0
|
||||
z1_term := p.qeAPI.MulExtension(
|
||||
l0Zeta,
|
||||
p.qeAPI.SubExtension(openings.PlonkZs[i], p.qeAPI.ONE_QE))
|
||||
vanishingZ1Terms = append(vanishingZ1Terms, z1_term)
|
||||
|
||||
numeratorValues := make([]field.QuadraticExtension, 0, p.commonData.Config.NumRoutedWires)
|
||||
denominatorValues := make([]field.QuadraticExtension, 0, p.commonData.Config.NumRoutedWires)
|
||||
for j := uint64(0); j < p.commonData.Config.NumRoutedWires; j++ {
|
||||
// The numerator is `beta * s_id + wire_value + gamma`, and the denominator is
|
||||
// `beta * s_sigma + wire_value + gamma`.
|
||||
wireValuePlusGamma := p.qeAPI.AddExtension(
|
||||
openings.Wires[j],
|
||||
p.qeAPI.FieldToQE(proofChallenges.PlonkGammas[i]),
|
||||
)
|
||||
|
||||
numerator := p.qeAPI.AddExtension(
|
||||
p.qeAPI.MulExtension(
|
||||
p.qeAPI.FieldToQE(proofChallenges.PlonkBetas[i]),
|
||||
sIDs[j],
|
||||
),
|
||||
wireValuePlusGamma,
|
||||
)
|
||||
|
||||
denominator := p.qeAPI.AddExtension(
|
||||
p.qeAPI.MulExtension(
|
||||
p.qeAPI.FieldToQE(proofChallenges.PlonkBetas[i]),
|
||||
openings.PlonkSigmas[j],
|
||||
),
|
||||
wireValuePlusGamma,
|
||||
)
|
||||
|
||||
numeratorValues = append(numeratorValues, numerator)
|
||||
denominatorValues = append(denominatorValues, denominator)
|
||||
}
|
||||
|
||||
vanishingPartialProductsTerms = append(
|
||||
vanishingPartialProductsTerms,
|
||||
p.checkPartialProducts(numeratorValues, denominatorValues, i, openings)...,
|
||||
)
|
||||
}
|
||||
|
||||
vanishingTerms := append(vanishingZ1Terms, vanishingPartialProductsTerms...)
|
||||
vanishingTerms = append(vanishingTerms, constraintTerms...)
|
||||
|
||||
reducedValues := make([]field.QuadraticExtension, p.commonData.Config.NumChallenges)
|
||||
for i := uint64(0); i < p.commonData.Config.NumChallenges; i++ {
|
||||
reducedValues[i] = p.qeAPI.ZERO_QE
|
||||
}
|
||||
|
||||
// reverse iterate the vanishingPartialProductsTerms array
|
||||
for i := len(vanishingTerms) - 1; i >= 0; i-- {
|
||||
for j := uint64(0); j < p.commonData.Config.NumChallenges; j++ {
|
||||
reducedValues[j] = p.qeAPI.AddExtension(
|
||||
vanishingTerms[i],
|
||||
p.qeAPI.ScalarMulExtension(
|
||||
reducedValues[j],
|
||||
proofChallenges.PlonkAlphas[j],
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return reducedValues
|
||||
}
|
||||
|
||||
func (p *PlonkChip) Verify(proofChallenges common.ProofChallenges, openings common.OpeningSet, publicInputsHash poseidon.PoseidonHashOut) {
|
||||
// Calculate zeta^n
|
||||
zetaPowN := p.expPowerOf2Extension(proofChallenges.PlonkZeta)
|
||||
|
||||
localConstants := openings.Constants
|
||||
localWires := openings.Wires
|
||||
vars := gates.NewEvaluationVars(
|
||||
localConstants,
|
||||
localWires,
|
||||
publicInputsHash,
|
||||
)
|
||||
|
||||
vanishingPolysZeta := p.evalVanishingPoly(*vars, proofChallenges, openings, zetaPowN)
|
||||
|
||||
// Calculate Z(H)
|
||||
zHZeta := p.qeAPI.SubExtension(zetaPowN, p.qeAPI.ONE_QE)
|
||||
|
||||
// `quotient_polys_zeta` holds `num_challenges * quotient_degree_factor` evaluations.
|
||||
// Each chunk of `quotient_degree_factor` holds the evaluations of `t_0(zeta),...,t_{quotient_degree_factor-1}(zeta)`
|
||||
// where the "real" quotient polynomial is `t(X) = t_0(X) + t_1(X)*X^n + t_2(X)*X^{2n} + ...`.
|
||||
// So to reconstruct `t(zeta)` we can compute `reduce_with_powers(chunk, zeta^n)` for each
|
||||
// `quotient_degree_factor`-sized chunk of the original evaluations.
|
||||
for i := 0; i < len(vanishingPolysZeta); i++ {
|
||||
quotientPolysStartIdx := i * int(p.commonData.QuotientDegreeFactor)
|
||||
quotientPolysEndIdx := quotientPolysStartIdx + int(p.commonData.QuotientDegreeFactor)
|
||||
prod := p.qeAPI.MulExtension(
|
||||
zHZeta,
|
||||
p.qeAPI.ReduceWithPowers(
|
||||
openings.QuotientPolys[quotientPolysStartIdx:quotientPolysEndIdx],
|
||||
zetaPowN,
|
||||
),
|
||||
)
|
||||
|
||||
p.qeAPI.AssertIsEqual(vanishingPolysZeta[i], prod)
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package plonk_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestPlonkCircuit struct {
|
||||
proofWithPIsFilename string `gnark:"-"`
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
verifierOnlyCircuitDataFilename string `gnark:"-"`
|
||||
}
|
||||
|
||||
func (circuit *TestPlonkCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename)
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename)
|
||||
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename)
|
||||
|
||||
verifierChip := verifier.NewVerifierChip(api, commonCircuitData)
|
||||
publicInputsHash := verifierChip.GetPublicInputsHash(proofWithPis.PublicInputs)
|
||||
proofChallenges := verifierChip.GetChallenges(proofWithPis.Proof, publicInputsHash, commonCircuitData, verifierOnlyCircuitData)
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI)
|
||||
plonkChip := plonk.NewPlonkChip(
|
||||
api,
|
||||
qeAPI,
|
||||
commonCircuitData,
|
||||
)
|
||||
|
||||
plonkChip.Verify(proofChallenges, proofWithPis.Proof.Openings, publicInputsHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPlonkDecodeBlock(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestPlonkCircuit{
|
||||
proofWithPIsFilename: "../../data/decode_block/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "../../data/decode_block/verifier_only_circuit_data.json",
|
||||
}
|
||||
witness := TestPlonkCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package plonk
|
||||
|
||||
import "github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
|
||||
type OpeningSet struct {
|
||||
Constants []field.QuadraticExtension
|
||||
PlonkSigmas []field.QuadraticExtension
|
||||
Wires []field.QuadraticExtension
|
||||
PlonkZs []field.QuadraticExtension
|
||||
PlonkZsNext []field.QuadraticExtension
|
||||
PartialProducts []field.QuadraticExtension
|
||||
QuotientPolys []field.QuadraticExtension
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk"
|
||||
)
|
||||
|
||||
type Proof struct {
|
||||
WiresCap common.MerkleCap
|
||||
PlonkZsPartialProductsCap common.MerkleCap
|
||||
QuotientPolysCap common.MerkleCap
|
||||
Openings plonk.OpeningSet
|
||||
OpeningProof common.FriProof
|
||||
}
|
||||
|
||||
type ProofWithPublicInputs struct {
|
||||
Proof Proof
|
||||
PublicInputs []field.F
|
||||
}
|
||||
|
||||
type ProofChallenges struct {
|
||||
PlonkBetas []field.F
|
||||
PlonkGammas []field.F
|
||||
PlonkAlphas []field.F
|
||||
PlonkZeta field.QuadraticExtension
|
||||
FriChallenges common.FriChallenges
|
||||
}
|
||||
@@ -2,63 +2,53 @@ package verifier
|
||||
|
||||
import (
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/challenger"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/fri"
|
||||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/plonk"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/types"
|
||||
)
|
||||
|
||||
type VerifierChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
fieldAPI field.FieldAPI `gnark:"-"`
|
||||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
|
||||
poseidonChip *poseidon.PoseidonChip
|
||||
poseidonBN128Chip *poseidon.PoseidonBN128Chip
|
||||
api frontend.API `gnark:"-"`
|
||||
poseidonGlChip *poseidon.GoldilocksChip
|
||||
poseidonBN254Chip *poseidon.BN254Chip
|
||||
plonkChip *plonk.PlonkChip
|
||||
friChip *fri.FriChip
|
||||
friChip *fri.Chip
|
||||
}
|
||||
|
||||
func NewVerifierChip(api frontend.API, commonCircuitData common.CommonCircuitData) *VerifierChip {
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI)
|
||||
poseidonBN128Chip := poseidon.NewPoseidonBN128Chip(api, fieldAPI)
|
||||
|
||||
friChip := fri.NewFriChip(api, fieldAPI, qeAPI, poseidonBN128Chip, &commonCircuitData.FriParams)
|
||||
plonkChip := plonk.NewPlonkChip(api, qeAPI, commonCircuitData)
|
||||
|
||||
// We are using goldilocks poseidon for the challenge computation
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
|
||||
|
||||
func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip {
|
||||
friChip := fri.NewChip(api, &commonCircuitData.FriParams)
|
||||
plonkChip := plonk.NewPlonkChip(api, commonCircuitData)
|
||||
poseidonGlChip := poseidon.NewGoldilocksChip(api)
|
||||
poseidonBN254Chip := poseidon.NewBN254Chip(api)
|
||||
return &VerifierChip{
|
||||
api: api,
|
||||
fieldAPI: fieldAPI,
|
||||
qeAPI: qeAPI,
|
||||
poseidonChip: poseidonChip,
|
||||
poseidonBN128Chip: poseidonBN128Chip,
|
||||
poseidonGlChip: poseidonGlChip,
|
||||
poseidonBN254Chip: poseidonBN254Chip,
|
||||
plonkChip: plonkChip,
|
||||
friChip: friChip,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *VerifierChip) GetPublicInputsHash(publicInputs []field.F) poseidon.PoseidonHashOut {
|
||||
return c.poseidonChip.HashNoPad(publicInputs)
|
||||
func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon.GoldilocksHashOut {
|
||||
return c.poseidonGlChip.HashNoPad(publicInputs)
|
||||
}
|
||||
|
||||
func (c *VerifierChip) GetChallenges(
|
||||
proof common.Proof,
|
||||
publicInputsHash poseidon.PoseidonHashOut,
|
||||
commonData common.CommonCircuitData,
|
||||
verifierData common.VerifierOnlyCircuitData,
|
||||
) common.ProofChallenges {
|
||||
proof types.Proof,
|
||||
publicInputsHash poseidon.GoldilocksHashOut,
|
||||
commonData types.CommonCircuitData,
|
||||
verifierData types.VerifierOnlyCircuitData,
|
||||
) types.ProofChallenges {
|
||||
config := commonData.Config
|
||||
numChallenges := config.NumChallenges
|
||||
challenger := plonk.NewChallengerChip(c.api, c.fieldAPI, c.poseidonChip, c.poseidonBN128Chip)
|
||||
challenger := challenger.NewChip(c.api)
|
||||
|
||||
var circuitDigest = verifierData.CircuitDigest
|
||||
|
||||
challenger.ObserveBN128Hash(circuitDigest)
|
||||
challenger.ObserveBN254Hash(circuitDigest)
|
||||
challenger.ObserveHash(publicInputsHash)
|
||||
challenger.ObserveCap(proof.WiresCap)
|
||||
plonkBetas := challenger.GetNChallenges(numChallenges)
|
||||
@@ -70,9 +60,9 @@ func (c *VerifierChip) GetChallenges(
|
||||
challenger.ObserveCap(proof.QuotientPolysCap)
|
||||
plonkZeta := challenger.GetExtensionChallenge()
|
||||
|
||||
challenger.ObserveOpenings(fri.ToFriOpenings(proof.Openings))
|
||||
challenger.ObserveOpenings(fri.ToOpenings(proof.Openings))
|
||||
|
||||
return common.ProofChallenges{
|
||||
return types.ProofChallenges{
|
||||
PlonkBetas: plonkBetas,
|
||||
PlonkGammas: plonkGammas,
|
||||
PlonkAlphas: plonkAlphas,
|
||||
@@ -154,7 +144,13 @@ func (c *VerifierChip) generateProofInput(commonData common.CommonCircuitData) c
|
||||
}
|
||||
*/
|
||||
|
||||
func (c *VerifierChip) Verify(proof common.Proof, publicInputs []field.F, verifierData common.VerifierOnlyCircuitData, commonData common.CommonCircuitData) {
|
||||
func (c *VerifierChip) Verify(
|
||||
proof types.Proof,
|
||||
publicInputs []gl.Variable,
|
||||
verifierData types.VerifierOnlyCircuitData,
|
||||
commonData types.CommonCircuitData,
|
||||
) {
|
||||
glApi := gl.NewChip(c.api)
|
||||
// TODO: Need to range check all the proof and public input elements to make sure they are within goldilocks field
|
||||
|
||||
// Generate the parts of the witness that is for the plonky2 proof input
|
||||
@@ -163,7 +159,7 @@ func (c *VerifierChip) Verify(proof common.Proof, publicInputs []field.F, verifi
|
||||
|
||||
c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash)
|
||||
|
||||
initialMerkleCaps := []common.MerkleCap{
|
||||
initialMerkleCaps := []types.FriMerkleCap{
|
||||
verifierData.ConstantSigmasCap,
|
||||
proof.WiresCap,
|
||||
proof.PlonkZsPartialProductsCap,
|
||||
@@ -172,26 +168,26 @@ func (c *VerifierChip) Verify(proof common.Proof, publicInputs []field.F, verifi
|
||||
|
||||
// Seems like there is a bug in the emulated field code.
|
||||
// Add ZERO to all of the fri challenges values to reduce them.
|
||||
proofChallenges.PlonkZeta[0] = c.fieldAPI.Add(proofChallenges.PlonkZeta[0], field.ZERO_F)
|
||||
proofChallenges.PlonkZeta[1] = c.fieldAPI.Add(proofChallenges.PlonkZeta[1], field.ZERO_F)
|
||||
proofChallenges.PlonkZeta[0] = glApi.Add(proofChallenges.PlonkZeta[0], gl.Zero())
|
||||
proofChallenges.PlonkZeta[1] = glApi.Add(proofChallenges.PlonkZeta[1], gl.Zero())
|
||||
|
||||
proofChallenges.FriChallenges.FriAlpha[0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[0], field.ZERO_F)
|
||||
proofChallenges.FriChallenges.FriAlpha[1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[1], field.ZERO_F)
|
||||
proofChallenges.FriChallenges.FriAlpha[0] = glApi.Add(proofChallenges.FriChallenges.FriAlpha[0], gl.Zero())
|
||||
proofChallenges.FriChallenges.FriAlpha[1] = glApi.Add(proofChallenges.FriChallenges.FriAlpha[1], gl.Zero())
|
||||
|
||||
for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ {
|
||||
proofChallenges.FriChallenges.FriBetas[i][0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][0], field.ZERO_F)
|
||||
proofChallenges.FriChallenges.FriBetas[i][1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][1], field.ZERO_F)
|
||||
proofChallenges.FriChallenges.FriBetas[i][0] = glApi.Add(proofChallenges.FriChallenges.FriBetas[i][0], gl.Zero())
|
||||
proofChallenges.FriChallenges.FriBetas[i][1] = glApi.Add(proofChallenges.FriChallenges.FriBetas[i][1], gl.Zero())
|
||||
}
|
||||
|
||||
proofChallenges.FriChallenges.FriPowResponse = c.fieldAPI.Add(proofChallenges.FriChallenges.FriPowResponse, field.ZERO_F)
|
||||
proofChallenges.FriChallenges.FriPowResponse = glApi.Add(proofChallenges.FriChallenges.FriPowResponse, gl.Zero())
|
||||
|
||||
for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndices); i++ {
|
||||
proofChallenges.FriChallenges.FriQueryIndices[i] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriQueryIndices[i], field.ZERO_F)
|
||||
proofChallenges.FriChallenges.FriQueryIndices[i] = glApi.Add(proofChallenges.FriChallenges.FriQueryIndices[i], gl.Zero())
|
||||
}
|
||||
|
||||
c.friChip.VerifyFriProof(
|
||||
fri.GetFriInstance(&commonData, c.qeAPI, proofChallenges.PlonkZeta, commonData.DegreeBits),
|
||||
fri.ToFriOpenings(proof.Openings),
|
||||
fri.GetInstance(&commonData, glApi, proofChallenges.PlonkZeta, commonData.DegreeBits),
|
||||
fri.ToOpenings(proof.Openings),
|
||||
&proofChallenges.FriChallenges,
|
||||
initialMerkleCaps,
|
||||
&proof.OpeningProof,
|
||||
|
||||
@@ -8,15 +8,14 @@ import (
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/std/math/emulated"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/types"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestVerifierCircuit struct {
|
||||
Proof common.Proof
|
||||
PublicInputs []field.F `gnark:",public"`
|
||||
Proof types.Proof
|
||||
PublicInputs []gl.Variable `gnark:",public"`
|
||||
|
||||
verifierChip *verifier.VerifierChip `gnark:"-"`
|
||||
plonky2CircuitName string `gnark:"-"`
|
||||
@@ -24,8 +23,8 @@ type TestVerifierCircuit struct {
|
||||
|
||||
func (c *TestVerifierCircuit) Define(api frontend.API) error {
|
||||
circuitDirname := "./data/" + c.plonky2CircuitName + "/"
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json")
|
||||
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json")
|
||||
commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json")
|
||||
verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json")
|
||||
|
||||
c.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
|
||||
|
||||
@@ -39,21 +38,21 @@ func TestStepVerifier(t *testing.T) {
|
||||
|
||||
testCase := func() {
|
||||
plonky2Circuit := "step"
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
proofWithPis := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
circuit := TestVerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis.Proof,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
}
|
||||
|
||||
proofWithPis2 := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
proofWithPis2 := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
witness := TestVerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis2.Proof,
|
||||
PublicInputs: proofWithPis2.PublicInputs,
|
||||
}
|
||||
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
testCase()
|
||||
@@ -63,14 +62,14 @@ func TestStepVerifier2(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
plonky2Circuit := "step"
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
proofWithPis := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
circuit := TestVerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis.Proof,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
}
|
||||
|
||||
proofWithPis2 := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
proofWithPis2 := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
witness := TestVerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis2.Proof,
|
||||
|
||||
Reference in New Issue
Block a user