Revert "Range check optimizations"

This commit is contained in:
puma314
2023-10-11 17:39:52 -07:00
committed by GitHub
parent c23b174535
commit 0c677ddd0d
50 changed files with 1146 additions and 1089 deletions

BIN
verifier/data/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,177 @@
{
"config": {
"num_wires": 136,
"num_routed_wires": 80,
"num_constants": 2,
"use_base_arithmetic_gate": true,
"security_bits": 100,
"num_challenges": 2,
"zero_knowledge": false,
"max_quotient_degree_factor": 8,
"fri_config": {
"rate_bits": 3,
"cap_height": 4,
"proof_of_work_bits": 16,
"reduction_strategy": {
"ConstantArityBits": [
4,
5
]
},
"num_query_rounds": 28
}
},
"fri_params": {
"config": {
"rate_bits": 3,
"cap_height": 4,
"proof_of_work_bits": 16,
"reduction_strategy": {
"ConstantArityBits": [
4,
5
]
},
"num_query_rounds": 28
},
"hiding": false,
"degree_bits": 12,
"reduction_arity_bits": [
4,
4
]
},
"gates": [
"NoopGate",
"ConstantGate { num_consts: 2 }",
"PoseidonMdsGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>",
"PublicInputGate",
"BaseSumGate { num_limbs: 63 } + Base: 2",
"ReducingExtensionGate { num_coeffs: 33 }",
"ReducingGate { num_coeffs: 44 }",
"ArithmeticExtensionGate { num_ops: 10 }",
"ArithmeticGate { num_ops: 20 }",
"MulExtensionGate { num_ops: 13 }",
"RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
"CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
"PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
],
"selectors_info": {
"selector_indices": [
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
2,
2
],
"groups": [
{
"start": 0,
"end": 7
},
{
"start": 7,
"end": 11
},
{
"start": 11,
"end": 13
}
]
},
"quotient_degree_factor": 8,
"num_gate_constraints": 123,
"num_constants": 5,
"num_public_inputs": 0,
"k_is": [
1,
7,
49,
343,
2401,
16807,
117649,
823543,
5764801,
40353607,
282475249,
1977326743,
13841287201,
96889010407,
678223072849,
4747561509943,
33232930569601,
232630513987207,
1628413597910449,
11398895185373143,
79792266297612001,
558545864083284007,
3909821048582988049,
8922003270666332022,
7113790686420571191,
12903046666114829695,
16534350385145470581,
5059988279530788141,
16973173887300932666,
8131752794619022736,
1582037354089406189,
11074261478625843323,
3732854072722565977,
7683234439643377518,
16889152938674473984,
7543606154233811962,
15911754940807515092,
701820169165099718,
4912741184155698026,
15942444219675301861,
916645121239607101,
6416515848677249707,
8022122801911579307,
814627405137302186,
5702391835961115302,
3023254712898638472,
2716038920875884983,
565528376716610560,
3958698637016273920,
9264146389699333119,
9508792519651578870,
11221315429317299127,
4762231727562756605,
14888878023524711914,
11988425817600061793,
10132004445542095267,
15583798910550913906,
16852872026783475737,
7289639770996824233,
14133990258148600989,
6704211459967285318,
10035992080941828584,
14911712358349047125,
12148266161370408270,
11250886851934520606,
4969231685883306958,
16337877731768564385,
3684679705892444769,
7346013871832529062,
14528608963998534792,
9466542400916821939,
10925564598174000610,
2691975909559666986,
397087297503084581,
2779611082521592067,
1010533508236560148,
7073734557655921036,
12622653764762278610,
14571600075677612986,
9767480182670369297
],
"num_partial_products": 9
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
{
"constants_sigmas_cap": [
"1499622638644728537774239858053278546400257982434845489329927574295172033326",
"2930852415723089264561622935088329191815636786066772202039928107654951266023",
"14464526654918087476596183134411486973966295253353738267325575394304709517161",
"18983137502540745159803953284357786408225887846069384394220291955925143226141",
"1386895482273961356932873002155159178542488359092693049720219479086930861707",
"14771237880407068338879830535366644743003305760875598132537125639168034999022",
"19702788661528474550894036146582137462836271070153286539426392895353557950694",
"15334727368281990897779779337943379898609200739305205677598255362701124565320",
"21691768748620820719274018448050849816536829760110881140528389629789448704790",
"15262009449532190852183220678787716636953257578372619913911054925901367503449",
"18166082909492900359627895435428332272663141560067836935272838076830554017630",
"10686995103794494099325675278866631156892436169286799401423857508483307145846",
"7660138004813546044706396059680360544539623731113711012915164533145284575301",
"1616448650742704848585620443874003913130079345238283349517269437117477195625",
"5734773590975050772666682899969130545487941904460247131732227238307211841652",
"11959183492303708131395376843823862107323459381741154704909455973421596288592"
],
"circuit_digest": "11532502846882484230992726008257788785937565673229400981185786126842727172973"
}

View File

@@ -0,0 +1,181 @@
{
"config": {
"num_wires": 136,
"num_routed_wires": 80,
"num_constants": 2,
"use_base_arithmetic_gate": true,
"security_bits": 100,
"num_challenges": 2,
"zero_knowledge": false,
"max_quotient_degree_factor": 8,
"fri_config": {
"rate_bits": 3,
"cap_height": 4,
"proof_of_work_bits": 16,
"reduction_strategy": {
"ConstantArityBits": [
4,
5
]
},
"num_query_rounds": 28
}
},
"fri_params": {
"config": {
"rate_bits": 3,
"cap_height": 4,
"proof_of_work_bits": 16,
"reduction_strategy": {
"ConstantArityBits": [
4,
5
]
},
"num_query_rounds": 28
},
"hiding": false,
"degree_bits": 13,
"reduction_arity_bits": [
4,
4
]
},
"gates": [
"NoopGate",
"PoseidonMdsGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>",
"PublicInputGate",
"BaseSumGate { num_limbs: 63 } + Base: 2",
"ReducingExtensionGate { num_coeffs: 33 }",
"ReducingGate { num_coeffs: 44 }",
"ArithmeticExtensionGate { num_ops: 10 }",
"ArithmeticGate { num_ops: 20 }",
"MulExtensionGate { num_ops: 13 }",
"ExponentiationGate { num_power_bits: 67, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
"RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
"CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
"PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
],
"selectors_info": {
"selector_indices": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
2,
2,
3
],
"groups": [
{
"start": 0,
"end": 6
},
{
"start": 6,
"end": 10
},
{
"start": 10,
"end": 12
},
{
"start": 12,
"end": 13
}
]
},
"quotient_degree_factor": 8,
"num_gate_constraints": 123,
"num_constants": 6,
"num_public_inputs": 36,
"k_is": [
1,
7,
49,
343,
2401,
16807,
117649,
823543,
5764801,
40353607,
282475249,
1977326743,
13841287201,
96889010407,
678223072849,
4747561509943,
33232930569601,
232630513987207,
1628413597910449,
11398895185373143,
79792266297612001,
558545864083284007,
3909821048582988049,
8922003270666332022,
7113790686420571191,
12903046666114829695,
16534350385145470581,
5059988279530788141,
16973173887300932666,
8131752794619022736,
1582037354089406189,
11074261478625843323,
3732854072722565977,
7683234439643377518,
16889152938674473984,
7543606154233811962,
15911754940807515092,
701820169165099718,
4912741184155698026,
15942444219675301861,
916645121239607101,
6416515848677249707,
8022122801911579307,
814627405137302186,
5702391835961115302,
3023254712898638472,
2716038920875884983,
565528376716610560,
3958698637016273920,
9264146389699333119,
9508792519651578870,
11221315429317299127,
4762231727562756605,
14888878023524711914,
11988425817600061793,
10132004445542095267,
15583798910550913906,
16852872026783475737,
7289639770996824233,
14133990258148600989,
6704211459967285318,
10035992080941828584,
14911712358349047125,
12148266161370408270,
11250886851934520606,
4969231685883306958,
16337877731768564385,
3684679705892444769,
7346013871832529062,
14528608963998534792,
9466542400916821939,
10925564598174000610,
2691975909559666986,
397087297503084581,
2779611082521592067,
1010533508236560148,
7073734557655921036,
12622653764762278610,
14571600075677612986,
9767480182670369297
],
"num_partial_products": 9
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
{
"constants_sigmas_cap": [
"4888357664296095718815758214440529393197762742365942012680717414927848556250",
"2209889448564462812608523791037999221131777281114110816711594808561629780010",
"4783027344594415431544036887584741450494432097097254847851160629277658732206",
"4025442984048235715703510356530005233167222504995885323997325327626847831042",
"7679520709262245108039166177805990311158829589366423240361001467027112647002",
"259363173405031877757571220908459576335668352861939433815090635029846220068",
"9880831542852849450717059869965520165948874814070335576566589765688426595600",
"19609124362176622223995417422711340578268398995610264736162079735652393008400",
"18373537388333609703859974831390403366607123416158043829042438107680621738551",
"17536955898347982953188585924984008856280005516232467427210505109184726402603",
"20695699955262630796033618899800264428111620406754391130684131882592523541095",
"20425708078899059362884835312568041888084734960481059866199231046085670179583",
"21697157774348170912700991744618658990139755973310165730160978582032237849079",
"7191613656222346675951718107316884243893764070036349498195400843757810414364",
"1499065111965288526081286015186615004571723160296680783059214594047760640474",
"5981619154302533357157777495393724169720902362468159062002824290823005959648"
],
"circuit_digest": "9263530673647634796487329488695915977644330282170255272053971232639965244017"
}

435
verifier/deserialize.go Normal file
View File

@@ -0,0 +1,435 @@
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
}

View File

@@ -0,0 +1,24 @@
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")
}

View File

@@ -1,24 +0,0 @@
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
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/succinctlabs/gnark-plonky2-verifier/plonk"
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
"github.com/succinctlabs/gnark-plonky2-verifier/types"
"github.com/succinctlabs/gnark-plonky2-verifier/variables"
)
type VerifierChip struct {
@@ -18,12 +17,11 @@ type VerifierChip struct {
poseidonBN254Chip *poseidon.BN254Chip `gnark:"-"`
plonkChip *plonk.PlonkChip `gnark:"-"`
friChip *fri.Chip `gnark:"-"`
commonData types.CommonCircuitData `gnark:"-"`
}
func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData) *VerifierChip {
glChip := gl.New(api)
friChip := fri.NewChip(api, &commonCircuitData, &commonCircuitData.FriParams)
glChip := gl.NewChip(api)
friChip := fri.NewChip(api, &commonCircuitData.FriParams)
plonkChip := plonk.NewPlonkChip(api, commonCircuitData)
poseidonGlChip := poseidon.NewGoldilocksChip(api)
poseidonBN254Chip := poseidon.NewBN254Chip(api)
@@ -34,7 +32,6 @@ func NewVerifierChip(api frontend.API, commonCircuitData types.CommonCircuitData
poseidonBN254Chip: poseidonBN254Chip,
plonkChip: plonkChip,
friChip: friChip,
commonData: commonCircuitData,
}
}
@@ -43,11 +40,12 @@ func (c *VerifierChip) GetPublicInputsHash(publicInputs []gl.Variable) poseidon.
}
func (c *VerifierChip) GetChallenges(
proof variables.Proof,
proof types.Proof,
publicInputsHash poseidon.GoldilocksHashOut,
verifierData variables.VerifierOnlyCircuitData,
) variables.ProofChallenges {
config := c.commonData.Config
commonData types.CommonCircuitData,
verifierData types.VerifierOnlyCircuitData,
) types.ProofChallenges {
config := commonData.Config
numChallenges := config.NumChallenges
challenger := challenger.NewChip(c.api)
@@ -65,9 +63,9 @@ func (c *VerifierChip) GetChallenges(
challenger.ObserveCap(proof.QuotientPolysCap)
plonkZeta := challenger.GetExtensionChallenge()
challenger.ObserveOpenings(c.friChip.ToOpenings(proof.Openings))
challenger.ObserveOpenings(fri.ToOpenings(proof.Openings))
return variables.ProofChallenges{
return types.ProofChallenges{
PlonkBetas: plonkBetas,
PlonkGammas: plonkGammas,
PlonkAlphas: plonkAlphas,
@@ -76,13 +74,80 @@ func (c *VerifierChip) GetChallenges(
proof.OpeningProof.CommitPhaseMerkleCaps,
proof.OpeningProof.FinalPoly,
proof.OpeningProof.PowWitness,
c.commonData.DegreeBits,
commonData.DegreeBits,
config.FriConfig,
),
}
}
func (c *VerifierChip) rangeCheckProof(proof variables.Proof) {
/*
func (c *VerifierChip) generateProofInput(commonData common.CommonCircuitData) common.ProofWithPublicInputs {
// Generate the parts of the witness that is for the plonky2 proof input
capHeight := commonData.Config.FriConfig.CapHeight
friCommitPhaseMerkleCaps := []common.MerkleCap{}
for i := 0; i < len(commonData.FriParams.ReductionArityBits); i++ {
friCommitPhaseMerkleCaps = append(friCommitPhaseMerkleCaps, common.NewMerkleCap(capHeight))
}
salt := commonData.SaltSize()
numLeavesPerOracle := []uint{
commonData.NumPreprocessedPolys(),
commonData.Config.NumWires + salt,
commonData.NumZsPartialProductsPolys() + salt,
commonData.NumQuotientPolys() + salt,
}
friQueryRoundProofs := []common.FriQueryRound{}
for i := uint64(0); i < commonData.FriParams.Config.NumQueryRounds; i++ {
evalProofs := []common.EvalProof{}
merkleProofLen := commonData.FriParams.LDEBits() - capHeight
for _, numLeaves := range numLeavesPerOracle {
leaves := make([]field.F, numLeaves)
merkleProof := common.NewMerkleProof(merkleProofLen)
evalProofs = append(evalProofs, common.NewEvalProof(leaves, merkleProof))
}
initialTreesProof := common.NewFriInitialTreeProof(evalProofs)
steps := []common.FriQueryStep{}
for _, arityBit := range commonData.FriParams.ReductionArityBits {
if merkleProofLen < arityBit {
panic("merkleProofLen < arityBits")
}
steps = append(steps, common.NewFriQueryStep(arityBit, merkleProofLen))
}
friQueryRoundProofs = append(friQueryRoundProofs, common.NewFriQueryRound(steps, initialTreesProof))
}
proofInput := common.ProofWithPublicInputs{
Proof: common.Proof{
WiresCap: common.NewMerkleCap(capHeight),
PlonkZsPartialProductsCap: common.NewMerkleCap(capHeight),
QuotientPolysCap: common.NewMerkleCap(capHeight),
Openings: common.NewOpeningSet(
commonData.Config.NumConstants,
commonData.Config.NumRoutedWires,
commonData.Config.NumWires,
commonData.Config.NumChallenges,
commonData.NumPartialProducts,
commonData.QuotientDegreeFactor,
),
OpeningProof: common.FriProof{
CommitPhaseMerkleCaps: friCommitPhaseMerkleCaps,
QueryRoundProofs: friQueryRoundProofs,
FinalPoly: common.NewPolynomialCoeffs(commonData.FriParams.FinalPolyLen()),
},
},
PublicInputs: make([]field.F, commonData.NumPublicInputs),
}
return proofInput
}
*/
func (c *VerifierChip) rangeCheckProof(proof types.Proof) {
// Need to verify the plonky2 proof's openings, openings proof (other than the sibling elements), fri's final poly, pow witness.
// Note that this is NOT range checking the public inputs (first 32 elements should be no more than 8 bits and the last 4 elements should be no more than 64 bits). Since this is currently being inputted via the smart contract,
@@ -140,19 +205,20 @@ func (c *VerifierChip) rangeCheckProof(proof variables.Proof) {
}
func (c *VerifierChip) Verify(
proof variables.Proof,
proof types.Proof,
publicInputs []gl.Variable,
verifierData variables.VerifierOnlyCircuitData,
verifierData types.VerifierOnlyCircuitData,
commonData types.CommonCircuitData,
) {
c.rangeCheckProof(proof)
// Generate the parts of the witness that is for the plonky2 proof input
publicInputsHash := c.GetPublicInputsHash(publicInputs)
proofChallenges := c.GetChallenges(proof, publicInputsHash, verifierData)
proofChallenges := c.GetChallenges(proof, publicInputsHash, commonData, verifierData)
c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash)
initialMerkleCaps := []variables.FriMerkleCap{
initialMerkleCaps := []types.FriMerkleCap{
verifierData.ConstantSigmasCap,
proof.WiresCap,
proof.PlonkZsPartialProductsCap,
@@ -160,8 +226,8 @@ func (c *VerifierChip) Verify(
}
c.friChip.VerifyFriProof(
c.friChip.GetInstance(proofChallenges.PlonkZeta),
c.friChip.ToOpenings(proof.Openings),
fri.GetInstance(&commonData, c.glChip, proofChallenges.PlonkZeta, commonData.DegreeBits),
fri.ToOpenings(proof.Openings),
&proofChallenges.FriChallenges,
initialMerkleCaps,
&proof.OpeningProof,

View File

@@ -4,34 +4,52 @@ import (
"testing"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/math/emulated"
"github.com/consensys/gnark/test"
gl "github.com/succinctlabs/gnark-plonky2-verifier/goldilocks"
"github.com/succinctlabs/gnark-plonky2-verifier/types"
"github.com/succinctlabs/gnark-plonky2-verifier/variables"
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
)
type TestVerifierCircuit struct {
Proof types.Proof
PublicInputs []gl.Variable `gnark:",public"`
verifierChip *verifier.VerifierChip `gnark:"-"`
plonky2CircuitName string `gnark:"-"`
}
func (c *TestVerifierCircuit) Define(api frontend.API) error {
circuitDirname := "./data/" + c.plonky2CircuitName + "/"
commonCircuitData := verifier.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json")
verifierOnlyCircuitData := verifier.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json")
c.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
c.verifierChip.Verify(c.Proof, c.PublicInputs, verifierOnlyCircuitData, commonCircuitData)
return nil
}
func TestStepVerifier(t *testing.T) {
assert := test.NewAssert(t)
testCase := func() {
plonky2Circuit := "step"
commonCircuitData := types.ReadCommonCircuitData("../testdata/" + plonky2Circuit + "/common_circuit_data.json")
proofWithPis := variables.DeserializeProofWithPublicInputs(types.ReadProofWithPublicInputs("../testdata/" + plonky2Circuit + "/proof_with_public_inputs.json"))
verifierOnlyCircuitData := variables.DeserializeVerifierOnlyCircuitData(types.ReadVerifierOnlyCircuitData("../testdata/" + plonky2Circuit + "/verifier_only_circuit_data.json"))
circuit := verifier.ExampleVerifierCircuit{
Proof: proofWithPis.Proof,
PublicInputs: proofWithPis.PublicInputs,
VerifierOnlyCircuitData: verifierOnlyCircuitData,
CommonCircuitData: commonCircuitData,
proofWithPis := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
circuit := TestVerifierCircuit{
plonky2CircuitName: plonky2Circuit,
Proof: proofWithPis.Proof,
PublicInputs: proofWithPis.PublicInputs,
}
witness := verifier.ExampleVerifierCircuit{
Proof: proofWithPis.Proof,
PublicInputs: proofWithPis.PublicInputs,
VerifierOnlyCircuitData: verifierOnlyCircuitData,
CommonCircuitData: commonCircuitData,
proofWithPis2 := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
witness := TestVerifierCircuit{
plonky2CircuitName: plonky2Circuit,
Proof: proofWithPis2.Proof,
PublicInputs: proofWithPis2.PublicInputs,
}
err := test.IsSolved(&circuit, &witness, ecc.BN254.ScalarField())
@@ -39,3 +57,66 @@ func TestStepVerifier(t *testing.T) {
}
testCase()
}
func TestStepVerifier2(t *testing.T) {
assert := test.NewAssert(t)
plonky2Circuit := "step"
proofWithPis := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
circuit := TestVerifierCircuit{
plonky2CircuitName: plonky2Circuit,
Proof: proofWithPis.Proof,
PublicInputs: proofWithPis.PublicInputs,
}
proofWithPis2 := verifier.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
witness := TestVerifierCircuit{
plonky2CircuitName: plonky2Circuit,
Proof: proofWithPis2.Proof,
PublicInputs: proofWithPis2.PublicInputs,
}
assert.ProverSucceeded(
&circuit,
&witness,
test.WithBackends(backend.GROTH16),
test.WithCurves(ecc.BN254),
test.NoFuzzing(),
test.NoSerialization(),
)
}
type testCircuit struct {
Arr [2]emulated.Element[emulated.Secp256k1Fp]
Expected emulated.Element[emulated.Secp256k1Fp]
}
func (circuit *testCircuit) Define(api frontend.API) error {
field, _ := emulated.NewField[emulated.Secp256k1Fp](api)
mulRes := field.Mul(&circuit.Arr[0], &circuit.Arr[1])
field.AssertIsEqual(mulRes, &circuit.Expected)
return nil
}
func TestMain(t *testing.T) {
assert := test.NewAssert(t)
var circuit testCircuit
assert.ProverSucceeded(
&circuit,
&testCircuit{
Arr: [2]emulated.Element[emulated.Secp256k1Fp]{
emulated.ValueOf[emulated.Secp256k1Fp](42),
emulated.ValueOf[emulated.Secp256k1Fp](24),
},
Expected: emulated.ValueOf[emulated.Secp256k1Fp](1008),
},
test.WithBackends(backend.GROTH16),
test.WithCurves(ecc.BN254),
test.NoFuzzing(),
test.NoSerialization(),
)
}