@ -1,187 +0,0 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"bytes" |
|||
"flag" |
|||
"fmt" |
|||
"math/big" |
|||
"os" |
|||
"time" |
|||
|
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/types" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier" |
|||
|
|||
"github.com/consensys/gnark-crypto/ecc" |
|||
"github.com/consensys/gnark/backend/plonk" |
|||
"github.com/consensys/gnark/constraint" |
|||
"github.com/consensys/gnark/frontend" |
|||
"github.com/consensys/gnark/frontend/cs/scs" |
|||
"github.com/consensys/gnark/profile" |
|||
"github.com/consensys/gnark/test" |
|||
) |
|||
|
|||
type BenchmarkPlonky2VerifierCircuitPlonk struct { |
|||
Proof types.Proof |
|||
PublicInputs []gl.Variable `gnark:",public"` |
|||
|
|||
verifierChip *verifier.VerifierChip `gnark:"-"` |
|||
plonky2CircuitName string `gnark:"-"` |
|||
} |
|||
|
|||
func (circuit *BenchmarkPlonky2VerifierCircuitPlonk) Define(api frontend.API) error { |
|||
circuitDirname := "./verifier/data/" + circuit.plonky2CircuitName + "/" |
|||
commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json") |
|||
verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json") |
|||
|
|||
circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData) |
|||
|
|||
circuit.verifierChip.Verify(circuit.Proof, circuit.PublicInputs, verifierOnlyCircuitData, commonCircuitData) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func compileCircuitPlonk(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, plonk.ProvingKey, plonk.VerifyingKey) { |
|||
circuit := BenchmarkPlonky2VerifierCircuitPlonk{ |
|||
plonky2CircuitName: plonky2Circuit, |
|||
} |
|||
proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") |
|||
circuit.Proof = proofWithPis.Proof |
|||
circuit.PublicInputs = proofWithPis.PublicInputs |
|||
|
|||
var p *profile.Profile |
|||
if profileCircuit { |
|||
p = profile.Start() |
|||
} |
|||
r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &circuit) |
|||
if err != nil { |
|||
fmt.Println("error in building circuit", err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
if profileCircuit { |
|||
p.Stop() |
|||
p.Top() |
|||
println("r1cs.GetNbCoefficients(): ", r1cs.GetNbCoefficients()) |
|||
println("r1cs.GetNbConstraints(): ", r1cs.GetNbConstraints()) |
|||
println("r1cs.GetNbSecretVariables(): ", r1cs.GetNbSecretVariables()) |
|||
println("r1cs.GetNbPublicVariables(): ", r1cs.GetNbPublicVariables()) |
|||
println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables()) |
|||
} |
|||
|
|||
// Don't serialize the circuit for now, since it takes up too much memory
|
|||
/* |
|||
if serialize { |
|||
fR1CS, _ := os.Create("circuit") |
|||
r1cs.WriteTo(fR1CS) |
|||
fR1CS.Close() |
|||
} |
|||
*/ |
|||
|
|||
srs, err := test.NewKZGSRS(r1cs) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
fmt.Println("Running circuit setup", time.Now()) |
|||
pk, vk, err := plonk.Setup(r1cs, srs) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
if serialize { |
|||
fPK, _ := os.Create("proving.key") |
|||
pk.WriteTo(fPK) |
|||
fPK.Close() |
|||
|
|||
fVK, _ := os.Create("verifying.key") |
|||
vk.WriteTo(fVK) |
|||
fVK.Close() |
|||
} |
|||
|
|||
if outputSolidity { |
|||
fSolidity, _ := os.Create("proof.sol") |
|||
err = vk.ExportSolidity(fSolidity) |
|||
} |
|||
|
|||
return r1cs, pk, vk |
|||
} |
|||
|
|||
func createProofPlonk(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk plonk.ProvingKey, vk plonk.VerifyingKey, serialize bool) plonk.Proof { |
|||
proofWithPis := verifier.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json") |
|||
|
|||
// Witness
|
|||
assignment := &BenchmarkPlonky2VerifierCircuitPlonk{ |
|||
Proof: proofWithPis.Proof, |
|||
PublicInputs: proofWithPis.PublicInputs, |
|||
} |
|||
|
|||
fmt.Println("Generating witness", time.Now()) |
|||
witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) |
|||
publicWitness, _ := witness.Public() |
|||
|
|||
fmt.Println("Creating proof", time.Now()) |
|||
proof, err := plonk.Prove(r1cs, pk, witness) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
os.Exit(1) |
|||
} |
|||
fmt.Println("Verifying proof", time.Now()) |
|||
err = plonk.Verify(proof, vk, publicWitness) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
os.Exit(1) |
|||
} |
|||
|
|||
const fpSize = 4 * 8 |
|||
var buf bytes.Buffer |
|||
proof.WriteRawTo(&buf) |
|||
proofBytes := buf.Bytes() |
|||
|
|||
var ( |
|||
a [2]*big.Int |
|||
b [2][2]*big.Int |
|||
c [2]*big.Int |
|||
) |
|||
|
|||
// proof.Ar, proof.Bs, proof.Krs
|
|||
a[0] = new(big.Int).SetBytes(proofBytes[fpSize*0 : fpSize*1]) |
|||
a[1] = new(big.Int).SetBytes(proofBytes[fpSize*1 : fpSize*2]) |
|||
b[0][0] = new(big.Int).SetBytes(proofBytes[fpSize*2 : fpSize*3]) |
|||
b[0][1] = new(big.Int).SetBytes(proofBytes[fpSize*3 : fpSize*4]) |
|||
b[1][0] = new(big.Int).SetBytes(proofBytes[fpSize*4 : fpSize*5]) |
|||
b[1][1] = new(big.Int).SetBytes(proofBytes[fpSize*5 : fpSize*6]) |
|||
c[0] = new(big.Int).SetBytes(proofBytes[fpSize*6 : fpSize*7]) |
|||
c[1] = new(big.Int).SetBytes(proofBytes[fpSize*7 : fpSize*8]) |
|||
|
|||
println("a[0] is ", a[0].String()) |
|||
println("a[1] is ", a[1].String()) |
|||
|
|||
println("b[0][0] is ", b[0][0].String()) |
|||
println("b[0][1] is ", b[0][1].String()) |
|||
println("b[1][0] is ", b[1][0].String()) |
|||
println("b[1][1] is ", b[1][1].String()) |
|||
|
|||
println("c[0] is ", c[0].String()) |
|||
println("c[1] is ", c[1].String()) |
|||
|
|||
return proof |
|||
} |
|||
|
|||
func main() { |
|||
plonky2Circuit := flag.String("plonky2-circuit", "", "plonky2 circuit to benchmark") |
|||
profileCircuit := flag.Bool("profile", false, "profile the circuit") |
|||
serialize := flag.Bool("serialize", false, "serialize the circuit") |
|||
outputSolidity := flag.Bool("solidity", false, "output solidity code for the circuit") |
|||
|
|||
flag.Parse() |
|||
|
|||
if plonky2Circuit == nil || *plonky2Circuit == "" { |
|||
fmt.Println("Please provide a plonky2 circuit to benchmark") |
|||
os.Exit(1) |
|||
} |
|||
|
|||
r1cs, pk, vk := compileCircuitPlonk(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity) |
|||
createProofPlonk(*plonky2Circuit, r1cs, pk, vk, *serialize) |
|||
} |
@ -0,0 +1,21 @@ |
|||
package fri |
|||
|
|||
import gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
|
|||
type BatchInfo struct { |
|||
Point gl.QuadraticExtensionVariable |
|||
Polynomials []PolynomialInfo |
|||
} |
|||
|
|||
type InstanceInfo struct { |
|||
Oracles []OracleInfo |
|||
Batches []BatchInfo |
|||
} |
|||
|
|||
type OpeningBatch struct { |
|||
Values []gl.QuadraticExtensionVariable |
|||
} |
|||
|
|||
type Openings struct { |
|||
Batches []OpeningBatch |
|||
} |
@ -0,0 +1 @@ |
|||
gnark.pprof |
@ -1,51 +0,0 @@ |
|||
package types |
|||
|
|||
import ( |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
) |
|||
|
|||
type Proof struct { |
|||
WiresCap FriMerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
|||
PlonkZsPartialProductsCap FriMerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
|||
QuotientPolysCap FriMerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
|||
Openings OpeningSet |
|||
OpeningProof FriProof |
|||
} |
|||
|
|||
type ProofWithPublicInputs struct { |
|||
Proof Proof |
|||
PublicInputs []gl.Variable // Length = CommonCircuitData.NumPublicInputs
|
|||
} |
|||
|
|||
type VerifierOnlyCircuitData struct { |
|||
ConstantSigmasCap FriMerkleCap |
|||
CircuitDigest poseidon.BN254HashOut |
|||
} |
|||
|
|||
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 []gl.Variable |
|||
NumPartialProducts uint64 |
|||
} |
@ -0,0 +1,122 @@ |
|||
package types |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"io" |
|||
"os" |
|||
|
|||
"github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" |
|||
) |
|||
|
|||
type CommonCircuitDataRaw struct { |
|||
Config struct { |
|||
NumWires uint64 `json:"num_wires"` |
|||
NumRoutedWires uint64 `json:"num_routed_wires"` |
|||
NumConstants uint64 `json:"num_constants"` |
|||
UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"` |
|||
SecurityBits uint64 `json:"security_bits"` |
|||
NumChallenges uint64 `json:"num_challenges"` |
|||
ZeroKnowledge bool `json:"zero_knowledge"` |
|||
MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"` |
|||
FriConfig struct { |
|||
RateBits uint64 `json:"rate_bits"` |
|||
CapHeight uint64 `json:"cap_height"` |
|||
ProofOfWorkBits uint64 `json:"proof_of_work_bits"` |
|||
ReductionStrategy struct { |
|||
ConstantArityBits []uint64 `json:"ConstantArityBits"` |
|||
} `json:"reduction_strategy"` |
|||
NumQueryRounds uint64 `json:"num_query_rounds"` |
|||
} `json:"fri_config"` |
|||
} `json:"config"` |
|||
FriParams struct { |
|||
Config struct { |
|||
RateBits uint64 `json:"rate_bits"` |
|||
CapHeight uint64 `json:"cap_height"` |
|||
ProofOfWorkBits uint64 `json:"proof_of_work_bits"` |
|||
ReductionStrategy struct { |
|||
ConstantArityBits []uint64 `json:"ConstantArityBits"` |
|||
} `json:"reduction_strategy"` |
|||
NumQueryRounds uint64 `json:"num_query_rounds"` |
|||
} `json:"config"` |
|||
Hiding bool `json:"hiding"` |
|||
DegreeBits uint64 `json:"degree_bits"` |
|||
ReductionArityBits []uint64 `json:"reduction_arity_bits"` |
|||
} `json:"fri_params"` |
|||
Gates []string `json:"gates"` |
|||
SelectorsInfo struct { |
|||
SelectorIndices []uint64 `json:"selector_indices"` |
|||
Groups []struct { |
|||
Start uint64 `json:"start"` |
|||
End uint64 `json:"end"` |
|||
} `json:"groups"` |
|||
} `json:"selectors_info"` |
|||
QuotientDegreeFactor uint64 `json:"quotient_degree_factor"` |
|||
NumGateConstraints uint64 `json:"num_gate_constraints"` |
|||
NumConstants uint64 `json:"num_constants"` |
|||
NumPublicInputs uint64 `json:"num_public_inputs"` |
|||
KIs []uint64 `json:"k_is"` |
|||
NumPartialProducts uint64 `json:"num_partial_products"` |
|||
} |
|||
|
|||
func ReadCommonCircuitData(path string) CommonCircuitData { |
|||
jsonFile, err := os.Open(path) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
defer jsonFile.Close() |
|||
rawBytes, _ := io.ReadAll(jsonFile) |
|||
|
|||
var raw CommonCircuitDataRaw |
|||
err = json.Unmarshal(rawBytes, &raw) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
var commonCircuitData CommonCircuitData |
|||
commonCircuitData.Config.NumWires = raw.Config.NumWires |
|||
commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires |
|||
commonCircuitData.Config.NumConstants = raw.Config.NumConstants |
|||
commonCircuitData.Config.UseBaseArithmeticGate = raw.Config.UseBaseArithmeticGate |
|||
commonCircuitData.Config.SecurityBits = raw.Config.SecurityBits |
|||
commonCircuitData.Config.NumChallenges = raw.Config.NumChallenges |
|||
commonCircuitData.Config.ZeroKnowledge = raw.Config.ZeroKnowledge |
|||
commonCircuitData.Config.MaxQuotientDegreeFactor = raw.Config.MaxQuotientDegreeFactor |
|||
|
|||
commonCircuitData.Config.FriConfig.RateBits = raw.Config.FriConfig.RateBits |
|||
commonCircuitData.Config.FriConfig.CapHeight = raw.Config.FriConfig.CapHeight |
|||
commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits |
|||
commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds |
|||
|
|||
commonCircuitData.FriParams.DegreeBits = raw.FriParams.DegreeBits |
|||
commonCircuitData.DegreeBits = raw.FriParams.DegreeBits |
|||
commonCircuitData.FriParams.Config.RateBits = raw.FriParams.Config.RateBits |
|||
commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight |
|||
commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits |
|||
commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds |
|||
commonCircuitData.FriParams.ReductionArityBits = raw.FriParams.ReductionArityBits |
|||
|
|||
commonCircuitData.GateIds = raw.Gates |
|||
|
|||
selectorGroupStart := []uint64{} |
|||
selectorGroupEnd := []uint64{} |
|||
for _, group := range raw.SelectorsInfo.Groups { |
|||
selectorGroupStart = append(selectorGroupStart, group.Start) |
|||
selectorGroupEnd = append(selectorGroupEnd, group.End) |
|||
} |
|||
|
|||
commonCircuitData.SelectorsInfo = *gates.NewSelectorsInfo( |
|||
raw.SelectorsInfo.SelectorIndices, |
|||
selectorGroupStart, |
|||
selectorGroupEnd, |
|||
) |
|||
|
|||
commonCircuitData.QuotientDegreeFactor = raw.QuotientDegreeFactor |
|||
commonCircuitData.NumGateConstraints = raw.NumGateConstraints |
|||
commonCircuitData.NumConstants = raw.NumConstants |
|||
commonCircuitData.NumPublicInputs = raw.NumPublicInputs |
|||
commonCircuitData.KIs = raw.KIs |
|||
commonCircuitData.NumPartialProducts = raw.NumPartialProducts |
|||
|
|||
return commonCircuitData |
|||
} |
@ -0,0 +1,9 @@ |
|||
package types |
|||
|
|||
import ( |
|||
"testing" |
|||
) |
|||
|
|||
func TestReadCommonCircuitData(t *testing.T) { |
|||
ReadCommonCircuitData("../testdata/decode_block/common_circuit_data.json") |
|||
} |
@ -0,0 +1,126 @@ |
|||
package types |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"io" |
|||
"os" |
|||
) |
|||
|
|||
type ProofWithPublicInputsRaw struct { |
|||
Proof struct { |
|||
WiresCap []string `json:"wires_cap"` |
|||
PlonkZsPartialProductsCap []string `json:"plonk_zs_partial_products_cap"` |
|||
QuotientPolysCap []string `json:"quotient_polys_cap"` |
|||
Openings struct { |
|||
Constants [][]uint64 `json:"constants"` |
|||
PlonkSigmas [][]uint64 `json:"plonk_sigmas"` |
|||
Wires [][]uint64 `json:"wires"` |
|||
PlonkZs [][]uint64 `json:"plonk_zs"` |
|||
PlonkZsNext [][]uint64 `json:"plonk_zs_next"` |
|||
PartialProducts [][]uint64 `json:"partial_products"` |
|||
QuotientPolys [][]uint64 `json:"quotient_polys"` |
|||
} `json:"openings"` |
|||
OpeningProof struct { |
|||
CommitPhaseMerkleCaps [][]string `json:"commit_phase_merkle_caps"` |
|||
QueryRoundProofs []struct { |
|||
InitialTreesProof struct { |
|||
EvalsProofs []EvalProofRaw `json:"evals_proofs"` |
|||
} `json:"initial_trees_proof"` |
|||
Steps []struct { |
|||
Evals [][]uint64 `json:"evals"` |
|||
MerkleProof struct { |
|||
Siblings []string `json:"siblings"` |
|||
} `json:"merkle_proof"` |
|||
} `json:"steps"` |
|||
} `json:"query_round_proofs"` |
|||
FinalPoly struct { |
|||
Coeffs [][]uint64 `json:"coeffs"` |
|||
} `json:"final_poly"` |
|||
PowWitness uint64 `json:"pow_witness"` |
|||
} `json:"opening_proof"` |
|||
} `json:"proof"` |
|||
PublicInputs []uint64 `json:"public_inputs"` |
|||
} |
|||
|
|||
type EvalProofRaw struct { |
|||
LeafElements []uint64 |
|||
MerkleProof MerkleProofRaw |
|||
} |
|||
|
|||
func (e *EvalProofRaw) UnmarshalJSON(data []byte) error { |
|||
return json.Unmarshal(data, &[]interface{}{&e.LeafElements, &e.MerkleProof}) |
|||
} |
|||
|
|||
type MerkleProofRaw struct { |
|||
Hash []string |
|||
} |
|||
|
|||
func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error { |
|||
type SiblingObject struct { |
|||
Siblings []string // "siblings"
|
|||
} |
|||
|
|||
var siblings SiblingObject |
|||
if err := json.Unmarshal(data, &siblings); err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
m.Hash = make([]string, len(siblings.Siblings)) |
|||
copy(m.Hash[:], siblings.Siblings) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
type ProofChallengesRaw struct { |
|||
PlonkBetas []uint64 `json:"plonk_betas"` |
|||
PlonkGammas []uint64 `json:"plonk_gammas"` |
|||
PlonkAlphas []uint64 `json:"plonk_alphas"` |
|||
PlonkZeta []uint64 `json:"plonk_zeta"` |
|||
FriChallenges struct { |
|||
FriAlpha []uint64 `json:"fri_alpha"` |
|||
FriBetas [][]uint64 `json:"fri_betas"` |
|||
FriPowResponse uint64 `json:"fri_pow_response"` |
|||
FriQueryIndices []uint64 `json:"fri_query_indices"` |
|||
} `json:"fri_challenges"` |
|||
} |
|||
|
|||
type VerifierOnlyCircuitDataRaw struct { |
|||
ConstantsSigmasCap []string `json:"constants_sigmas_cap"` |
|||
CircuitDigest string `json:"circuit_digest"` |
|||
} |
|||
|
|||
func ReadProofWithPublicInputs(path string) ProofWithPublicInputsRaw { |
|||
jsonFile, err := os.Open(path) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
defer jsonFile.Close() |
|||
rawBytes, _ := io.ReadAll(jsonFile) |
|||
|
|||
var raw ProofWithPublicInputsRaw |
|||
err = json.Unmarshal(rawBytes, &raw) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
return raw |
|||
} |
|||
|
|||
func ReadVerifierOnlyCircuitData(path string) VerifierOnlyCircuitDataRaw { |
|||
jsonFile, err := os.Open(path) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
defer jsonFile.Close() |
|||
rawBytes, _ := io.ReadAll(jsonFile) |
|||
|
|||
var raw VerifierOnlyCircuitDataRaw |
|||
err = json.Unmarshal(rawBytes, &raw) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
return raw |
|||
} |
@ -0,0 +1,13 @@ |
|||
package types |
|||
|
|||
import ( |
|||
"testing" |
|||
) |
|||
|
|||
func TestReadProofWithPublicInputs(t *testing.T) { |
|||
ReadProofWithPublicInputs("../testdata/decode_block/proof_with_public_inputs.json") |
|||
} |
|||
|
|||
func TestReadVerifierOnlyCircuitData(t *testing.T) { |
|||
ReadVerifierOnlyCircuitData("../testdata/decode_block/verifier_only_circuit_data.json") |
|||
} |
@ -0,0 +1,48 @@ |
|||
package types |
|||
|
|||
import "github.com/succinctlabs/gnark-plonky2-verifier/plonk/gates" |
|||
|
|||
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 |
|||
} |
|||
|
|||
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 |
|||
GateIds []string |
|||
SelectorsInfo gates.SelectorsInfo |
|||
DegreeBits uint64 |
|||
QuotientDegreeFactor uint64 |
|||
NumGateConstraints uint64 |
|||
NumConstants uint64 |
|||
NumPublicInputs uint64 |
|||
KIs []uint64 |
|||
NumPartialProducts uint64 |
|||
} |
@ -0,0 +1,21 @@ |
|||
package types |
|||
|
|||
func ReductionArityBits( |
|||
arityBits uint64, |
|||
finalPolyBits uint64, |
|||
degreeBits uint64, |
|||
rateBits uint64, |
|||
capHeight uint64, |
|||
) []uint64 { |
|||
returnArr := make([]uint64, 0) |
|||
|
|||
for degreeBits > finalPolyBits && degreeBits+rateBits-arityBits >= capHeight { |
|||
returnArr = append(returnArr, arityBits) |
|||
if degreeBits < arityBits { |
|||
panic("degreeBits < arityBits") |
|||
} |
|||
degreeBits -= arityBits |
|||
} |
|||
|
|||
return returnArr |
|||
} |
@ -0,0 +1,24 @@ |
|||
package variables |
|||
|
|||
import ( |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
) |
|||
|
|||
type Proof struct { |
|||
WiresCap FriMerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
|||
PlonkZsPartialProductsCap FriMerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
|||
QuotientPolysCap FriMerkleCap // length = 2^CircuitConfig.FriConfig.CapHeight
|
|||
Openings OpeningSet |
|||
OpeningProof FriProof |
|||
} |
|||
|
|||
type ProofWithPublicInputs struct { |
|||
Proof Proof |
|||
PublicInputs []gl.Variable // Length = CommonCircuitData.NumPublicInputs
|
|||
} |
|||
|
|||
type VerifierOnlyCircuitData struct { |
|||
ConstantSigmasCap FriMerkleCap |
|||
CircuitDigest poseidon.BN254HashOut |
|||
} |
@ -0,0 +1,156 @@ |
|||
package variables |
|||
|
|||
import ( |
|||
"math/big" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/types" |
|||
) |
|||
|
|||
func DeserializeMerkleCap(merkleCapRaw []string) FriMerkleCap { |
|||
n := len(merkleCapRaw) |
|||
merkleCap := make([]poseidon.BN254HashOut, n) |
|||
for i := 0; i < n; i++ { |
|||
capBigInt, _ := new(big.Int).SetString(merkleCapRaw[i], 10) |
|||
merkleCap[i] = frontend.Variable(capBigInt) |
|||
} |
|||
return merkleCap |
|||
} |
|||
|
|||
func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) FriMerkleProof { |
|||
n := len(merkleProofRaw.Siblings) |
|||
var mp FriMerkleProof |
|||
mp.Siblings = make([]poseidon.BN254HashOut, n) |
|||
for i := 0; i < n; i++ { |
|||
element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 }) |
|||
mp.Siblings[i] = gl.Uint64ArrayToVariableArray(element.Elements) |
|||
} |
|||
return mp |
|||
} |
|||
|
|||
func DeserializeOpeningSet(openingSetRaw struct { |
|||
Constants [][]uint64 |
|||
PlonkSigmas [][]uint64 |
|||
Wires [][]uint64 |
|||
PlonkZs [][]uint64 |
|||
PlonkZsNext [][]uint64 |
|||
PartialProducts [][]uint64 |
|||
QuotientPolys [][]uint64 |
|||
}) OpeningSet { |
|||
return 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 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.BN254HashOut(hashVar)) |
|||
} |
|||
|
|||
return hashes |
|||
} |
|||
|
|||
func DeserializeFriProof(openingProofRaw struct { |
|||
CommitPhaseMerkleCaps [][]string |
|||
QueryRoundProofs []struct { |
|||
InitialTreesProof struct { |
|||
EvalsProofs []types.EvalProofRaw |
|||
} |
|||
Steps []struct { |
|||
Evals [][]uint64 |
|||
MerkleProof struct { |
|||
Siblings []string |
|||
} |
|||
} |
|||
} |
|||
FinalPoly struct { |
|||
Coeffs [][]uint64 |
|||
} |
|||
PowWitness uint64 |
|||
}) FriProof { |
|||
var openingProof FriProof |
|||
openingProof.PowWitness = gl.NewVariable(openingProofRaw.PowWitness) |
|||
openingProof.FinalPoly.Coeffs = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs) |
|||
|
|||
openingProof.CommitPhaseMerkleCaps = make([]FriMerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps)) |
|||
for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ { |
|||
openingProof.CommitPhaseMerkleCaps[i] = StringArrayToHashBN254Array(openingProofRaw.CommitPhaseMerkleCaps[i]) |
|||
} |
|||
|
|||
numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs) |
|||
openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs) |
|||
|
|||
for i := 0; i < numQueryRoundProofs; i++ { |
|||
numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs) |
|||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]FriEvalProof, numEvalProofs) |
|||
for j := 0; j < numEvalProofs; j++ { |
|||
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([]FriQueryStep, numSteps) |
|||
for j := 0; j < numSteps; j++ { |
|||
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(raw types.ProofWithPublicInputsRaw) ProofWithPublicInputs { |
|||
var proofWithPis ProofWithPublicInputs |
|||
proofWithPis.Proof.WiresCap = DeserializeMerkleCap(raw.Proof.WiresCap) |
|||
proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap(raw.Proof.PlonkZsPartialProductsCap) |
|||
proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap(raw.Proof.QuotientPolysCap) |
|||
proofWithPis.Proof.Openings = DeserializeOpeningSet(struct { |
|||
Constants [][]uint64 |
|||
PlonkSigmas [][]uint64 |
|||
Wires [][]uint64 |
|||
PlonkZs [][]uint64 |
|||
PlonkZsNext [][]uint64 |
|||
PartialProducts [][]uint64 |
|||
QuotientPolys [][]uint64 |
|||
}(raw.Proof.Openings)) |
|||
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct { |
|||
CommitPhaseMerkleCaps [][]string |
|||
QueryRoundProofs []struct { |
|||
InitialTreesProof struct { |
|||
EvalsProofs []types.EvalProofRaw |
|||
} |
|||
Steps []struct { |
|||
Evals [][]uint64 |
|||
MerkleProof struct { |
|||
Siblings []string |
|||
} |
|||
} |
|||
} |
|||
FinalPoly struct{ Coeffs [][]uint64 } |
|||
PowWitness uint64 |
|||
}(raw.Proof.OpeningProof)) |
|||
proofWithPis.PublicInputs = gl.Uint64ArrayToVariableArray(raw.PublicInputs) |
|||
|
|||
return proofWithPis |
|||
} |
|||
|
|||
func DeserializeVerifierOnlyCircuitData(raw types.VerifierOnlyCircuitDataRaw) VerifierOnlyCircuitData { |
|||
var verifierOnlyCircuitData VerifierOnlyCircuitData |
|||
verifierOnlyCircuitData.ConstantSigmasCap = DeserializeMerkleCap(raw.ConstantsSigmasCap) |
|||
circuitDigestBigInt, _ := new(big.Int).SetString(raw.CircuitDigest, 10) |
|||
circuitDigestVar := frontend.Variable(circuitDigestBigInt) |
|||
verifierOnlyCircuitData.CircuitDigest = poseidon.BN254HashOut(circuitDigestVar) |
|||
return verifierOnlyCircuitData |
|||
} |
@ -0,0 +1,17 @@ |
|||
package variables |
|||
|
|||
import ( |
|||
"testing" |
|||
|
|||
"github.com/succinctlabs/gnark-plonky2-verifier/types" |
|||
) |
|||
|
|||
func TestDeserializeProofWithPublicInputs(t *testing.T) { |
|||
proofWithPis := DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("../testdata/decode_block/proof_with_public_inputs.json")) |
|||
t.Logf("%+v\n", proofWithPis) |
|||
} |
|||
|
|||
func TestDeserializeVerifierOnlyCircuitData(t *testing.T) { |
|||
verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("../testdata/decode_block/verifier_only_circuit_data.json")) |
|||
t.Logf("%+v\n", verifierOnlyCircuitData) |
|||
} |
@ -1,4 +1,4 @@ |
|||
package types |
|||
package variables |
|||
|
|||
import gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
|
@ -1,435 +0,0 @@ |
|||
package verifier |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"io" |
|||
"math/big" |
|||
"os" |
|||
|
|||
"github.com/consensys/gnark/frontend" |
|||
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/types" |
|||
) |
|||
|
|||
type ProofWithPublicInputsRaw struct { |
|||
Proof struct { |
|||
WiresCap []string `json:"wires_cap"` |
|||
PlonkZsPartialProductsCap []string `json:"plonk_zs_partial_products_cap"` |
|||
QuotientPolysCap []string `json:"quotient_polys_cap"` |
|||
Openings struct { |
|||
Constants [][]uint64 `json:"constants"` |
|||
PlonkSigmas [][]uint64 `json:"plonk_sigmas"` |
|||
Wires [][]uint64 `json:"wires"` |
|||
PlonkZs [][]uint64 `json:"plonk_zs"` |
|||
PlonkZsNext [][]uint64 `json:"plonk_zs_next"` |
|||
PartialProducts [][]uint64 `json:"partial_products"` |
|||
QuotientPolys [][]uint64 `json:"quotient_polys"` |
|||
} `json:"openings"` |
|||
OpeningProof struct { |
|||
CommitPhaseMerkleCaps [][]string `json:"commit_phase_merkle_caps"` |
|||
QueryRoundProofs []struct { |
|||
InitialTreesProof struct { |
|||
EvalsProofs []EvalProofRaw `json:"evals_proofs"` |
|||
} `json:"initial_trees_proof"` |
|||
Steps []struct { |
|||
Evals [][]uint64 `json:"evals"` |
|||
MerkleProof struct { |
|||
Siblings []string `json:"siblings"` |
|||
} `json:"merkle_proof"` |
|||
} `json:"steps"` |
|||
} `json:"query_round_proofs"` |
|||
FinalPoly struct { |
|||
Coeffs [][]uint64 `json:"coeffs"` |
|||
} `json:"final_poly"` |
|||
PowWitness uint64 `json:"pow_witness"` |
|||
} `json:"opening_proof"` |
|||
} `json:"proof"` |
|||
PublicInputs []uint64 `json:"public_inputs"` |
|||
} |
|||
|
|||
type EvalProofRaw struct { |
|||
LeafElements []uint64 |
|||
MerkleProof MerkleProofRaw |
|||
} |
|||
|
|||
func (e *EvalProofRaw) UnmarshalJSON(data []byte) error { |
|||
return json.Unmarshal(data, &[]interface{}{&e.LeafElements, &e.MerkleProof}) |
|||
} |
|||
|
|||
type MerkleProofRaw struct { |
|||
Hash []string |
|||
} |
|||
|
|||
func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error { |
|||
type SiblingObject struct { |
|||
Siblings []string // "siblings"
|
|||
} |
|||
|
|||
var siblings SiblingObject |
|||
if err := json.Unmarshal(data, &siblings); err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
m.Hash = make([]string, len(siblings.Siblings)) |
|||
copy(m.Hash[:], siblings.Siblings) |
|||
|
|||
return nil |
|||
} |
|||
|
|||
type CommonCircuitDataRaw struct { |
|||
Config struct { |
|||
NumWires uint64 `json:"num_wires"` |
|||
NumRoutedWires uint64 `json:"num_routed_wires"` |
|||
NumConstants uint64 `json:"num_constants"` |
|||
UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"` |
|||
SecurityBits uint64 `json:"security_bits"` |
|||
NumChallenges uint64 `json:"num_challenges"` |
|||
ZeroKnowledge bool `json:"zero_knowledge"` |
|||
MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"` |
|||
FriConfig struct { |
|||
RateBits uint64 `json:"rate_bits"` |
|||
CapHeight uint64 `json:"cap_height"` |
|||
ProofOfWorkBits uint64 `json:"proof_of_work_bits"` |
|||
ReductionStrategy struct { |
|||
ConstantArityBits []uint64 `json:"ConstantArityBits"` |
|||
} `json:"reduction_strategy"` |
|||
NumQueryRounds uint64 `json:"num_query_rounds"` |
|||
} `json:"fri_config"` |
|||
} `json:"config"` |
|||
FriParams struct { |
|||
Config struct { |
|||
RateBits uint64 `json:"rate_bits"` |
|||
CapHeight uint64 `json:"cap_height"` |
|||
ProofOfWorkBits uint64 `json:"proof_of_work_bits"` |
|||
ReductionStrategy struct { |
|||
ConstantArityBits []uint64 `json:"ConstantArityBits"` |
|||
} `json:"reduction_strategy"` |
|||
NumQueryRounds uint64 `json:"num_query_rounds"` |
|||
} `json:"config"` |
|||
Hiding bool `json:"hiding"` |
|||
DegreeBits uint64 `json:"degree_bits"` |
|||
ReductionArityBits []uint64 `json:"reduction_arity_bits"` |
|||
} `json:"fri_params"` |
|||
Gates []string `json:"gates"` |
|||
SelectorsInfo struct { |
|||
SelectorIndices []uint64 `json:"selector_indices"` |
|||
Groups []struct { |
|||
Start uint64 `json:"start"` |
|||
End uint64 `json:"end"` |
|||
} `json:"groups"` |
|||
} `json:"selectors_info"` |
|||
QuotientDegreeFactor uint64 `json:"quotient_degree_factor"` |
|||
NumGateConstraints uint64 `json:"num_gate_constraints"` |
|||
NumConstants uint64 `json:"num_constants"` |
|||
NumPublicInputs uint64 `json:"num_public_inputs"` |
|||
KIs []uint64 `json:"k_is"` |
|||
NumPartialProducts uint64 `json:"num_partial_products"` |
|||
} |
|||
|
|||
type ProofChallengesRaw struct { |
|||
PlonkBetas []uint64 `json:"plonk_betas"` |
|||
PlonkGammas []uint64 `json:"plonk_gammas"` |
|||
PlonkAlphas []uint64 `json:"plonk_alphas"` |
|||
PlonkZeta []uint64 `json:"plonk_zeta"` |
|||
FriChallenges struct { |
|||
FriAlpha []uint64 `json:"fri_alpha"` |
|||
FriBetas [][]uint64 `json:"fri_betas"` |
|||
FriPowResponse uint64 `json:"fri_pow_response"` |
|||
FriQueryIndices []uint64 `json:"fri_query_indices"` |
|||
} `json:"fri_challenges"` |
|||
} |
|||
|
|||
type VerifierOnlyCircuitDataRaw struct { |
|||
ConstantsSigmasCap []string `json:"constants_sigmas_cap"` |
|||
CircuitDigest string `json:"circuit_digest"` |
|||
} |
|||
|
|||
func DeserializeMerkleCap(merkleCapRaw []string) types.FriMerkleCap { |
|||
n := len(merkleCapRaw) |
|||
merkleCap := make([]poseidon.BN254HashOut, n) |
|||
for i := 0; i < n; i++ { |
|||
capBigInt, _ := new(big.Int).SetString(merkleCapRaw[i], 10) |
|||
merkleCap[i] = frontend.Variable(capBigInt) |
|||
} |
|||
return merkleCap |
|||
} |
|||
|
|||
func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) types.FriMerkleProof { |
|||
n := len(merkleProofRaw.Siblings) |
|||
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] = gl.Uint64ArrayToVariableArray(element.Elements) |
|||
} |
|||
return mp |
|||
} |
|||
|
|||
func DeserializeOpeningSet(openingSetRaw struct { |
|||
Constants [][]uint64 |
|||
PlonkSigmas [][]uint64 |
|||
Wires [][]uint64 |
|||
PlonkZs [][]uint64 |
|||
PlonkZsNext [][]uint64 |
|||
PartialProducts [][]uint64 |
|||
QuotientPolys [][]uint64 |
|||
}) 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 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.BN254HashOut(hashVar)) |
|||
} |
|||
|
|||
return hashes |
|||
} |
|||
|
|||
func DeserializeFriProof(openingProofRaw struct { |
|||
CommitPhaseMerkleCaps [][]string |
|||
QueryRoundProofs []struct { |
|||
InitialTreesProof struct { |
|||
EvalsProofs []EvalProofRaw |
|||
} |
|||
Steps []struct { |
|||
Evals [][]uint64 |
|||
MerkleProof struct { |
|||
Siblings []string |
|||
} |
|||
} |
|||
} |
|||
FinalPoly struct { |
|||
Coeffs [][]uint64 |
|||
} |
|||
PowWitness uint64 |
|||
}) types.FriProof { |
|||
var openingProof types.FriProof |
|||
openingProof.PowWitness = gl.NewVariable(openingProofRaw.PowWitness) |
|||
openingProof.FinalPoly.Coeffs = gl.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs) |
|||
|
|||
openingProof.CommitPhaseMerkleCaps = make([]types.FriMerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps)) |
|||
for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ { |
|||
openingProof.CommitPhaseMerkleCaps[i] = StringArrayToHashBN254Array(openingProofRaw.CommitPhaseMerkleCaps[i]) |
|||
} |
|||
|
|||
numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs) |
|||
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([]types.FriEvalProof, numEvalProofs) |
|||
for j := 0; j < numEvalProofs; j++ { |
|||
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([]types.FriQueryStep, numSteps) |
|||
for j := 0; j < numSteps; j++ { |
|||
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) types.ProofWithPublicInputs { |
|||
jsonFile, err := os.Open(path) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
defer jsonFile.Close() |
|||
rawBytes, _ := io.ReadAll(jsonFile) |
|||
|
|||
var raw ProofWithPublicInputsRaw |
|||
err = json.Unmarshal(rawBytes, &raw) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
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) |
|||
proofWithPis.Proof.Openings = DeserializeOpeningSet(struct { |
|||
Constants [][]uint64 |
|||
PlonkSigmas [][]uint64 |
|||
Wires [][]uint64 |
|||
PlonkZs [][]uint64 |
|||
PlonkZsNext [][]uint64 |
|||
PartialProducts [][]uint64 |
|||
QuotientPolys [][]uint64 |
|||
}(raw.Proof.Openings)) |
|||
proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct { |
|||
CommitPhaseMerkleCaps [][]string |
|||
QueryRoundProofs []struct { |
|||
InitialTreesProof struct { |
|||
EvalsProofs []EvalProofRaw |
|||
} |
|||
Steps []struct { |
|||
Evals [][]uint64 |
|||
MerkleProof struct { |
|||
Siblings []string |
|||
} |
|||
} |
|||
} |
|||
FinalPoly struct{ Coeffs [][]uint64 } |
|||
PowWitness uint64 |
|||
}(raw.Proof.OpeningProof)) |
|||
proofWithPis.PublicInputs = gl.Uint64ArrayToVariableArray(raw.PublicInputs) |
|||
|
|||
return proofWithPis |
|||
} |
|||
|
|||
func DeserializeProofChallenges(path string) types.ProofChallenges { |
|||
jsonFile, err := os.Open(path) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
defer jsonFile.Close() |
|||
rawBytes, _ := io.ReadAll(jsonFile) |
|||
|
|||
var raw ProofChallengesRaw |
|||
err = json.Unmarshal(rawBytes, &raw) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
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 |
|||
} |
|||
|
|||
func ReductionArityBits( |
|||
arityBits uint64, |
|||
finalPolyBits uint64, |
|||
degreeBits uint64, |
|||
rateBits uint64, |
|||
capHeight uint64, |
|||
) []uint64 { |
|||
returnArr := make([]uint64, 0) |
|||
|
|||
for degreeBits > finalPolyBits && degreeBits+rateBits-arityBits >= capHeight { |
|||
returnArr = append(returnArr, arityBits) |
|||
if degreeBits < arityBits { |
|||
panic("degreeBits < arityBits") |
|||
} |
|||
degreeBits -= arityBits |
|||
} |
|||
|
|||
return returnArr |
|||
} |
|||
|
|||
func DeserializeCommonCircuitData(path string) types.CommonCircuitData { |
|||
jsonFile, err := os.Open(path) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
defer jsonFile.Close() |
|||
rawBytes, _ := io.ReadAll(jsonFile) |
|||
|
|||
var raw CommonCircuitDataRaw |
|||
err = json.Unmarshal(rawBytes, &raw) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
var commonCircuitData types.CommonCircuitData |
|||
commonCircuitData.Config.NumWires = raw.Config.NumWires |
|||
commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires |
|||
commonCircuitData.Config.NumConstants = raw.Config.NumConstants |
|||
commonCircuitData.Config.UseBaseArithmeticGate = raw.Config.UseBaseArithmeticGate |
|||
commonCircuitData.Config.SecurityBits = raw.Config.SecurityBits |
|||
commonCircuitData.Config.NumChallenges = raw.Config.NumChallenges |
|||
commonCircuitData.Config.ZeroKnowledge = raw.Config.ZeroKnowledge |
|||
commonCircuitData.Config.MaxQuotientDegreeFactor = raw.Config.MaxQuotientDegreeFactor |
|||
|
|||
commonCircuitData.Config.FriConfig.RateBits = raw.Config.FriConfig.RateBits |
|||
commonCircuitData.Config.FriConfig.CapHeight = raw.Config.FriConfig.CapHeight |
|||
commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits |
|||
commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds |
|||
|
|||
commonCircuitData.FriParams.DegreeBits = raw.FriParams.DegreeBits |
|||
commonCircuitData.DegreeBits = raw.FriParams.DegreeBits |
|||
commonCircuitData.FriParams.Config.RateBits = raw.FriParams.Config.RateBits |
|||
commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight |
|||
commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits |
|||
commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds |
|||
commonCircuitData.FriParams.ReductionArityBits = raw.FriParams.ReductionArityBits |
|||
|
|||
commonCircuitData.Gates = []gates.Gate{} |
|||
for _, gate := range raw.Gates { |
|||
commonCircuitData.Gates = append(commonCircuitData.Gates, gates.GateInstanceFromId(gate)) |
|||
} |
|||
|
|||
selectorGroupStart := []uint64{} |
|||
selectorGroupEnd := []uint64{} |
|||
for _, group := range raw.SelectorsInfo.Groups { |
|||
selectorGroupStart = append(selectorGroupStart, group.Start) |
|||
selectorGroupEnd = append(selectorGroupEnd, group.End) |
|||
} |
|||
|
|||
commonCircuitData.SelectorsInfo = *gates.NewSelectorsInfo( |
|||
raw.SelectorsInfo.SelectorIndices, |
|||
selectorGroupStart, |
|||
selectorGroupEnd, |
|||
) |
|||
|
|||
commonCircuitData.QuotientDegreeFactor = raw.QuotientDegreeFactor |
|||
commonCircuitData.NumGateConstraints = raw.NumGateConstraints |
|||
commonCircuitData.NumConstants = raw.NumConstants |
|||
commonCircuitData.NumPublicInputs = raw.NumPublicInputs |
|||
commonCircuitData.KIs = gl.Uint64ArrayToVariableArray(raw.KIs) |
|||
commonCircuitData.NumPartialProducts = raw.NumPartialProducts |
|||
|
|||
return commonCircuitData |
|||
} |
|||
|
|||
func DeserializeVerifierOnlyCircuitData(path string) types.VerifierOnlyCircuitData { |
|||
jsonFile, err := os.Open(path) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
defer jsonFile.Close() |
|||
rawBytes, _ := io.ReadAll(jsonFile) |
|||
|
|||
var raw VerifierOnlyCircuitDataRaw |
|||
err = json.Unmarshal(rawBytes, &raw) |
|||
if err != nil { |
|||
panic(err) |
|||
} |
|||
|
|||
var verifierOnlyCircuitData types.VerifierOnlyCircuitData |
|||
verifierOnlyCircuitData.ConstantSigmasCap = DeserializeMerkleCap(raw.ConstantsSigmasCap) |
|||
circuitDigestBigInt, _ := new(big.Int).SetString(raw.CircuitDigest, 10) |
|||
circuitDigestVar := frontend.Variable(circuitDigestBigInt) |
|||
verifierOnlyCircuitData.CircuitDigest = poseidon.BN254HashOut(circuitDigestVar) |
|||
return verifierOnlyCircuitData |
|||
} |
@ -1,24 +0,0 @@ |
|||
package verifier |
|||
|
|||
import ( |
|||
"fmt" |
|||
"testing" |
|||
) |
|||
|
|||
func TestDeserializeProofWithPublicInputs(t *testing.T) { |
|||
proofWithPis := DeserializeProofWithPublicInputs("../data/decode_block/proof_with_public_inputs.json") |
|||
fmt.Printf("%+v\n", proofWithPis) |
|||
panic("look at stdout") |
|||
} |
|||
|
|||
func TestDeserializeCommonCircuitData(t *testing.T) { |
|||
commonCircuitData := DeserializeCommonCircuitData("../data/decode_block/common_circuit_data.json") |
|||
fmt.Printf("%+v\n", commonCircuitData) |
|||
panic("look at stdout") |
|||
} |
|||
|
|||
func TestDeserializeVerifierOnlyCircuitData(t *testing.T) { |
|||
verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("../data/decode_block/verifier_only_circuit_data.json") |
|||
fmt.Printf("%+v\n", verifierOnlyCircuitData) |
|||
panic("look at stdout") |
|||
} |
@ -0,0 +1,24 @@ |
|||
package verifier |
|||
|
|||
import ( |
|||
"github.com/consensys/gnark/frontend" |
|||
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/types" |
|||
"github.com/succinctlabs/gnark-plonky2-verifier/variables" |
|||
) |
|||
|
|||
type ExampleVerifierCircuit struct { |
|||
PublicInputs []gl.Variable `gnark:",public"` |
|||
Proof variables.Proof `gnark:"-"` |
|||
VerifierOnlyCircuitData variables.VerifierOnlyCircuitData `gnark:"-"` |
|||
|
|||
// This is configuration for the circuit, it is a constant not a variable
|
|||
CommonCircuitData types.CommonCircuitData |
|||
} |
|||
|
|||
func (c *ExampleVerifierCircuit) Define(api frontend.API) error { |
|||
verifierChip := NewVerifierChip(api, c.CommonCircuitData) |
|||
verifierChip.Verify(c.Proof, c.PublicInputs, c.VerifierOnlyCircuitData) |
|||
|
|||
return nil |
|||
} |