Range check optimizationsmain
@ -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" |
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 |
||||
|
} |