mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 00:51:33 +01:00
Rearranged files (#17)
* removed unused file * change field import * change import of field package * changed field import * moved hash to poseidon and some changes to the field package * changed file structure
This commit is contained in:
57
verifier/common/config.go
Normal file
57
verifier/common/config.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
)
|
||||
|
||||
type VerifierOnlyCircuitData struct {
|
||||
ConstantSigmasCap MerkleCap
|
||||
CircuitDigest poseidon.Hash
|
||||
}
|
||||
|
||||
type CircuitConfig struct {
|
||||
NumWires uint64
|
||||
NumRoutedWires uint64
|
||||
NumConstants uint64
|
||||
UseBaseArithmeticGate bool
|
||||
SecurityBits uint64
|
||||
NumChallenges uint64
|
||||
ZeroKnowledge bool
|
||||
MaxQuotientDegreeFactor uint64
|
||||
FriConfig FriConfig
|
||||
}
|
||||
|
||||
type CommonCircuitData struct {
|
||||
Config CircuitConfig
|
||||
FriParams FriParams
|
||||
Gates []gates.Gate
|
||||
SelectorsInfo gates.SelectorsInfo
|
||||
DegreeBits uint64
|
||||
QuotientDegreeFactor uint64
|
||||
NumGateConstraints uint64
|
||||
NumConstants uint64
|
||||
NumPublicInputs uint64
|
||||
KIs []field.F
|
||||
NumPartialProducts uint64
|
||||
}
|
||||
|
||||
type FriConfig struct {
|
||||
RateBits uint64
|
||||
CapHeight uint64
|
||||
ProofOfWorkBits uint64
|
||||
NumQueryRounds uint64
|
||||
// TODO: add FriReductionStrategy
|
||||
}
|
||||
|
||||
func (fc *FriConfig) Rate() float64 {
|
||||
return 1.0 / float64((uint64(1) << fc.RateBits))
|
||||
}
|
||||
|
||||
type FriParams struct {
|
||||
Config FriConfig
|
||||
Hiding bool
|
||||
DegreeBits uint64
|
||||
ReductionArityBits []uint64
|
||||
}
|
||||
80
verifier/common/types.go
Normal file
80
verifier/common/types.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
)
|
||||
|
||||
type MerkleCap = []poseidon.Hash
|
||||
|
||||
type MerkleProof struct {
|
||||
Siblings []poseidon.Hash
|
||||
}
|
||||
|
||||
type EvalProof struct {
|
||||
Elements []field.F
|
||||
MerkleProof MerkleProof
|
||||
}
|
||||
|
||||
type PolynomialCoeffs struct {
|
||||
Coeffs []field.QuadraticExtension
|
||||
}
|
||||
|
||||
type OpeningSet struct {
|
||||
Constants []field.QuadraticExtension
|
||||
PlonkSigmas []field.QuadraticExtension
|
||||
Wires []field.QuadraticExtension
|
||||
PlonkZs []field.QuadraticExtension
|
||||
PlonkZsNext []field.QuadraticExtension
|
||||
PartialProducts []field.QuadraticExtension
|
||||
QuotientPolys []field.QuadraticExtension
|
||||
}
|
||||
|
||||
type Proof struct {
|
||||
WiresCap MerkleCap
|
||||
PlonkZsPartialProductsCap MerkleCap
|
||||
QuotientPolysCap MerkleCap
|
||||
Openings OpeningSet
|
||||
OpeningProof FriProof
|
||||
}
|
||||
|
||||
type ProofWithPublicInputs struct {
|
||||
Proof Proof
|
||||
PublicInputs []field.F
|
||||
}
|
||||
|
||||
type ProofChallenges struct {
|
||||
PlonkBetas []field.F
|
||||
PlonkGammas []field.F
|
||||
PlonkAlphas []field.F
|
||||
PlonkZeta field.QuadraticExtension
|
||||
FriChallenges FriChallenges
|
||||
}
|
||||
|
||||
type FriInitialTreeProof struct {
|
||||
EvalsProofs []EvalProof
|
||||
}
|
||||
|
||||
type FriQueryStep struct {
|
||||
Evals []field.QuadraticExtension
|
||||
MerkleProof MerkleProof
|
||||
}
|
||||
|
||||
type FriQueryRound struct {
|
||||
InitialTreesProof FriInitialTreeProof
|
||||
Steps []FriQueryStep
|
||||
}
|
||||
|
||||
type FriProof struct {
|
||||
CommitPhaseMerkleCaps []MerkleCap
|
||||
QueryRoundProofs []FriQueryRound
|
||||
FinalPoly PolynomialCoeffs
|
||||
PowWitness field.F
|
||||
}
|
||||
|
||||
type FriChallenges struct {
|
||||
FriAlpha field.QuadraticExtension
|
||||
FriBetas []field.QuadraticExtension
|
||||
FriPowResponse field.F
|
||||
FriQueryIndices []field.F
|
||||
}
|
||||
150
verifier/data/dummy_2^14_gates/common_circuit_data.json
Normal file
150
verifier/data/dummy_2^14_gates/common_circuit_data.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"config": {
|
||||
"num_wires": 135,
|
||||
"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": 14,
|
||||
"reduction_arity_bits": [
|
||||
4,
|
||||
4,
|
||||
4
|
||||
]
|
||||
},
|
||||
"gates": [
|
||||
"NoopGate",
|
||||
"ConstantGate { num_consts: 2 }",
|
||||
"PublicInputGate"
|
||||
],
|
||||
"selectors_info": {
|
||||
"selector_indices": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
"quotient_degree_factor": 8,
|
||||
"num_gate_constraints": 4,
|
||||
"num_constants": 3,
|
||||
"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
|
||||
}
|
||||
31140
verifier/data/dummy_2^14_gates/proof_with_public_inputs.json
Normal file
31140
verifier/data/dummy_2^14_gates/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
140
verifier/data/dummy_2^14_gates/verifier_only_circuit_data.json
Normal file
140
verifier/data/dummy_2^14_gates/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"constants_sigmas_cap": [
|
||||
{
|
||||
"elements": [
|
||||
4759797886241550041,
|
||||
16047691004983234860,
|
||||
9659762256552197216,
|
||||
10112553966470275428
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6580856520142680697,
|
||||
17545262075403841780,
|
||||
17375632104615520990,
|
||||
7416977774732798943
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
16353512268073979322,
|
||||
819827092644027799,
|
||||
16690673607724368808,
|
||||
15037968687422549712
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
8436504004905600346,
|
||||
9803040091724299970,
|
||||
13874489205559745161,
|
||||
9113368467425613680
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
11091349953543466700,
|
||||
16835828310505248580,
|
||||
9401730018779004456,
|
||||
16217511395210280637
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
14652613590798123935,
|
||||
6513400524233583632,
|
||||
14260635575060377802,
|
||||
2934429662141013591
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
16079430466329685864,
|
||||
15523825632000959289,
|
||||
10929447713382773099,
|
||||
13359117551990706652
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
3981642429220224195,
|
||||
16563383270645026066,
|
||||
11676626736400014113,
|
||||
12391006943408842728
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
14534632951568236500,
|
||||
6622950057448608217,
|
||||
10317722778604321203,
|
||||
16857091229989966532
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
1854667436830330051,
|
||||
10698208885037992043,
|
||||
8279000029256055765,
|
||||
16473632613257578260
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6112653519502862522,
|
||||
16414985808267477185,
|
||||
17212339018953338390,
|
||||
2035088574051215606
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
283442216994125368,
|
||||
5745335585396117672,
|
||||
5374569058514548582,
|
||||
10252700696576858963
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
9306370623805561429,
|
||||
16251397047578608507,
|
||||
14346837135739683212,
|
||||
16134961398977435830
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
7908139687533230014,
|
||||
868091850428391307,
|
||||
17334379805830263268,
|
||||
14344912333616841759
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
5694816422417791625,
|
||||
1123655791248550867,
|
||||
10759039854778271524,
|
||||
14259550375971834217
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
8540856852870738366,
|
||||
13653940430116418378,
|
||||
12200920580995523853,
|
||||
4531851613365767268
|
||||
]
|
||||
}
|
||||
],
|
||||
"circuit_digest": {
|
||||
"elements": [
|
||||
651333322065354824,
|
||||
4413552684545354123,
|
||||
11977324165034072678,
|
||||
16531113439125733803
|
||||
]
|
||||
}
|
||||
}
|
||||
1
verifier/data/dummy_small/common_circuit_data.json
Normal file
1
verifier/data/dummy_small/common_circuit_data.json
Normal file
@@ -0,0 +1 @@
|
||||
{"config":{"num_wires":135,"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":12,"cap_height":4,"proof_of_work_bits":16,"reduction_strategy":{"ConstantArityBits":[4,5]},"num_query_rounds":7}},"fri_params":{"config":{"rate_bits":12,"cap_height":4,"proof_of_work_bits":16,"reduction_strategy":{"ConstantArityBits":[4,5]},"num_query_rounds":7},"hiding":false,"degree_bits":2,"reduction_arity_bits":[]},"gates":["NoopGate","ConstantGate { num_consts: 2 }","PublicInputGate"],"selectors_info":{"selector_indices":[0,0,0],"groups":[{"start":0,"end":3}]},"quotient_degree_factor":8,"num_gate_constraints":4,"num_constants":3,"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}
|
||||
1
verifier/data/dummy_small/proof_with_public_inputs.json
Normal file
1
verifier/data/dummy_small/proof_with_public_inputs.json
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"constants_sigmas_cap":[{"elements":[12942050173360299287,15429129527496118608,11044804177370023771,17027862521442293343]},{"elements":[5129937521595676319,9249371000310776833,1698652619737853229,3597277235363989900]},{"elements":[9499069482602362280,6056775334288968735,9416720030884613634,8481612183293566397]},{"elements":[7444928464878659248,59632799137831308,6374428807271012784,12055696886890254745]},{"elements":[11760551261657627154,5292872815316944996,12187602224948210417,184439611357521062]},{"elements":[13972524877212598728,11420817450690243876,15994255466128604849,1311060574252414086]},{"elements":[16494325411515456931,18075355179587378715,4646724997371828866,1372832552151954570]},{"elements":[16387476627685153284,17032030743812759632,16808048043752991311,16788518620316721833]},{"elements":[4194862242212612774,364226560743618053,11438397620101696839,9286576348843874621]},{"elements":[6340101954898285234,10773051474343740098,6629082148740745229,3982094848619266494]},{"elements":[8009275308971482529,10105260369496924395,8987390598028905021,9739740379439925196]},{"elements":[13635364907274847648,1135616847056663194,6574618410485087638,11497429148813108159]},{"elements":[15405963465632273554,10983537026674671450,17181205620785852479,2598367474817225484]},{"elements":[16613943869767229638,8953767102519510969,2778482474224727871,835196900223386389]},{"elements":[213910466424313779,1036984933257510494,9766858993890477954,5836427172912690664]},{"elements":[1538574690328025715,2426907990630109879,8393881157947355071,8063812988973786255]}],"circuit_digest":{"elements":[18101853563531100136,12778281678899705371,12856635299514517756,11554767480547589421]}}
|
||||
152
verifier/data/fibonacci/common_circuit_data.json
Normal file
152
verifier/data/fibonacci/common_circuit_data.json
Normal file
@@ -0,0 +1,152 @@
|
||||
{
|
||||
"config": {
|
||||
"num_wires": 135,
|
||||
"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": 3,
|
||||
"reduction_arity_bits": []
|
||||
},
|
||||
"gates": [
|
||||
"ConstantGate { num_consts: 2 }",
|
||||
"PublicInputGate",
|
||||
"ArithmeticGate { num_ops: 20 }",
|
||||
"PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
||||
],
|
||||
"selectors_info": {
|
||||
"selector_indices": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 3
|
||||
},
|
||||
{
|
||||
"start": 3,
|
||||
"end": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"quotient_degree_factor": 8,
|
||||
"num_gate_constraints": 123,
|
||||
"num_constants": 4,
|
||||
"num_public_inputs": 3,
|
||||
"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
|
||||
}
|
||||
11509
verifier/data/fibonacci/proof_with_public_inputs.json
Normal file
11509
verifier/data/fibonacci/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
140
verifier/data/fibonacci/verifier_only_circuit_data.json
Normal file
140
verifier/data/fibonacci/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"constants_sigmas_cap": [
|
||||
{
|
||||
"elements": [
|
||||
2913805118787558759,
|
||||
15605217703384212484,
|
||||
9293436862297178555,
|
||||
10529947991695419448
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
1937331278189251620,
|
||||
17537260089483183877,
|
||||
10458485670158100707,
|
||||
4116443229550247591
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
8142760542024755709,
|
||||
3845244796524514577,
|
||||
16191049345326767258,
|
||||
7348433903875207214
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
18274477257392359471,
|
||||
9341197367296335592,
|
||||
14314312946600883535,
|
||||
17431979896521737468
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
12713790163422286570,
|
||||
9838614764658999419,
|
||||
3024549327814176904,
|
||||
6544549858431318793
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17461063081201329467,
|
||||
1929790214678747830,
|
||||
14738190695567211833,
|
||||
4502436664569676311
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17446087997043032816,
|
||||
17518692693064701003,
|
||||
4915378766449394412,
|
||||
10675325761198739044
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
11349186227918507635,
|
||||
7105572536043210156,
|
||||
13296927306801261929,
|
||||
6138189381388819111
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17427080957162886576,
|
||||
4310228111529328877,
|
||||
16109317445338921222,
|
||||
11923676504992192083
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
11292141569337462929,
|
||||
7213981967192374125,
|
||||
4837353949249389782,
|
||||
13157524938508720907
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17221477633935993097,
|
||||
7905315334616496868,
|
||||
2950048088611741910,
|
||||
16851660641249290423
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
1918571898367258879,
|
||||
14473285549490778842,
|
||||
16456257732802770188,
|
||||
16611801325745795527
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
7880989808200689690,
|
||||
16935107633380717766,
|
||||
8956194191973051375,
|
||||
1103945341495739535
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
4501339912027744074,
|
||||
12142665268233044767,
|
||||
9270990890291324944,
|
||||
45374981263348191
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
13657768796246999470,
|
||||
2899654677720502418,
|
||||
7228867285602519410,
|
||||
3363587770111123806
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
18227101298896629706,
|
||||
12986849723013952028,
|
||||
16815808278639394978,
|
||||
16460725848109409638
|
||||
]
|
||||
}
|
||||
],
|
||||
"circuit_digest": {
|
||||
"elements": [
|
||||
15489309507512017401,
|
||||
16244437215982314072,
|
||||
10011620388767144997,
|
||||
15394117319313330212
|
||||
]
|
||||
}
|
||||
}
|
||||
173
verifier/data/recursive/common_circuit_data.json
Normal file
173
verifier/data/recursive/common_circuit_data.json
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"config": {
|
||||
"num_wires": 135,
|
||||
"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",
|
||||
"PublicInputGate",
|
||||
"BaseSumGate { num_limbs: 63 } + Base: 2",
|
||||
"ReducingExtensionGate { num_coeffs: 32 }",
|
||||
"ReducingGate { num_coeffs: 43 }",
|
||||
"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, 256, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 1048576, 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,
|
||||
2,
|
||||
2
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 6
|
||||
},
|
||||
{
|
||||
"start": 6,
|
||||
"end": 9
|
||||
},
|
||||
{
|
||||
"start": 9,
|
||||
"end": 11
|
||||
}
|
||||
]
|
||||
},
|
||||
"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
|
||||
}
|
||||
26194
verifier/data/recursive/proof_with_public_inputs.json
Normal file
26194
verifier/data/recursive/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
140
verifier/data/recursive/verifier_only_circuit_data.json
Normal file
140
verifier/data/recursive/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"constants_sigmas_cap": [
|
||||
{
|
||||
"elements": [
|
||||
5792880812518408658,
|
||||
2007865592137458435,
|
||||
5118679776640867091,
|
||||
13069431186724985571
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
620745627896223750,
|
||||
11689482378865345226,
|
||||
515625484560203909,
|
||||
6594700411046985771
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
4288547219194413000,
|
||||
13137436527356415412,
|
||||
12622945773280822587,
|
||||
650627082873761457
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
13506996103707830465,
|
||||
8679821128676565111,
|
||||
4223042913738287628,
|
||||
9099197279443824593
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
14449575924890308633,
|
||||
8733833351673036584,
|
||||
16541374894852431819,
|
||||
9332074455551145433
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
10076928807302913775,
|
||||
3821138534617469739,
|
||||
1717959071597020718,
|
||||
17760656161674093717
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
2599426417611084017,
|
||||
13871968726722310950,
|
||||
1516291378797220061,
|
||||
13799666340648349967
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
12663813165492321869,
|
||||
14876506856106059016,
|
||||
1242723042851988831,
|
||||
2875934737469787816
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17378423119286703930,
|
||||
11222598627075744078,
|
||||
9488528583590922099,
|
||||
14157718813638267686
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
1071412395592558182,
|
||||
18101728088624707784,
|
||||
3182026360229291426,
|
||||
14227530413232734538
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
726974142246132532,
|
||||
15153315199262507247,
|
||||
17940113059510197877,
|
||||
16772587044853202303
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
12231534358502296703,
|
||||
10511512947619127431,
|
||||
16590010230992836643,
|
||||
12522924984185338479
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
8037124124878150231,
|
||||
7299067373190351508,
|
||||
6928393757878692343,
|
||||
14665216450327743533
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
8476349181260794151,
|
||||
2992858515573144844,
|
||||
12544833538408559347,
|
||||
12322593314271890822
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17452538538131258483,
|
||||
16559982778748471691,
|
||||
7832234514212696397,
|
||||
7687737265950783860
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
5386649132465675374,
|
||||
15880918294706587722,
|
||||
12305658309516685089,
|
||||
1973473830101720437
|
||||
]
|
||||
}
|
||||
],
|
||||
"circuit_digest": {
|
||||
"elements": [
|
||||
7986243079228529757,
|
||||
6431975618990554147,
|
||||
3826625528654889031,
|
||||
10807866526356205171
|
||||
]
|
||||
}
|
||||
}
|
||||
172
verifier/data/recursive_small/common_circuit_data.json
Normal file
172
verifier/data/recursive_small/common_circuit_data.json
Normal file
@@ -0,0 +1,172 @@
|
||||
{
|
||||
"config": {
|
||||
"num_wires": 135,
|
||||
"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": 2
|
||||
}
|
||||
},
|
||||
"fri_params": {
|
||||
"config": {
|
||||
"rate_bits": 3,
|
||||
"cap_height": 4,
|
||||
"proof_of_work_bits": 16,
|
||||
"reduction_strategy": {
|
||||
"ConstantArityBits": [
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
"num_query_rounds": 2
|
||||
},
|
||||
"hiding": false,
|
||||
"degree_bits": 9,
|
||||
"reduction_arity_bits": [
|
||||
4
|
||||
]
|
||||
},
|
||||
"gates": [
|
||||
"NoopGate",
|
||||
"ConstantGate { num_consts: 2 }",
|
||||
"PublicInputGate",
|
||||
"BaseSumGate { num_limbs: 63 } + Base: 2",
|
||||
"ReducingExtensionGate { num_coeffs: 32 }",
|
||||
"ReducingGate { num_coeffs: 43 }",
|
||||
"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>",
|
||||
"PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
||||
],
|
||||
"selectors_info": {
|
||||
"selector_indices": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 6
|
||||
},
|
||||
{
|
||||
"start": 6,
|
||||
"end": 10
|
||||
},
|
||||
{
|
||||
"start": 10,
|
||||
"end": 11
|
||||
}
|
||||
]
|
||||
},
|
||||
"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
|
||||
}
|
||||
3024
verifier/data/recursive_small/proof_with_public_inputs.json
Normal file
3024
verifier/data/recursive_small/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
140
verifier/data/recursive_small/verifier_only_circuit_data.json
Normal file
140
verifier/data/recursive_small/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"constants_sigmas_cap": [
|
||||
{
|
||||
"elements": [
|
||||
158845205314874220,
|
||||
9668380905015929998,
|
||||
1411954196422652535,
|
||||
16261560315091018602
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
10819768878069205512,
|
||||
10806329121382974236,
|
||||
4449962652936030991,
|
||||
3437130958683867731
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
13409308832792573752,
|
||||
5142428395608775971,
|
||||
8304804561534366563,
|
||||
3333782371953158323
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
18228625912291347825,
|
||||
10166925566614695203,
|
||||
18158685652491144528,
|
||||
5812383934966268838
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
9826807818157299303,
|
||||
16982355347088639655,
|
||||
9164194217012055587,
|
||||
2807644941373961188
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
14310741273297755831,
|
||||
12981827714166111968,
|
||||
4530737992662289685,
|
||||
18335773668219568846
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
7917966912899515534,
|
||||
17667717333057450416,
|
||||
952641997971486450,
|
||||
428804504796282154
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6150969121154358920,
|
||||
8533162538572915310,
|
||||
13902780732405127329,
|
||||
10048329503515769882
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17799006350046251788,
|
||||
10571037994954145577,
|
||||
16382491710544403234,
|
||||
8887053452984223370
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
3963886065503765705,
|
||||
2739764768577488879,
|
||||
5343505536176223500,
|
||||
9151432391854309795
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
4165310799113686308,
|
||||
10915634867031695254,
|
||||
5813235613342911366,
|
||||
17907275021812350449
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
12954911538188629834,
|
||||
6738667513261916639,
|
||||
12025960525821021496,
|
||||
3765915660295958137
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
15699732256890621800,
|
||||
14355912053969064032,
|
||||
9559845752177194786,
|
||||
6008684051170164157
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
5973104887002336129,
|
||||
15822297470108300955,
|
||||
1285855046140391788,
|
||||
8567304882129939594
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
531701086966465293,
|
||||
13988001761158611208,
|
||||
10640541520023034000,
|
||||
12368315472470450606
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
16726108137472169650,
|
||||
9400941780708454743,
|
||||
2656080070909638220,
|
||||
10262921538692249992
|
||||
]
|
||||
}
|
||||
],
|
||||
"circuit_digest": {
|
||||
"elements": [
|
||||
7291397556757192596,
|
||||
149044718719699113,
|
||||
14214393601687894808,
|
||||
15901190186686913364
|
||||
]
|
||||
}
|
||||
}
|
||||
175
verifier/data/recursive_step/common_circuit_data.json
Normal file
175
verifier/data/recursive_step/common_circuit_data.json
Normal file
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"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",
|
||||
"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
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 6
|
||||
},
|
||||
{
|
||||
"start": 6,
|
||||
"end": 10
|
||||
},
|
||||
{
|
||||
"start": 10,
|
||||
"end": 12
|
||||
}
|
||||
]
|
||||
},
|
||||
"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
|
||||
}
|
||||
27634
verifier/data/recursive_step/proof_with_public_inputs.json
Normal file
27634
verifier/data/recursive_step/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
140
verifier/data/recursive_step/verifier_only_circuit_data.json
Normal file
140
verifier/data/recursive_step/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"constants_sigmas_cap": [
|
||||
{
|
||||
"elements": [
|
||||
11953454831364282697,
|
||||
1780640713616741507,
|
||||
9332530534753348552,
|
||||
17084282210745809382
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17758681460299977814,
|
||||
15435331084685806694,
|
||||
7766646160278036540,
|
||||
5345072798617230589
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
8802797469535268068,
|
||||
3037505332513657608,
|
||||
16030922155257393390,
|
||||
13188886177244942097
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
2357959411935908456,
|
||||
1458480601790550366,
|
||||
11949473050563493262,
|
||||
1836765554619785226
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17907165543584078363,
|
||||
9893605436382885449,
|
||||
6670152476736706784,
|
||||
562838117712837468
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
5744223185797504102,
|
||||
13743400022410455956,
|
||||
6205029693922586080,
|
||||
15336463778776378871
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
14723206064376829937,
|
||||
13180213430291675472,
|
||||
5411273601294455899,
|
||||
8840354110576908600
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
10897208927347958232,
|
||||
2388900836403833331,
|
||||
13400951517389305038,
|
||||
2629935461033320568
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6382278241197748160,
|
||||
2864721123412042365,
|
||||
1383065474344220868,
|
||||
2692411485496850147
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
4198408477591504932,
|
||||
8255926325330378434,
|
||||
14022111482748940978,
|
||||
8650742941998823647
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6235912550116348485,
|
||||
1591288015265630569,
|
||||
6942981485091244971,
|
||||
9620918527217246407
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
8301265937387597891,
|
||||
13822840883914340904,
|
||||
13370707368391237777,
|
||||
15118584100319351289
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
12805136189787682184,
|
||||
14515274878974073778,
|
||||
15431575651860817805,
|
||||
1563913167146652597
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6512639279406449383,
|
||||
15697846660972222282,
|
||||
5729086478860256848,
|
||||
1818341437677547274
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
4116477618393991081,
|
||||
604123225308335767,
|
||||
459683656323372900,
|
||||
10069219213626177582
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
7335240546348323257,
|
||||
12233386866476119728,
|
||||
4755043335297619337,
|
||||
2281707033870644336
|
||||
]
|
||||
}
|
||||
],
|
||||
"circuit_digest": {
|
||||
"elements": [
|
||||
14321013545913480595,
|
||||
17038401155010977967,
|
||||
2998069758835997053,
|
||||
10198464630670001962
|
||||
]
|
||||
}
|
||||
}
|
||||
205
verifier/data/step/common_circuit_data.json
Normal file
205
verifier/data/step/common_circuit_data.json
Normal file
@@ -0,0 +1,205 @@
|
||||
{
|
||||
"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": 21,
|
||||
"reduction_arity_bits": [
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
4
|
||||
]
|
||||
},
|
||||
"gates": [
|
||||
"NoopGate",
|
||||
"ConstantGate { num_consts: 2 }",
|
||||
"PublicInputGate",
|
||||
"BaseSumGate { num_limbs: 32 } + Base: 2",
|
||||
"BaseSumGate { num_limbs: 63 } + Base: 2",
|
||||
"ArithmeticGate { num_ops: 20 }",
|
||||
"RandomAccessGate { bits: 2, num_copies: 13, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
|
||||
"XOR3Gate { num_xors: 16 }",
|
||||
"BaseSumGate { num_limbs: 16 } + Base: 4",
|
||||
"ComparisonGate { num_bits: 32, num_chunks: 16, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
|
||||
"U32AddManyGate { num_addends: 11, num_ops: 4, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32AddManyGate { num_addends: 13, num_ops: 4, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32AddManyGate { num_addends: 15, num_ops: 3, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32AddManyGate { num_addends: 16, num_ops: 3, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32AddManyGate { num_addends: 3, num_ops: 5, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32AddManyGate { num_addends: 5, num_ops: 5, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32AddManyGate { num_addends: 7, num_ops: 4, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32AddManyGate { num_addends: 9, num_ops: 4, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32ArithmeticGate { num_ops: 3, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32RangeCheckGate { num_input_limbs: 8, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"U32SubtractionGate { num_ops: 6, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }",
|
||||
"RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
|
||||
],
|
||||
"selectors_info": {
|
||||
"selector_indices": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
4
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 6
|
||||
},
|
||||
{
|
||||
"start": 6,
|
||||
"end": 11
|
||||
},
|
||||
{
|
||||
"start": 11,
|
||||
"end": 16
|
||||
},
|
||||
{
|
||||
"start": 16,
|
||||
"end": 21
|
||||
},
|
||||
{
|
||||
"start": 21,
|
||||
"end": 22
|
||||
}
|
||||
]
|
||||
},
|
||||
"quotient_degree_factor": 8,
|
||||
"num_gate_constraints": 136,
|
||||
"num_constants": 7,
|
||||
"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
|
||||
}
|
||||
45430
verifier/data/step/proof_with_public_inputs.json
Normal file
45430
verifier/data/step/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
140
verifier/data/step/verifier_only_circuit_data.json
Normal file
140
verifier/data/step/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"constants_sigmas_cap": [
|
||||
{
|
||||
"elements": [
|
||||
9037422181318074482,
|
||||
13844553280258601189,
|
||||
14013690396566737561,
|
||||
14600533186953608428
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
3891365497285560518,
|
||||
6785071445101560305,
|
||||
7146616719154245281,
|
||||
8484433928946731576
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
15935467950899360740,
|
||||
1041659913562170406,
|
||||
11898906592313038819,
|
||||
7940456224436700998
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
17420135248456983,
|
||||
10686061014804565544,
|
||||
17782021355470763205,
|
||||
12726022340820773339
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
13322967402317526249,
|
||||
12119892482906381301,
|
||||
1483851501277040422,
|
||||
17519911664522741561
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
3901474702590233137,
|
||||
16494478574194405372,
|
||||
3644962804006307872,
|
||||
7967195830112920768
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
15532816309418050992,
|
||||
11198055639421810456,
|
||||
7449000032233257165,
|
||||
6080646728225911938
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
7944791944524511304,
|
||||
15470849481646525511,
|
||||
11102721978231118523,
|
||||
10011467322465036320
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
14679375199524381062,
|
||||
9219647684485300612,
|
||||
8902882543708912876,
|
||||
6737676211275058717
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
15215848762718399329,
|
||||
9538467614418882672,
|
||||
7337952705707955964,
|
||||
17932579689749986997
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
3111383469397480110,
|
||||
17276616486884637185,
|
||||
10511216595022742027,
|
||||
3343575652946909638
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
2417848701164748156,
|
||||
7846191940051381446,
|
||||
4363725272084187306,
|
||||
3143323624098735830
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
7639597922146523429,
|
||||
14015537888097194053,
|
||||
10449936634441844342,
|
||||
3897071524048579556
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
12445360068819311840,
|
||||
4910166437012489060,
|
||||
9670875686931891121,
|
||||
5569206524147441284
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6965775890897127688,
|
||||
14853930701622190781,
|
||||
2643689027677976461,
|
||||
1883768007952536249
|
||||
]
|
||||
},
|
||||
{
|
||||
"elements": [
|
||||
6771363979354677578,
|
||||
6567107174924251028,
|
||||
15758449129319031800,
|
||||
6619880945043941329
|
||||
]
|
||||
}
|
||||
],
|
||||
"circuit_digest": {
|
||||
"elements": [
|
||||
8574090053162898339,
|
||||
2808971464690312489,
|
||||
14807704193989191909,
|
||||
14951686172889873386
|
||||
]
|
||||
}
|
||||
}
|
||||
571
verifier/internal/fri/fri.go
Normal file
571
verifier/internal/fri/fri.go
Normal file
@@ -0,0 +1,571 @@
|
||||
package fri
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"math/bits"
|
||||
|
||||
"github.com/consensys/gnark-crypto/field/goldilocks"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
)
|
||||
|
||||
type FriChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
fieldAPI frontend.API `gnark:"-"`
|
||||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
|
||||
hashAPI *poseidon.HashAPI `gnark:"-"`
|
||||
|
||||
poseidonChip *poseidon.PoseidonChip
|
||||
|
||||
friParams *common.FriParams `gnark:"-"`
|
||||
}
|
||||
|
||||
func NewFriChip(
|
||||
api frontend.API,
|
||||
fieldAPI frontend.API,
|
||||
qeAPI *field.QuadraticExtensionAPI,
|
||||
hashAPI *poseidon.HashAPI,
|
||||
poseidonChip *poseidon.PoseidonChip,
|
||||
friParams *common.FriParams,
|
||||
) *FriChip {
|
||||
return &FriChip{
|
||||
api: api,
|
||||
fieldAPI: fieldAPI,
|
||||
qeAPI: qeAPI,
|
||||
hashAPI: hashAPI,
|
||||
poseidonChip: poseidonChip,
|
||||
friParams: friParams,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FriChip) assertLeadingZeros(powWitness field.F, friConfig common.FriConfig) {
|
||||
// Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros.
|
||||
// Note that this is assuming that the Goldilocks field is being used. Specfically that the
|
||||
// field is 64 bits long
|
||||
maxPowWitness := uint64(math.Pow(2, float64(64-friConfig.ProofOfWorkBits))) - 1
|
||||
f.fieldAPI.AssertIsLessOrEqual(powWitness, field.NewFieldElement(maxPowWitness))
|
||||
}
|
||||
|
||||
func (f *FriChip) fromOpeningsAndAlpha(openings *FriOpenings, alpha field.QuadraticExtension) []field.QuadraticExtension {
|
||||
// One reduced opening for all openings evaluated at point Zeta.
|
||||
// Another one for all openings evaluated at point Zeta * Omega (which is only PlonkZsNext polynomial)
|
||||
|
||||
reducedOpenings := make([]field.QuadraticExtension, 0, 2)
|
||||
for _, batch := range openings.Batches {
|
||||
reducedOpenings = append(reducedOpenings, f.qeAPI.ReduceWithPowers(batch.Values, alpha))
|
||||
}
|
||||
|
||||
return reducedOpenings
|
||||
}
|
||||
|
||||
func (f *FriChip) hashOrNoop(data []field.F) poseidon.Hash {
|
||||
var elements poseidon.Hash
|
||||
if len(data) <= 4 {
|
||||
// Pad the data to have a size of 4
|
||||
for i, inputElement := range data {
|
||||
elements[i] = inputElement
|
||||
}
|
||||
for i := len(data); i < 4; i++ {
|
||||
elements[i] = field.ZERO_F
|
||||
}
|
||||
|
||||
return elements
|
||||
} else {
|
||||
hashOutput := f.poseidonChip.HashNToMNoPad(data, 4)
|
||||
|
||||
if len(hashOutput) != len(elements) {
|
||||
panic("The length of hashOutput and elements is different")
|
||||
}
|
||||
|
||||
for i, hashField := range hashOutput {
|
||||
elements[i] = hashField
|
||||
}
|
||||
|
||||
return elements
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyMerkleProofToCapWithCapIndex(leafData []field.F, leafIndexBits []frontend.Variable, capIndexBits []frontend.Variable, merkleCap common.MerkleCap, proof *common.MerkleProof) {
|
||||
currentDigest := f.hashOrNoop(leafData)
|
||||
fourZeros := [4]field.F{field.ZERO_F, field.ZERO_F, field.ZERO_F, field.ZERO_F}
|
||||
for i, sibling := range proof.Siblings {
|
||||
bit := leafIndexBits[i]
|
||||
|
||||
var leftSiblingState poseidon.PoseidonState
|
||||
copy(leftSiblingState[0:4], sibling[0:4])
|
||||
copy(leftSiblingState[4:8], currentDigest[0:4])
|
||||
copy(leftSiblingState[8:12], fourZeros[0:4])
|
||||
|
||||
leftHash := f.poseidonChip.Poseidon(leftSiblingState)
|
||||
|
||||
var leftHashCompress poseidon.Hash
|
||||
leftHashCompress[0] = leftHash[0]
|
||||
leftHashCompress[1] = leftHash[1]
|
||||
leftHashCompress[2] = leftHash[2]
|
||||
leftHashCompress[3] = leftHash[3]
|
||||
|
||||
var rightSiblingState poseidon.PoseidonState
|
||||
copy(rightSiblingState[0:4], currentDigest[0:4])
|
||||
copy(rightSiblingState[4:8], sibling[0:4])
|
||||
copy(rightSiblingState[8:12], fourZeros[0:4])
|
||||
|
||||
rightHash := f.poseidonChip.Poseidon(rightSiblingState)
|
||||
|
||||
var rightHashCompress poseidon.Hash
|
||||
rightHashCompress[0] = rightHash[0]
|
||||
rightHashCompress[1] = rightHash[1]
|
||||
rightHashCompress[2] = rightHash[2]
|
||||
rightHashCompress[3] = rightHash[3]
|
||||
|
||||
currentDigest = f.hashAPI.SelectHash(bit, leftHashCompress, rightHashCompress)
|
||||
}
|
||||
|
||||
// We assume that the cap_height is 4. Create two levels of the Lookup2 circuit
|
||||
if len(capIndexBits) != 4 || len(merkleCap) != 16 {
|
||||
errorMsg, _ := fmt.Printf(
|
||||
"capIndexBits length should be 4 and the merkleCap length should be 16. Actual values (capIndexBits: %d, merkleCap: %d)\n",
|
||||
len(capIndexBits),
|
||||
len(merkleCap),
|
||||
)
|
||||
panic(errorMsg)
|
||||
}
|
||||
|
||||
const NUM_LEAF_LOOKUPS = 4
|
||||
var leafLookups [NUM_LEAF_LOOKUPS]poseidon.Hash
|
||||
// First create the "leaf" lookup2 circuits
|
||||
// The will use the least significant bits of the capIndexBits array
|
||||
for i := 0; i < NUM_LEAF_LOOKUPS; i++ {
|
||||
leafLookups[i] = f.hashAPI.Lookup2Hash(
|
||||
capIndexBits[0], capIndexBits[1],
|
||||
merkleCap[i*NUM_LEAF_LOOKUPS], merkleCap[i*NUM_LEAF_LOOKUPS+1], merkleCap[i*NUM_LEAF_LOOKUPS+2], merkleCap[i*NUM_LEAF_LOOKUPS+3],
|
||||
)
|
||||
}
|
||||
|
||||
// Use the most 2 significant bits of the capIndexBits array for the "root" lookup
|
||||
merkleCapEntry := f.hashAPI.Lookup2Hash(capIndexBits[2], capIndexBits[3], leafLookups[0], leafLookups[1], leafLookups[2], leafLookups[3])
|
||||
f.hashAPI.AssertIsEqualHash(currentDigest, merkleCapEntry)
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyInitialProof(xIndexBits []frontend.Variable, proof *common.FriInitialTreeProof, initialMerkleCaps []common.MerkleCap, capIndexBits []frontend.Variable) {
|
||||
if len(proof.EvalsProofs) != len(initialMerkleCaps) {
|
||||
panic("length of eval proofs in fri proof should equal length of initial merkle caps")
|
||||
}
|
||||
|
||||
for i := 0; i < len(initialMerkleCaps); i++ {
|
||||
evals := proof.EvalsProofs[i].Elements
|
||||
merkleProof := proof.EvalsProofs[i].MerkleProof
|
||||
cap := initialMerkleCaps[i]
|
||||
f.verifyMerkleProofToCapWithCapIndex(evals, xIndexBits, capIndexBits, cap, &merkleProof)
|
||||
}
|
||||
}
|
||||
|
||||
// / We decompose FRI query indices into bits without verifying that the decomposition given by
|
||||
// / the prover is the canonical one. In particular, if `x_index < 2^field_bits - p`, then the
|
||||
// / prover could supply the binary encoding of either `x_index` or `x_index + p`, since they are
|
||||
// / congruent mod `p`. However, this only occurs with probability
|
||||
// / p_ambiguous = (2^field_bits - p) / p
|
||||
// / which is small for the field that we use in practice.
|
||||
// /
|
||||
// / In particular, the soundness error of one FRI query is roughly the codeword rate, which
|
||||
// / is much larger than this ambiguous-element probability given any reasonable parameters.
|
||||
// / Thus ambiguous elements contribute a negligible amount to soundness error.
|
||||
// /
|
||||
// / Here we compare the probabilities as a sanity check, to verify the claim above.
|
||||
func (f *FriChip) assertNoncanonicalIndicesOK() {
|
||||
numAmbiguousElems := uint64(math.MaxUint64) - goldilocks.Modulus().Uint64() + 1
|
||||
queryError := f.friParams.Config.Rate()
|
||||
pAmbiguous := float64(numAmbiguousElems) / float64(goldilocks.Modulus().Uint64())
|
||||
|
||||
// TODO: Check that pAmbiguous value is the same as the one in plonky2 verifier
|
||||
if pAmbiguous >= queryError*1e-5 {
|
||||
panic("A non-negligible portion of field elements are in the range that permits non-canonical encodings. Need to do more analysis or enforce canonical encodings.")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FriChip) expFromBitsConstBase(
|
||||
base goldilocks.Element,
|
||||
exponentBits []frontend.Variable,
|
||||
) field.F {
|
||||
product := field.ONE_F
|
||||
for i, bit := range exponentBits {
|
||||
pow := int64(1 << i)
|
||||
// If the bit is on, we multiply product by base^pow.
|
||||
// We can arithmetize this as:
|
||||
// product *= 1 + bit (base^pow - 1)
|
||||
// product = (base^pow - 1) product bit + product
|
||||
basePow := goldilocks.NewElement(0)
|
||||
basePow.Exp(base, big.NewInt(pow))
|
||||
|
||||
basePowElement := field.NewFieldElement(basePow.Uint64() - 1)
|
||||
|
||||
product = f.fieldAPI.Add(
|
||||
f.fieldAPI.Mul(
|
||||
basePowElement,
|
||||
product,
|
||||
bit,
|
||||
),
|
||||
product,
|
||||
).(field.F)
|
||||
}
|
||||
|
||||
return product
|
||||
}
|
||||
|
||||
func (f *FriChip) calculateSubgroupX(
|
||||
xIndexBits []frontend.Variable,
|
||||
nLog uint64,
|
||||
) field.F {
|
||||
// Compute x from its index
|
||||
// `subgroup_x` is `subgroup[x_index]`, i.e., the actual field element in the domain.
|
||||
// TODO - Make these as global values
|
||||
g := field.NewFieldElement(field.GOLDILOCKS_MULTIPLICATIVE_GROUP_GENERATOR.Uint64())
|
||||
base := field.GoldilocksPrimitiveRootOfUnity(nLog)
|
||||
|
||||
// Create a reverse list of xIndexBits
|
||||
xIndexBitsRev := make([]frontend.Variable, 0)
|
||||
for i := len(xIndexBits) - 1; i >= 0; i-- {
|
||||
xIndexBitsRev = append(xIndexBitsRev, xIndexBits[i])
|
||||
}
|
||||
|
||||
product := f.expFromBitsConstBase(base, xIndexBitsRev)
|
||||
|
||||
return f.fieldAPI.Mul(g, product).(field.F)
|
||||
}
|
||||
|
||||
func (f *FriChip) friCombineInitial(
|
||||
instance FriInstanceInfo,
|
||||
proof common.FriInitialTreeProof,
|
||||
friAlpha field.QuadraticExtension,
|
||||
subgroupX_QE field.QuadraticExtension,
|
||||
precomputedReducedEval []field.QuadraticExtension,
|
||||
) field.QuadraticExtension {
|
||||
sum := f.qeAPI.ZERO_QE
|
||||
|
||||
if len(instance.Batches) != len(precomputedReducedEval) {
|
||||
panic("len(openings) != len(precomputedReducedEval)")
|
||||
}
|
||||
|
||||
for i := 0; i < len(instance.Batches); i++ {
|
||||
batch := instance.Batches[i]
|
||||
reducedOpenings := precomputedReducedEval[i]
|
||||
|
||||
point := batch.Point
|
||||
evals := make([]field.QuadraticExtension, 0)
|
||||
for _, polynomial := range batch.Polynomials {
|
||||
evals = append(
|
||||
evals,
|
||||
field.QuadraticExtension{proof.EvalsProofs[polynomial.OracleIndex].Elements[polynomial.PolynomialInfo], field.ZERO_F},
|
||||
)
|
||||
}
|
||||
|
||||
reducedEvals := f.qeAPI.ReduceWithPowers(evals, friAlpha)
|
||||
numerator := f.qeAPI.SubExtension(reducedEvals, reducedOpenings)
|
||||
denominator := f.qeAPI.SubExtension(subgroupX_QE, point)
|
||||
sum = f.qeAPI.MulExtension(f.qeAPI.ExpU64Extension(friAlpha, uint64(len(evals))), sum)
|
||||
sum = f.qeAPI.AddExtension(
|
||||
f.qeAPI.DivExtension(
|
||||
numerator,
|
||||
denominator,
|
||||
),
|
||||
sum,
|
||||
)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
func (f *FriChip) finalPolyEval(finalPoly common.PolynomialCoeffs, point field.QuadraticExtension) field.QuadraticExtension {
|
||||
ret := f.qeAPI.ZERO_QE
|
||||
for i := len(finalPoly.Coeffs) - 1; i >= 0; i-- {
|
||||
ret = f.qeAPI.AddExtension(
|
||||
f.qeAPI.MulExtension(
|
||||
ret,
|
||||
point,
|
||||
),
|
||||
finalPoly.Coeffs[i],
|
||||
)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (f *FriChip) interpolate(x field.QuadraticExtension, xPoints []field.QuadraticExtension, yPoints []field.QuadraticExtension, barycentricWeights []field.QuadraticExtension) field.QuadraticExtension {
|
||||
if len(xPoints) != len(yPoints) || len(xPoints) != len(barycentricWeights) {
|
||||
panic("length of xPoints, yPoints, and barycentricWeights are inconsistent")
|
||||
}
|
||||
|
||||
lX := f.qeAPI.ONE_QE
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
lX = f.qeAPI.MulExtension(
|
||||
lX,
|
||||
f.qeAPI.SubExtension(
|
||||
x,
|
||||
xPoints[i],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sum := f.qeAPI.ZERO_QE
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
sum = f.qeAPI.AddExtension(
|
||||
f.qeAPI.MulExtension(
|
||||
f.qeAPI.DivExtension(
|
||||
barycentricWeights[i],
|
||||
f.qeAPI.SubExtension(
|
||||
x,
|
||||
xPoints[i],
|
||||
),
|
||||
),
|
||||
yPoints[i],
|
||||
),
|
||||
sum,
|
||||
)
|
||||
}
|
||||
|
||||
interpolation := f.qeAPI.MulExtension(lX, sum)
|
||||
|
||||
returnField := interpolation
|
||||
// Now check if x is already within the xPoints
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
returnField = f.qeAPI.Select(
|
||||
f.qeAPI.IsZero(f.qeAPI.SubExtension(x, xPoints[i])),
|
||||
yPoints[i],
|
||||
returnField,
|
||||
)
|
||||
}
|
||||
|
||||
return returnField
|
||||
}
|
||||
|
||||
func (f *FriChip) computeEvaluation(
|
||||
x field.F,
|
||||
xIndexWithinCosetBits []frontend.Variable,
|
||||
arityBits uint64,
|
||||
evals []field.QuadraticExtension,
|
||||
beta field.QuadraticExtension,
|
||||
) field.QuadraticExtension {
|
||||
arity := 1 << arityBits
|
||||
if (len(evals)) != arity {
|
||||
panic("len(evals) ! arity")
|
||||
}
|
||||
if arityBits > 8 {
|
||||
panic("currently assuming that arityBits is <= 8")
|
||||
}
|
||||
|
||||
g := field.GoldilocksPrimitiveRootOfUnity(arityBits)
|
||||
gInv := goldilocks.NewElement(0)
|
||||
gInv.Exp(g, big.NewInt(int64(arity-1)))
|
||||
|
||||
// The evaluation vector needs to be reordered first. Permute the evals array such that each
|
||||
// element's new index is the bit reverse of it's original index.
|
||||
// TODO: Optimization - Since the size of the evals array should be constant (e.g. 2^arityBits),
|
||||
// we can just hard code the permutation.
|
||||
permutedEvals := make([]field.QuadraticExtension, len(evals))
|
||||
for i := uint8(0); i < uint8(len(evals)); i++ {
|
||||
newIndex := bits.Reverse8(i) >> arityBits
|
||||
permutedEvals[newIndex] = evals[i]
|
||||
}
|
||||
|
||||
// Want `g^(arity - rev_x_index_within_coset)` as in the out-of-circuit version. Compute it
|
||||
// as `(g^-1)^rev_x_index_within_coset`.
|
||||
revXIndexWithinCosetBits := make([]frontend.Variable, len(xIndexWithinCosetBits))
|
||||
for i := 0; i < len(xIndexWithinCosetBits); i++ {
|
||||
revXIndexWithinCosetBits[len(xIndexWithinCosetBits)-1-i] = xIndexWithinCosetBits[i]
|
||||
}
|
||||
start := f.expFromBitsConstBase(gInv, revXIndexWithinCosetBits)
|
||||
cosetStart := f.fieldAPI.Mul(start, x).(field.F)
|
||||
|
||||
xPoints := make([]field.QuadraticExtension, len(evals))
|
||||
yPoints := permutedEvals
|
||||
|
||||
// TODO: Make g_F a constant
|
||||
g_F := f.qeAPI.FieldToQE(field.NewFieldElement(g.Uint64()))
|
||||
xPoints[0] = f.qeAPI.FieldToQE(cosetStart)
|
||||
for i := 1; i < len(evals); i++ {
|
||||
xPoints[i] = f.qeAPI.MulExtension(xPoints[i-1], g_F)
|
||||
}
|
||||
|
||||
// TODO: This is n^2. Is there a way to do this better?
|
||||
// Compute the barycentric weights
|
||||
barycentricWeights := make([]field.QuadraticExtension, len(xPoints))
|
||||
for i := 0; i < len(xPoints); i++ {
|
||||
barycentricWeights[i] = f.qeAPI.ONE_QE
|
||||
for j := 0; j < len(xPoints); j++ {
|
||||
if i != j {
|
||||
barycentricWeights[i] = f.qeAPI.MulExtension(
|
||||
f.qeAPI.SubExtension(xPoints[i], xPoints[j]),
|
||||
barycentricWeights[i],
|
||||
)
|
||||
}
|
||||
}
|
||||
// Take the inverse of the barycentric weights
|
||||
// TODO: Can provide a witness to this value
|
||||
barycentricWeights[i] = f.qeAPI.InverseExtension(barycentricWeights[i])
|
||||
}
|
||||
|
||||
return f.interpolate(beta, xPoints, yPoints, barycentricWeights)
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyQueryRound(
|
||||
instance FriInstanceInfo,
|
||||
challenges *common.FriChallenges,
|
||||
precomputedReducedEval []field.QuadraticExtension,
|
||||
initialMerkleCaps []common.MerkleCap,
|
||||
proof *common.FriProof,
|
||||
xIndex field.F,
|
||||
n uint64,
|
||||
nLog uint64,
|
||||
roundProof *common.FriQueryRound,
|
||||
) {
|
||||
f.assertNoncanonicalIndicesOK()
|
||||
xIndexBits := f.fieldAPI.ToBinary(xIndex, int(nLog))
|
||||
capIndexBits := xIndexBits[len(xIndexBits)-int(f.friParams.Config.CapHeight):]
|
||||
|
||||
f.verifyInitialProof(xIndexBits, &roundProof.InitialTreesProof, initialMerkleCaps, capIndexBits)
|
||||
|
||||
subgroupX := f.calculateSubgroupX(
|
||||
xIndexBits,
|
||||
nLog,
|
||||
)
|
||||
|
||||
subgroupX_QE := field.QuadraticExtension{subgroupX, field.ZERO_F}
|
||||
|
||||
oldEval := f.friCombineInitial(
|
||||
instance,
|
||||
roundProof.InitialTreesProof,
|
||||
challenges.FriAlpha,
|
||||
subgroupX_QE,
|
||||
precomputedReducedEval,
|
||||
)
|
||||
|
||||
for i, arityBits := range f.friParams.ReductionArityBits {
|
||||
evals := roundProof.Steps[i].Evals
|
||||
|
||||
cosetIndexBits := xIndexBits[arityBits:]
|
||||
xIndexWithinCosetBits := xIndexBits[:arityBits]
|
||||
|
||||
// Assumes that the arity bits will be 4. That means that the range of
|
||||
// xIndexWithCoset is [0,2^4-1]. This is based on plonky2's circuit recursive
|
||||
// config: https://github.com/mir-protocol/plonky2/blob/main/plonky2/src/plonk/circuit_data.rs#L63
|
||||
// Will use a two levels tree of 4-selector gadgets.
|
||||
if arityBits != 4 {
|
||||
panic("assuming arity bits is 4")
|
||||
}
|
||||
|
||||
const NUM_LEAF_LOOKUPS = 4
|
||||
var leafLookups [NUM_LEAF_LOOKUPS]field.QuadraticExtension
|
||||
// First create the "leaf" lookup2 circuits
|
||||
// The will use the least significant bits of the xIndexWithCosetBits array
|
||||
for i := 0; i < NUM_LEAF_LOOKUPS; i++ {
|
||||
leafLookups[i] = f.qeAPI.Lookup2(
|
||||
xIndexWithinCosetBits[0],
|
||||
xIndexWithinCosetBits[1],
|
||||
evals[i*NUM_LEAF_LOOKUPS],
|
||||
evals[i*NUM_LEAF_LOOKUPS+1],
|
||||
evals[i*NUM_LEAF_LOOKUPS+2],
|
||||
evals[i*NUM_LEAF_LOOKUPS+3],
|
||||
)
|
||||
}
|
||||
|
||||
// Use the most 2 significant bits of the xIndexWithCosetBits array for the "root" lookup
|
||||
newEval := f.qeAPI.Lookup2(
|
||||
xIndexWithinCosetBits[2],
|
||||
xIndexWithinCosetBits[3],
|
||||
leafLookups[0],
|
||||
leafLookups[1],
|
||||
leafLookups[2],
|
||||
leafLookups[3],
|
||||
)
|
||||
|
||||
f.qeAPI.AssertIsEqual(newEval, oldEval)
|
||||
|
||||
oldEval = f.computeEvaluation(
|
||||
subgroupX,
|
||||
xIndexWithinCosetBits,
|
||||
arityBits,
|
||||
evals,
|
||||
challenges.FriBetas[i],
|
||||
)
|
||||
|
||||
// Convert evals (array of QE) to fields by taking their 0th degree coefficients
|
||||
fieldEvals := make([]field.F, 0, 2*len(evals))
|
||||
for j := 0; j < len(evals); j++ {
|
||||
fieldEvals = append(fieldEvals, evals[j][0])
|
||||
fieldEvals = append(fieldEvals, evals[j][1])
|
||||
}
|
||||
f.verifyMerkleProofToCapWithCapIndex(
|
||||
fieldEvals,
|
||||
cosetIndexBits,
|
||||
capIndexBits,
|
||||
proof.CommitPhaseMerkleCaps[i],
|
||||
&roundProof.Steps[i].MerkleProof,
|
||||
)
|
||||
|
||||
// Update the point x to x^arity.
|
||||
for j := uint64(0); j < arityBits; j++ {
|
||||
subgroupX = f.fieldAPI.Mul(subgroupX, subgroupX).(field.F)
|
||||
}
|
||||
|
||||
xIndexBits = cosetIndexBits
|
||||
}
|
||||
|
||||
subgroupX_QE = f.qeAPI.FieldToQE(subgroupX)
|
||||
finalPolyEval := f.finalPolyEval(proof.FinalPoly, subgroupX_QE)
|
||||
|
||||
f.qeAPI.AssertIsEqual(oldEval, finalPolyEval)
|
||||
}
|
||||
|
||||
func (f *FriChip) VerifyFriProof(
|
||||
instance FriInstanceInfo,
|
||||
openings FriOpenings,
|
||||
friChallenges *common.FriChallenges,
|
||||
initialMerkleCaps []common.MerkleCap,
|
||||
friProof *common.FriProof,
|
||||
) {
|
||||
// TODO: Check fri config
|
||||
/* if let Some(max_arity_bits) = params.max_arity_bits() {
|
||||
self.check_recursion_config::<C>(max_arity_bits);
|
||||
}
|
||||
|
||||
debug_assert_eq!(
|
||||
params.final_poly_len(),
|
||||
proof.final_poly.len(),
|
||||
"Final polynomial has wrong degree."
|
||||
); */
|
||||
|
||||
// Check POW
|
||||
f.assertLeadingZeros(friChallenges.FriPowResponse, f.friParams.Config)
|
||||
|
||||
precomputedReducedEvals := f.fromOpeningsAndAlpha(&openings, friChallenges.FriAlpha)
|
||||
|
||||
// Size of the LDE domain.
|
||||
nLog := f.friParams.DegreeBits + f.friParams.Config.RateBits
|
||||
n := uint64(math.Pow(2, float64(nLog)))
|
||||
|
||||
if len(friChallenges.FriQueryIndices) != len(friProof.QueryRoundProofs) {
|
||||
panic(fmt.Sprintf(
|
||||
"Number of query indices (%d) should equal number of query round proofs (%d)",
|
||||
len(friChallenges.FriQueryIndices),
|
||||
len(friProof.QueryRoundProofs),
|
||||
))
|
||||
}
|
||||
|
||||
for idx, xIndex := range friChallenges.FriQueryIndices {
|
||||
roundProof := friProof.QueryRoundProofs[idx]
|
||||
|
||||
f.verifyQueryRound(
|
||||
instance,
|
||||
friChallenges,
|
||||
precomputedReducedEvals,
|
||||
initialMerkleCaps,
|
||||
friProof,
|
||||
xIndex,
|
||||
n,
|
||||
nLog,
|
||||
&roundProof,
|
||||
)
|
||||
}
|
||||
}
|
||||
188
verifier/internal/fri/fri_test.go
Normal file
188
verifier/internal/fri/fri_test.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package fri_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestFriCircuit struct {
|
||||
proofWithPIsFilename string `gnark:"-"`
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
verifierOnlyCircuitDataFilename string `gnark:"-"`
|
||||
|
||||
plonkZeta field.QuadraticExtension
|
||||
friAlpha field.QuadraticExtension
|
||||
friBetas []field.QuadraticExtension
|
||||
friPOWResponse field.F
|
||||
friQueryIndices []field.F
|
||||
}
|
||||
|
||||
func (circuit *TestFriCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename)
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename)
|
||||
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename)
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
|
||||
hashAPI := poseidon.NewHashAPI(fieldAPI)
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
|
||||
friChip := fri.NewFriChip(api, fieldAPI, qeAPI, hashAPI, poseidonChip, &commonCircuitData.FriParams)
|
||||
|
||||
friChallenges := common.FriChallenges{
|
||||
FriAlpha: circuit.friAlpha,
|
||||
FriBetas: circuit.friBetas,
|
||||
FriPowResponse: circuit.friPOWResponse,
|
||||
FriQueryIndices: circuit.friQueryIndices,
|
||||
}
|
||||
|
||||
initialMerkleCaps := []common.MerkleCap{
|
||||
verifierOnlyCircuitData.ConstantSigmasCap,
|
||||
proofWithPis.Proof.WiresCap,
|
||||
proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
proofWithPis.Proof.QuotientPolysCap,
|
||||
}
|
||||
|
||||
friChip.VerifyFriProof(
|
||||
fri.GetFriInstance(&commonCircuitData, qeAPI, circuit.plonkZeta, commonCircuitData.DegreeBits),
|
||||
fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
&friChallenges,
|
||||
initialMerkleCaps,
|
||||
&proofWithPis.Proof.OpeningProof,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFibonacciFriProof(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestFriCircuit{
|
||||
proofWithPIsFilename: "./data/fibonacci/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/fibonacci/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/fibonacci/verifier_only_circuit_data.json",
|
||||
plonkZeta: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("14887793628029982930"),
|
||||
field.NewFieldElementFromString("1136137158284059037"),
|
||||
},
|
||||
friAlpha: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("14641715242626918707"),
|
||||
field.NewFieldElementFromString("10574243340537902930"),
|
||||
},
|
||||
friBetas: []field.QuadraticExtension{},
|
||||
friPOWResponse: field.NewFieldElement(82451580476419),
|
||||
friQueryIndices: []field.F{
|
||||
field.NewFieldElement(6790812084677375942),
|
||||
field.NewFieldElement(12394212020331474798),
|
||||
field.NewFieldElement(16457600747000998582),
|
||||
field.NewFieldElement(1543271328932331916),
|
||||
field.NewFieldElement(12115726870906958644),
|
||||
field.NewFieldElement(6775897107605342797),
|
||||
field.NewFieldElement(15989401564746021030),
|
||||
field.NewFieldElement(10691676456016926845),
|
||||
field.NewFieldElement(1632499470630032007),
|
||||
field.NewFieldElement(1317292355445098328),
|
||||
field.NewFieldElement(18391440812534384252),
|
||||
field.NewFieldElement(17321705613231354333),
|
||||
field.NewFieldElement(6176487551308859603),
|
||||
field.NewFieldElement(7119835651572002873),
|
||||
field.NewFieldElement(3903019169623116693),
|
||||
field.NewFieldElement(4886491111111487546),
|
||||
field.NewFieldElement(4087641893164620518),
|
||||
field.NewFieldElement(13801643080324181364),
|
||||
field.NewFieldElement(16993775312274189321),
|
||||
field.NewFieldElement(9268202926222765679),
|
||||
field.NewFieldElement(10683001302406181735),
|
||||
field.NewFieldElement(13359465725531647963),
|
||||
field.NewFieldElement(4523327590105620849),
|
||||
field.NewFieldElement(4883588003760409588),
|
||||
field.NewFieldElement(187699146998097671),
|
||||
field.NewFieldElement(14489263557623716717),
|
||||
field.NewFieldElement(11748359318238148146),
|
||||
field.NewFieldElement(13636347200053048758),
|
||||
},
|
||||
}
|
||||
witness := TestFriCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
|
||||
func TestDummyFriProof(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestFriCircuit{
|
||||
proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json",
|
||||
plonkZeta: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("17377750363769967882"),
|
||||
field.NewFieldElementFromString("11921191651424768462"),
|
||||
},
|
||||
friAlpha: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("16721004555774385479"),
|
||||
field.NewFieldElementFromString("10688151135543754663"),
|
||||
},
|
||||
friBetas: []field.QuadraticExtension{
|
||||
{
|
||||
field.NewFieldElementFromString("3312441922957827805"),
|
||||
field.NewFieldElementFromString("15128092514958289671"),
|
||||
},
|
||||
{
|
||||
field.NewFieldElementFromString("13630530769060141802"),
|
||||
field.NewFieldElementFromString("14559883974933163008"),
|
||||
},
|
||||
{
|
||||
field.NewFieldElementFromString("16146508250083930687"),
|
||||
field.NewFieldElementFromString("5176346568444408396"),
|
||||
},
|
||||
},
|
||||
friPOWResponse: field.NewFieldElement(4389),
|
||||
friQueryIndices: []field.F{
|
||||
field.NewFieldElementFromString("16334967868590615051"),
|
||||
field.NewFieldElementFromString("2911473540496037915"),
|
||||
field.NewFieldElementFromString("14887216056886344225"),
|
||||
field.NewFieldElementFromString("7808811227805914295"),
|
||||
field.NewFieldElementFromString("2018594961417375749"),
|
||||
field.NewFieldElementFromString("3733368398777208435"),
|
||||
field.NewFieldElementFromString("2623035669037055104"),
|
||||
field.NewFieldElementFromString("299243030573481514"),
|
||||
field.NewFieldElementFromString("7189789717962704433"),
|
||||
field.NewFieldElementFromString("14566344026886816268"),
|
||||
field.NewFieldElementFromString("12555390069003437453"),
|
||||
field.NewFieldElementFromString("17225508403199418233"),
|
||||
field.NewFieldElementFromString("5088797913879903292"),
|
||||
field.NewFieldElementFromString("9715691392773433023"),
|
||||
field.NewFieldElementFromString("7565836764713256165"),
|
||||
field.NewFieldElementFromString("1500143546029322929"),
|
||||
field.NewFieldElementFromString("1245802417104422080"),
|
||||
field.NewFieldElementFromString("6831959786661245110"),
|
||||
field.NewFieldElementFromString("17271054758535453780"),
|
||||
field.NewFieldElementFromString("6225460404576395409"),
|
||||
field.NewFieldElementFromString("15932661092896277351"),
|
||||
field.NewFieldElementFromString("12452534049198240575"),
|
||||
field.NewFieldElementFromString("4225199666055520177"),
|
||||
field.NewFieldElementFromString("13235091290587791090"),
|
||||
field.NewFieldElementFromString("2562357622728700774"),
|
||||
field.NewFieldElementFromString("17676678042980201498"),
|
||||
field.NewFieldElementFromString("5837067135702409874"),
|
||||
field.NewFieldElementFromString("11238419549114325157"),
|
||||
},
|
||||
}
|
||||
witness := TestFriCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
199
verifier/internal/fri/fri_utils.go
Normal file
199
verifier/internal/fri/fri_utils.go
Normal file
@@ -0,0 +1,199 @@
|
||||
package fri
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
)
|
||||
|
||||
type FriOpeningBatch struct {
|
||||
Values []field.QuadraticExtension
|
||||
}
|
||||
|
||||
type FriOpenings struct {
|
||||
Batches []FriOpeningBatch
|
||||
}
|
||||
|
||||
func ToFriOpenings(c common.OpeningSet) FriOpenings {
|
||||
values := c.Constants // num_constants + 1
|
||||
values = append(values, c.PlonkSigmas...) // num_routed_wires
|
||||
values = append(values, c.Wires...) // num_wires
|
||||
values = append(values, c.PlonkZs...) // num_challenges
|
||||
values = append(values, c.PartialProducts...) // num_challenges * num_partial_products
|
||||
values = append(values, c.QuotientPolys...) // num_challenges * quotient_degree_factor
|
||||
zetaBatch := FriOpeningBatch{Values: values}
|
||||
zetaNextBatch := FriOpeningBatch{Values: c.PlonkZsNext}
|
||||
return FriOpenings{Batches: []FriOpeningBatch{zetaBatch, zetaNextBatch}}
|
||||
}
|
||||
|
||||
type FriPolynomialInfo struct {
|
||||
OracleIndex uint64
|
||||
PolynomialInfo uint64
|
||||
}
|
||||
|
||||
type FriOracleInfo struct {
|
||||
NumPolys uint64
|
||||
Blinding bool
|
||||
}
|
||||
|
||||
type FriBatchInfo struct {
|
||||
Point field.QuadraticExtension
|
||||
Polynomials []FriPolynomialInfo
|
||||
}
|
||||
|
||||
type FriInstanceInfo struct {
|
||||
Oracles []FriOracleInfo
|
||||
Batches []FriBatchInfo
|
||||
}
|
||||
|
||||
type PlonkOracle struct {
|
||||
index uint64
|
||||
blinding bool
|
||||
}
|
||||
|
||||
var CONSTANTS_SIGMAS = PlonkOracle{
|
||||
index: 0,
|
||||
blinding: false,
|
||||
}
|
||||
|
||||
var WIRES = PlonkOracle{
|
||||
index: 1,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
var ZS_PARTIAL_PRODUCTS = PlonkOracle{
|
||||
index: 2,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
var QUOTIENT = PlonkOracle{
|
||||
index: 3,
|
||||
blinding: true,
|
||||
}
|
||||
|
||||
func polynomialInfoFromRange(c *common.CommonCircuitData, oracleIdx uint64, startPolyIdx uint64, endPolyIdx uint64) []FriPolynomialInfo {
|
||||
returnArr := make([]FriPolynomialInfo, 0)
|
||||
for i := startPolyIdx; i < endPolyIdx; i++ {
|
||||
returnArr = append(returnArr,
|
||||
FriPolynomialInfo{
|
||||
OracleIndex: oracleIdx,
|
||||
PolynomialInfo: i,
|
||||
})
|
||||
}
|
||||
|
||||
return returnArr
|
||||
}
|
||||
|
||||
// Range of the sigma polynomials in the `constants_sigmas_commitment`.
|
||||
func sigmasRange(c *common.CommonCircuitData) []uint64 {
|
||||
returnArr := make([]uint64, 0)
|
||||
for i := c.NumConstants; i <= c.NumConstants+c.Config.NumRoutedWires; i++ {
|
||||
returnArr = append(returnArr, i)
|
||||
}
|
||||
|
||||
return returnArr
|
||||
}
|
||||
|
||||
func numPreprocessedPolys(c *common.CommonCircuitData) uint64 {
|
||||
sigmasRange := sigmasRange(c)
|
||||
return sigmasRange[len(sigmasRange)-1]
|
||||
}
|
||||
|
||||
func numZSPartialProductsPolys(c *common.CommonCircuitData) uint64 {
|
||||
return c.Config.NumChallenges * (1 + c.NumPartialProducts)
|
||||
}
|
||||
|
||||
func numQuotientPolys(c *common.CommonCircuitData) uint64 {
|
||||
return c.Config.NumChallenges * c.QuotientDegreeFactor
|
||||
}
|
||||
|
||||
func friPreprocessedPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
CONSTANTS_SIGMAS.index,
|
||||
0,
|
||||
numPreprocessedPolys(c),
|
||||
)
|
||||
}
|
||||
|
||||
func friWirePolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
numWirePolys := c.Config.NumWires
|
||||
return polynomialInfoFromRange(c, WIRES.index, 0, numWirePolys)
|
||||
}
|
||||
|
||||
func friZSPartialProductsPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
ZS_PARTIAL_PRODUCTS.index,
|
||||
0,
|
||||
numZSPartialProductsPolys(c),
|
||||
)
|
||||
}
|
||||
|
||||
func friQuotientPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
QUOTIENT.index,
|
||||
0,
|
||||
numQuotientPolys(c),
|
||||
)
|
||||
}
|
||||
|
||||
func friZSPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
return polynomialInfoFromRange(
|
||||
c,
|
||||
ZS_PARTIAL_PRODUCTS.index,
|
||||
0,
|
||||
c.Config.NumChallenges,
|
||||
)
|
||||
}
|
||||
|
||||
func friOracles(c *common.CommonCircuitData) []FriOracleInfo {
|
||||
return []FriOracleInfo{
|
||||
{
|
||||
NumPolys: numPreprocessedPolys(c),
|
||||
Blinding: CONSTANTS_SIGMAS.blinding,
|
||||
},
|
||||
{
|
||||
NumPolys: c.Config.NumWires,
|
||||
Blinding: WIRES.blinding,
|
||||
},
|
||||
{
|
||||
NumPolys: numZSPartialProductsPolys(c),
|
||||
Blinding: ZS_PARTIAL_PRODUCTS.blinding,
|
||||
},
|
||||
{
|
||||
NumPolys: numQuotientPolys(c),
|
||||
Blinding: QUOTIENT.blinding,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func friAllPolys(c *common.CommonCircuitData) []FriPolynomialInfo {
|
||||
returnArr := make([]FriPolynomialInfo, 0)
|
||||
returnArr = append(returnArr, friPreprocessedPolys(c)...)
|
||||
returnArr = append(returnArr, friWirePolys(c)...)
|
||||
returnArr = append(returnArr, friZSPartialProductsPolys(c)...)
|
||||
returnArr = append(returnArr, friQuotientPolys(c)...)
|
||||
|
||||
return returnArr
|
||||
}
|
||||
|
||||
func GetFriInstance(c *common.CommonCircuitData, qeAPI *field.QuadraticExtensionAPI, zeta field.QuadraticExtension, degreeBits uint64) FriInstanceInfo {
|
||||
zetaBatch := FriBatchInfo{
|
||||
Point: zeta,
|
||||
Polynomials: friAllPolys(c),
|
||||
}
|
||||
|
||||
g := field.GoldilocksPrimitiveRootOfUnity(degreeBits)
|
||||
zetaNext := qeAPI.MulExtension(qeAPI.FieldToQE(field.NewFieldElement(g.Uint64())), zeta)
|
||||
|
||||
zetaNextBath := FriBatchInfo{
|
||||
Point: zetaNext,
|
||||
Polynomials: friZSPolys(c),
|
||||
}
|
||||
|
||||
return FriInstanceInfo{
|
||||
Oracles: friOracles(c),
|
||||
Batches: []FriBatchInfo{zetaBatch, zetaNextBath},
|
||||
}
|
||||
}
|
||||
82
verifier/internal/gates/arithmetic_extension_gate.go
Normal file
82
verifier/internal/gates/arithmetic_extension_gate.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var aritheticExtensionGateRegex = regexp.MustCompile("ArithmeticExtensionGate { num_ops: (?P<numOps>[0-9]+) }")
|
||||
|
||||
func deserializeExtensionArithmeticGate(parameters map[string]string) Gate {
|
||||
// Has the format "ArithmeticExtensionGate { num_ops: 10 }"
|
||||
numOps, hasNumOps := parameters["numOps"]
|
||||
if !hasNumOps {
|
||||
panic("Missing field num_ops in ArithmeticExtensionGate")
|
||||
}
|
||||
|
||||
numOpsInt, err := strconv.Atoi(numOps)
|
||||
if err != nil {
|
||||
panic("Invalid num_ops field in ArithmeticExtensionGate")
|
||||
}
|
||||
|
||||
return NewArithmeticExtensionGate(uint64(numOpsInt))
|
||||
}
|
||||
|
||||
type ArithmeticExtensionGate struct {
|
||||
numOps uint64
|
||||
}
|
||||
|
||||
func NewArithmeticExtensionGate(numOps uint64) *ArithmeticExtensionGate {
|
||||
return &ArithmeticExtensionGate{
|
||||
numOps: numOps,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) Id() string {
|
||||
return fmt.Sprintf("ArithmeticExtensionGate { num_ops: %d }", g.numOps)
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthMultiplicand0(i uint64) Range {
|
||||
return Range{4 * field.D * i, 4*field.D*i + field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthMultiplicand1(i uint64) Range {
|
||||
return Range{4*field.D*i + field.D, 4*field.D*i + 2*field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthAddend(i uint64) Range {
|
||||
return Range{4*field.D*i + 2*field.D, 4*field.D*i + 3*field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) wiresIthOutput(i uint64) Range {
|
||||
return Range{4*field.D*i + 3*field.D, 4*field.D*i + 4*field.D}
|
||||
}
|
||||
|
||||
func (g *ArithmeticExtensionGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
const0 := vars.localConstants[0]
|
||||
const1 := vars.localConstants[1]
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.numOps; i++ {
|
||||
multiplicand0 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand0(i))
|
||||
multiplicand1 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand1(i))
|
||||
addend := vars.GetLocalExtAlgebra(g.wiresIthAddend(i))
|
||||
output := vars.GetLocalExtAlgebra(g.wiresIthOutput(i))
|
||||
|
||||
mul := qeAPI.MulExtensionAlgebra(multiplicand0, multiplicand1)
|
||||
scaled_mul := qeAPI.ScalarMulExtensionAlgebra(const0, mul)
|
||||
computed_output := qeAPI.ScalarMulExtensionAlgebra(const1, addend)
|
||||
computed_output = qeAPI.AddExtensionAlgebra(computed_output, scaled_mul)
|
||||
|
||||
diff := qeAPI.SubExtensionAlgebra(output, computed_output)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, diff[j])
|
||||
}
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
80
verifier/internal/gates/arithmetic_gate.go
Normal file
80
verifier/internal/gates/arithmetic_gate.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var aritheticGateRegex = regexp.MustCompile("ArithmeticGate { num_ops: (?P<numOps>[0-9]+) }")
|
||||
|
||||
func deserializeArithmeticGate(parameters map[string]string) Gate {
|
||||
// Has the format "ArithmeticGate { num_ops: 10 }"
|
||||
|
||||
numOps, hasNumOps := parameters["numOps"]
|
||||
if !hasNumOps {
|
||||
panic("no num_ops field in ArithmeticGate")
|
||||
}
|
||||
|
||||
numOpsInt, err := strconv.Atoi(numOps)
|
||||
if err != nil {
|
||||
panic("Invalid num_ops field in ArithmeticGate")
|
||||
}
|
||||
|
||||
return NewArithmeticGate(uint64(numOpsInt))
|
||||
}
|
||||
|
||||
type ArithmeticGate struct {
|
||||
numOps uint64
|
||||
}
|
||||
|
||||
func NewArithmeticGate(numOps uint64) *ArithmeticGate {
|
||||
return &ArithmeticGate{
|
||||
numOps: numOps,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) Id() string {
|
||||
return fmt.Sprintf("ArithmeticGate { num_ops: %d }", g.numOps)
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthMultiplicand0(i uint64) uint64 {
|
||||
return 4 * i
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthMultiplicand1(i uint64) uint64 {
|
||||
return 4*i + 1
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthAddend(i uint64) uint64 {
|
||||
return 4*i + 2
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) WireIthOutput(i uint64) uint64 {
|
||||
return 4*i + 3
|
||||
}
|
||||
|
||||
func (g *ArithmeticGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
const0 := vars.localConstants[0]
|
||||
const1 := vars.localConstants[1]
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.numOps; i++ {
|
||||
multiplicand0 := vars.localWires[g.WireIthMultiplicand0(i)]
|
||||
multiplicand1 := vars.localWires[g.WireIthMultiplicand1(i)]
|
||||
addend := vars.localWires[g.WireIthAddend(i)]
|
||||
output := vars.localWires[g.WireIthOutput(i)]
|
||||
|
||||
computedOutput := qeAPI.AddExtension(
|
||||
qeAPI.MulExtension(qeAPI.MulExtension(multiplicand0, multiplicand1), const0),
|
||||
qeAPI.MulExtension(addend, const1),
|
||||
)
|
||||
|
||||
constraints = append(constraints, qeAPI.SubExtension(output, computedOutput))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
92
verifier/internal/gates/base_sum_gate.go
Normal file
92
verifier/internal/gates/base_sum_gate.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var baseSumGateRegex = regexp.MustCompile(`BaseSumGate { num_limbs: (?P<numLimbs>[0-9]+) } \+ Base: (?P<base>[0-9]+)`)
|
||||
|
||||
func deserializeBaseSumGate(parameters map[string]string) Gate {
|
||||
|
||||
// Has the format "BaseSumGate { num_limbs: 32 } + Base: 2"
|
||||
numLimbs, hasNumLimbs := parameters["numLimbs"]
|
||||
base, hasBase := parameters["base"]
|
||||
if !hasNumLimbs || !hasBase {
|
||||
panic("Missing field num_limbs or base in BaseSumGate")
|
||||
}
|
||||
|
||||
numLimbsInt, err := strconv.Atoi(numLimbs)
|
||||
if err != nil {
|
||||
panic("Invalid num_limbs field in BaseSumGate")
|
||||
}
|
||||
|
||||
baseInt, err := strconv.Atoi(base)
|
||||
if err != nil {
|
||||
panic("Invalid base field in BaseSumGate")
|
||||
}
|
||||
|
||||
return NewBaseSumGate(uint64(numLimbsInt), uint64(baseInt))
|
||||
}
|
||||
|
||||
const (
|
||||
BASESUM_GATE_WIRE_SUM = 0
|
||||
BASESUM_GATE_START_LIMBS = 1
|
||||
)
|
||||
|
||||
type BaseSumGate struct {
|
||||
numLimbs uint64
|
||||
base uint64
|
||||
}
|
||||
|
||||
func NewBaseSumGate(numLimbs uint64, base uint64) *BaseSumGate {
|
||||
return &BaseSumGate{
|
||||
numLimbs: numLimbs,
|
||||
base: base,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *BaseSumGate) Id() string {
|
||||
return fmt.Sprintf("BaseSumGate { num_ops: %d } + Base: %d", g.numLimbs, g.base)
|
||||
}
|
||||
|
||||
func (g *BaseSumGate) limbs() []uint64 {
|
||||
limbIndices := make([]uint64, g.numLimbs)
|
||||
for i := uint64(0); i < g.numLimbs; i++ {
|
||||
limbIndices[i] = uint64(BASESUM_GATE_START_LIMBS + i)
|
||||
}
|
||||
|
||||
return limbIndices
|
||||
}
|
||||
|
||||
func (g *BaseSumGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
sum := vars.localWires[BASESUM_GATE_WIRE_SUM]
|
||||
limbs := make([]field.QuadraticExtension, g.numLimbs)
|
||||
limbIndices := g.limbs()
|
||||
for i, limbIdx := range limbIndices {
|
||||
limbs[i] = vars.localWires[limbIdx]
|
||||
}
|
||||
|
||||
base_qe := qeAPI.FieldToQE(field.NewFieldElement(g.base))
|
||||
computedSum := qeAPI.ReduceWithPowers(
|
||||
limbs,
|
||||
base_qe,
|
||||
)
|
||||
|
||||
var constraints []field.QuadraticExtension
|
||||
constraints = append(constraints, qeAPI.SubExtension(computedSum, sum))
|
||||
for _, limb := range limbs {
|
||||
acc := qeAPI.ONE_QE
|
||||
for i := uint64(0); i < g.base; i++ {
|
||||
difference := qeAPI.SubExtension(limb, qeAPI.FieldToQE(field.NewFieldElement(i)))
|
||||
acc = qeAPI.MulExtension(acc, difference)
|
||||
}
|
||||
constraints = append(constraints, acc)
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
65
verifier/internal/gates/constant_gate.go
Normal file
65
verifier/internal/gates/constant_gate.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var constantGateRegex = regexp.MustCompile("ConstantGate { num_consts: (?P<numConsts>[0-9]+) }")
|
||||
|
||||
func deserializeConstantGate(parameters map[string]string) Gate {
|
||||
// Has the format "ConstantGate { num_consts: 2 }"
|
||||
numConsts, hasNumConsts := parameters["numConsts"]
|
||||
if !hasNumConsts {
|
||||
panic("Missing field num_consts in ConstantGate")
|
||||
}
|
||||
|
||||
numConstsInt, err := strconv.Atoi(numConsts)
|
||||
if err != nil {
|
||||
panic("Invalid num_consts field in ConstantGate")
|
||||
}
|
||||
|
||||
return NewConstantGate(uint64(numConstsInt))
|
||||
}
|
||||
|
||||
type ConstantGate struct {
|
||||
numConsts uint64
|
||||
}
|
||||
|
||||
func NewConstantGate(numConsts uint64) *ConstantGate {
|
||||
return &ConstantGate{
|
||||
numConsts: numConsts,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ConstantGate) Id() string {
|
||||
return fmt.Sprintf("ConstantGate { num_consts: %d }", g.numConsts)
|
||||
}
|
||||
|
||||
func (g *ConstantGate) ConstInput(i uint64) uint64 {
|
||||
if i > g.numConsts {
|
||||
panic("Invalid constant index")
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func (g *ConstantGate) WireOutput(i uint64) uint64 {
|
||||
if i > g.numConsts {
|
||||
panic("Invalid wire index")
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func (g *ConstantGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
for i := uint64(0); i < g.numConsts; i++ {
|
||||
constraints = append(constraints, qeAPI.SubExtension(vars.localConstants[g.ConstInput(i)], vars.localWires[g.WireOutput(i)]))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
215
verifier/internal/gates/coset_interpolation_gate.go
Normal file
215
verifier/internal/gates/coset_interpolation_gate.go
Normal file
@@ -0,0 +1,215 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/consensys/gnark-crypto/field/goldilocks"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var cosetInterpolationGateRegex = regexp.MustCompile(`CosetInterpolationGate { subgroup_bits: (?P<subgroupBits>[0-9]+), degree: (?P<degree>[0-9]+), barycentric_weights: \[(?P<barycentricWeights>[0-9, ]+)\], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>`)
|
||||
|
||||
func deserializeCosetInterpolationGate(parameters map[string]string) Gate {
|
||||
// Has the format CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
||||
subgroupBits, hasSubgroupBits := parameters["subgroupBits"]
|
||||
degree, hasDegree := parameters["degree"]
|
||||
barycentricWeights, hasBarycentricWeights := parameters["barycentricWeights"]
|
||||
|
||||
if !hasSubgroupBits || !hasDegree || !hasBarycentricWeights {
|
||||
panic("missing subgroupBits, degree or barycentricWeights in CosetInterpolationGate")
|
||||
}
|
||||
|
||||
subgroupBitsInt, err := strconv.ParseUint(subgroupBits, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid subgroupBits in CosetInterpolationGate")
|
||||
}
|
||||
|
||||
degreeInt, err := strconv.ParseUint(degree, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid degree in CosetInterpolationGate")
|
||||
}
|
||||
|
||||
barycentricWeightsStr := strings.Split(barycentricWeights, ",")
|
||||
barycentricWeightsInt := make([]goldilocks.Element, len(barycentricWeightsStr))
|
||||
for i, barycentricWeightStr := range barycentricWeightsStr {
|
||||
barycentricWeightStr = strings.TrimSpace(barycentricWeightStr)
|
||||
barycentricWeightInt, err := strconv.ParseUint(barycentricWeightStr, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid barycentricWeights in CosetInterpolationGate")
|
||||
}
|
||||
barycentricWeightsInt[i].SetUint64(barycentricWeightInt)
|
||||
}
|
||||
|
||||
return NewCosetInterpolationGate(subgroupBitsInt, degreeInt, barycentricWeightsInt)
|
||||
}
|
||||
|
||||
type CosetInterpolationGate struct {
|
||||
subgroupBits uint64
|
||||
degree uint64
|
||||
barycentricWeights []goldilocks.Element
|
||||
}
|
||||
|
||||
func NewCosetInterpolationGate(subgroupBits uint64, degree uint64, barycentricWeights []goldilocks.Element) *CosetInterpolationGate {
|
||||
return &CosetInterpolationGate{
|
||||
subgroupBits: subgroupBits,
|
||||
degree: degree,
|
||||
barycentricWeights: barycentricWeights,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) Id() string {
|
||||
|
||||
return fmt.Sprintf(
|
||||
"CosetInterpolationGate { subgroup_bits: %d, degree: %d, barycentric_weights: %s }",
|
||||
g.subgroupBits,
|
||||
g.degree,
|
||||
fmt.Sprint(g.barycentricWeights),
|
||||
)
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) numPoints() uint64 {
|
||||
return 1 << g.subgroupBits
|
||||
}
|
||||
|
||||
// Wire index of the coset shift.
|
||||
func (g *CosetInterpolationGate) wireShift() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startValues() uint64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Wire indices of the `i`th interpolant value.
|
||||
func (g *CosetInterpolationGate) wiresValue(i uint64) Range {
|
||||
if i >= g.numPoints() {
|
||||
panic("Invalid point index")
|
||||
}
|
||||
start := g.startValues() + i*field.D
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startEvaluationPoint() uint64 {
|
||||
return g.startValues() + g.numPoints()*field.D
|
||||
}
|
||||
|
||||
// Wire indices of the point to evaluate the interpolant at.
|
||||
func (g *CosetInterpolationGate) wiresEvaluationPoint() Range {
|
||||
start := g.startEvaluationPoint()
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startEvaluationValue() uint64 {
|
||||
return g.startEvaluationPoint() + field.D
|
||||
}
|
||||
|
||||
// Wire indices of the interpolated value.
|
||||
func (g *CosetInterpolationGate) wiresEvaluationValue() Range {
|
||||
start := g.startEvaluationValue()
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) startIntermediates() uint64 {
|
||||
return g.startEvaluationValue() + field.D
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) numIntermediates() uint64 {
|
||||
return (g.numPoints() - 2) / (g.degree - 1)
|
||||
}
|
||||
|
||||
// The wires corresponding to the i'th intermediate evaluation.
|
||||
func (g *CosetInterpolationGate) wiresIntermediateEval(i uint64) Range {
|
||||
if i >= g.numIntermediates() {
|
||||
panic("Invalid intermediate index")
|
||||
}
|
||||
start := g.startIntermediates() + field.D*i
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
// The wires corresponding to the i'th intermediate product.
|
||||
func (g *CosetInterpolationGate) wiresIntermediateProd(i uint64) Range {
|
||||
if i >= g.numIntermediates() {
|
||||
panic("Invalid intermediate index")
|
||||
}
|
||||
start := g.startIntermediates() + field.D*(g.numIntermediates()+i)
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
// Wire indices of the shifted point to evaluate the interpolant at.
|
||||
func (g *CosetInterpolationGate) wiresShiftedEvaluationPoint() Range {
|
||||
start := g.startIntermediates() + field.D*2*g.numIntermediates()
|
||||
return Range{start, start + field.D}
|
||||
}
|
||||
|
||||
func (g *CosetInterpolationGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
shift := vars.localWires[g.wireShift()]
|
||||
evaluationPoint := vars.GetLocalExtAlgebra(g.wiresEvaluationPoint())
|
||||
shiftedEvaluationPoint := vars.GetLocalExtAlgebra(g.wiresShiftedEvaluationPoint())
|
||||
|
||||
negShift := qeAPI.ScalarMulExtension(shift, field.NEG_ONE_F)
|
||||
|
||||
tmp := qeAPI.ScalarMulExtensionAlgebra(negShift, shiftedEvaluationPoint)
|
||||
tmp = qeAPI.AddExtensionAlgebra(tmp, evaluationPoint)
|
||||
|
||||
for i := 0; i < field.D; i++ {
|
||||
constraints = append(constraints, tmp[i])
|
||||
}
|
||||
|
||||
domain := field.TwoAdicSubgroup(g.subgroupBits)
|
||||
values := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numPoints(); i++ {
|
||||
values = append(values, vars.GetLocalExtAlgebra(g.wiresValue(i)))
|
||||
}
|
||||
weights := g.barycentricWeights
|
||||
|
||||
initialEval := qeAPI.ZERO_QE_ALGEBRA
|
||||
initialProd := field.QEAlgebra{qeAPI.ONE_QE, qeAPI.ZERO_QE}
|
||||
computedEval, computedProd := qeAPI.PartialInterpolateExtAlgebra(
|
||||
domain[:g.degree],
|
||||
values[:g.degree],
|
||||
weights[:g.degree],
|
||||
shiftedEvaluationPoint,
|
||||
initialEval,
|
||||
initialProd,
|
||||
)
|
||||
|
||||
for i := uint64(0); i < g.numIntermediates(); i++ {
|
||||
intermediateEval := vars.GetLocalExtAlgebra(g.wiresIntermediateEval(i))
|
||||
intermediateProd := vars.GetLocalExtAlgebra(g.wiresIntermediateProd(i))
|
||||
|
||||
evalDiff := qeAPI.SubExtensionAlgebra(intermediateEval, computedEval)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, evalDiff[j])
|
||||
}
|
||||
|
||||
prodDiff := qeAPI.SubExtensionAlgebra(intermediateProd, computedProd)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, prodDiff[j])
|
||||
}
|
||||
|
||||
startIndex := 1 + (g.degree-1)*(i+1)
|
||||
endIndex := startIndex + g.degree - 1
|
||||
computedEval, computedProd = qeAPI.PartialInterpolateExtAlgebra(
|
||||
domain[startIndex:endIndex],
|
||||
values[startIndex:endIndex],
|
||||
weights[startIndex:endIndex],
|
||||
shiftedEvaluationPoint,
|
||||
intermediateEval,
|
||||
intermediateProd,
|
||||
)
|
||||
}
|
||||
|
||||
evaluationValue := vars.GetLocalExtAlgebra(g.wiresEvaluationValue())
|
||||
evalDiff := qeAPI.SubExtensionAlgebra(evaluationValue, computedEval)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, evalDiff[j])
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
104
verifier/internal/gates/evaluate_gates.go
Normal file
104
verifier/internal/gates/evaluate_gates.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
type EvaluateGatesChip struct {
|
||||
api frontend.API
|
||||
qeAPI *field.QuadraticExtensionAPI
|
||||
|
||||
gates []Gate
|
||||
numGateConstraints uint64
|
||||
|
||||
selectorsInfo SelectorsInfo
|
||||
}
|
||||
|
||||
func NewEvaluateGatesChip(
|
||||
api frontend.API,
|
||||
qeAPI *field.QuadraticExtensionAPI,
|
||||
gates []Gate,
|
||||
numGateConstraints uint64,
|
||||
selectorsInfo SelectorsInfo,
|
||||
) *EvaluateGatesChip {
|
||||
return &EvaluateGatesChip{
|
||||
api: api,
|
||||
qeAPI: qeAPI,
|
||||
|
||||
gates: gates,
|
||||
numGateConstraints: numGateConstraints,
|
||||
|
||||
selectorsInfo: selectorsInfo,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *EvaluateGatesChip) computeFilter(
|
||||
row uint64,
|
||||
groupRange Range,
|
||||
s field.QuadraticExtension,
|
||||
manySelector bool,
|
||||
) field.QuadraticExtension {
|
||||
product := g.qeAPI.ONE_QE
|
||||
for i := groupRange.start; i < groupRange.end; i++ {
|
||||
if i == uint64(row) {
|
||||
continue
|
||||
}
|
||||
|
||||
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldElement(i)), s))
|
||||
}
|
||||
|
||||
if manySelector {
|
||||
product = g.qeAPI.MulExtension(product, g.qeAPI.SubExtension(g.qeAPI.FieldToQE(field.NewFieldElement(UNUSED_SELECTOR)), s))
|
||||
}
|
||||
|
||||
return product
|
||||
}
|
||||
|
||||
func (g *EvaluateGatesChip) evalFiltered(
|
||||
gate Gate,
|
||||
vars EvaluationVars,
|
||||
row uint64,
|
||||
selectorIndex uint64,
|
||||
groupRange Range,
|
||||
numSelectors uint64,
|
||||
) []field.QuadraticExtension {
|
||||
filter := g.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1)
|
||||
|
||||
vars.RemovePrefix(numSelectors)
|
||||
|
||||
unfiltered := gate.EvalUnfiltered(g.api, g.qeAPI, vars)
|
||||
for i := range unfiltered {
|
||||
unfiltered[i] = g.qeAPI.MulExtension(unfiltered[i], filter)
|
||||
}
|
||||
return unfiltered
|
||||
}
|
||||
|
||||
func (g *EvaluateGatesChip) EvaluateGateConstraints(vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := make([]field.QuadraticExtension, g.numGateConstraints)
|
||||
for i := range constraints {
|
||||
constraints[i] = g.qeAPI.ZERO_QE
|
||||
}
|
||||
|
||||
for i, gate := range g.gates {
|
||||
selectorIndex := g.selectorsInfo.selectorIndices[i]
|
||||
|
||||
gateConstraints := g.evalFiltered(
|
||||
gate,
|
||||
vars,
|
||||
uint64(i),
|
||||
selectorIndex,
|
||||
g.selectorsInfo.groups[selectorIndex],
|
||||
g.selectorsInfo.NumSelectors(),
|
||||
)
|
||||
|
||||
for i, constraint := range gateConstraints {
|
||||
if uint64(i) >= g.numGateConstraints {
|
||||
panic("num_constraints() gave too low of a number")
|
||||
}
|
||||
constraints[i] = g.qeAPI.AddExtension(constraints[i], constraint)
|
||||
}
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
110
verifier/internal/gates/exponentiation_gate.go
Normal file
110
verifier/internal/gates/exponentiation_gate.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var exponentiationGateRegex = regexp.MustCompile("ExponentiationGate { num_power_bits: (?P<numPowerBits>[0-9]+), _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=(?P<base>[0-9]+)>")
|
||||
|
||||
func deserializeExponentiationGate(parameters map[string]string) Gate {
|
||||
// Has the format "ExponentiationGate { num_power_bits: 67, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
|
||||
numPowerBits, hasNumPowerBits := parameters["numPowerBits"]
|
||||
if !hasNumPowerBits {
|
||||
panic("Missing field num_power_bits in ExponentiationGate")
|
||||
}
|
||||
|
||||
numPowerBitsInt, err := strconv.Atoi(numPowerBits)
|
||||
if err != nil {
|
||||
panic("Invalid num_power_bits field in ExponentiationGate")
|
||||
}
|
||||
|
||||
return NewExponentiationGate(uint64(numPowerBitsInt))
|
||||
}
|
||||
|
||||
type ExponentiationGate struct {
|
||||
numPowerBits uint64
|
||||
}
|
||||
|
||||
func NewExponentiationGate(numPowerBits uint64) *ExponentiationGate {
|
||||
return &ExponentiationGate{
|
||||
numPowerBits: numPowerBits,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) Id() string {
|
||||
return fmt.Sprintf("ExponentiationGate { num_power_bits: %d }", g.numPowerBits)
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) wireBase() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// / The `i`th bit of the exponent, in little-endian order.
|
||||
func (g *ExponentiationGate) wirePowerBit(i uint64) uint64 {
|
||||
if i >= g.numPowerBits {
|
||||
panic("Invalid power bit index")
|
||||
}
|
||||
return 1 + i
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) wireOutput() uint64 {
|
||||
return 1 + g.numPowerBits
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) wireIntermediateValue(i uint64) uint64 {
|
||||
if i >= g.numPowerBits {
|
||||
panic("Invalid intermediate value index")
|
||||
}
|
||||
return 2 + g.numPowerBits + i
|
||||
}
|
||||
|
||||
func (g *ExponentiationGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
base := vars.localWires[g.wireBase()]
|
||||
|
||||
var powerBits []field.QuadraticExtension
|
||||
for i := uint64(0); i < g.numPowerBits; i++ {
|
||||
powerBits = append(powerBits, vars.localWires[g.wirePowerBit(i)])
|
||||
}
|
||||
|
||||
var intermediateValues []field.QuadraticExtension
|
||||
for i := uint64(0); i < g.numPowerBits; i++ {
|
||||
intermediateValues = append(intermediateValues, vars.localWires[g.wireIntermediateValue(i)])
|
||||
}
|
||||
|
||||
output := vars.localWires[g.wireOutput()]
|
||||
|
||||
var constraints []field.QuadraticExtension
|
||||
|
||||
for i := uint64(0); i < g.numPowerBits; i++ {
|
||||
var prevIntermediateValue field.QuadraticExtension
|
||||
if i == 0 {
|
||||
prevIntermediateValue = qeAPI.ONE_QE
|
||||
} else {
|
||||
prevIntermediateValue = qeAPI.SquareExtension(intermediateValues[i-1])
|
||||
}
|
||||
|
||||
// powerBits is in LE order, but we accumulate in BE order.
|
||||
curBit := powerBits[g.numPowerBits-i-1]
|
||||
|
||||
// Do a polynomial representation of generaized select (where the selector variable doesn't have to be binary)
|
||||
// if b { x } else { y }
|
||||
// i.e. `bx - (by-y)`.
|
||||
tmp := qeAPI.MulExtension(curBit, qeAPI.ONE_QE)
|
||||
tmp = qeAPI.SubExtension(tmp, qeAPI.ONE_QE)
|
||||
mulBy := qeAPI.MulExtension(curBit, base)
|
||||
mulBy = qeAPI.SubExtension(mulBy, tmp)
|
||||
intermediateValueDiff := qeAPI.MulExtension(prevIntermediateValue, mulBy)
|
||||
intermediateValueDiff = qeAPI.SubExtension(intermediateValueDiff, intermediateValues[i])
|
||||
constraints = append(constraints, intermediateValueDiff)
|
||||
}
|
||||
|
||||
outputDiff := qeAPI.SubExtension(output, intermediateValues[g.numPowerBits-1])
|
||||
constraints = append(constraints, outputDiff)
|
||||
|
||||
return constraints
|
||||
}
|
||||
49
verifier/internal/gates/gate.go
Normal file
49
verifier/internal/gates/gate.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
type Gate interface {
|
||||
Id() string
|
||||
EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension
|
||||
}
|
||||
|
||||
var gateRegexHandlers = map[*regexp.Regexp]func(parameters map[string]string) Gate{
|
||||
aritheticGateRegex: deserializeArithmeticGate,
|
||||
aritheticExtensionGateRegex: deserializeExtensionArithmeticGate,
|
||||
baseSumGateRegex: deserializeBaseSumGate,
|
||||
constantGateRegex: deserializeConstantGate,
|
||||
cosetInterpolationGateRegex: deserializeCosetInterpolationGate,
|
||||
exponentiationGateRegex: deserializeExponentiationGate,
|
||||
mulExtensionGateRegex: deserializeMulExtensionGate,
|
||||
noopGateRegex: deserializeNoopGate,
|
||||
poseidonGateRegex: deserializePoseidonGate,
|
||||
publicInputGateRegex: deserializePublicInputGate,
|
||||
randomAccessGateRegex: deserializeRandomAccessGate,
|
||||
reducingExtensionGateRegex: deserializeReducingExtensionGate,
|
||||
reducingGateRegex: deserializeReducingGate,
|
||||
}
|
||||
|
||||
func GateInstanceFromId(gateId string) Gate {
|
||||
for regex, handler := range gateRegexHandlers {
|
||||
matches := regex.FindStringSubmatch(gateId)
|
||||
if matches != nil {
|
||||
parameters := make(map[string]string)
|
||||
for i, name := range regex.SubexpNames() {
|
||||
if i != 0 && name != "" {
|
||||
parameters[name] = matches[i]
|
||||
}
|
||||
}
|
||||
|
||||
if matches != nil {
|
||||
return handler(parameters)
|
||||
}
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf("Unknown gate ID %s", gateId))
|
||||
}
|
||||
807
verifier/internal/gates/gate_test.go
Normal file
807
verifier/internal/gates/gate_test.go
Normal file
@@ -0,0 +1,807 @@
|
||||
package gates_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark-crypto/field/goldilocks"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
// From recursive_step circuit
|
||||
var localConstants = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(1164933405384298079), field.NewFieldElement(7438400583921661370)},
|
||||
{field.NewFieldElement(13151230530771189075), field.NewFieldElement(13023721207846057894)},
|
||||
{field.NewFieldElement(3881971040049882570), field.NewFieldElement(16581297326342691797)},
|
||||
{field.NewFieldElement(5184944824742294361), field.NewFieldElement(4925002013441838394)},
|
||||
{field.NewFieldElement(13156856690013129271), field.NewFieldElement(11795766134230417198)},
|
||||
}
|
||||
|
||||
var localWires = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(10289971018233574142), field.NewFieldElement(4567684908222573778)},
|
||||
{field.NewFieldElement(11564178579868812087), field.NewFieldElement(4510091545046358953)},
|
||||
{field.NewFieldElement(2427374067806073277), field.NewFieldElement(6911441533263492425)},
|
||||
{field.NewFieldElement(7693977127287585254), field.NewFieldElement(9885192257977663560)},
|
||||
{field.NewFieldElement(4829743769894031521), field.NewFieldElement(1070322096310857911)},
|
||||
{field.NewFieldElement(841614584488095356), field.NewFieldElement(3266720090708573245)},
|
||||
{field.NewFieldElement(9335841732020668562), field.NewFieldElement(7959135654284183511)},
|
||||
{field.NewFieldElement(16824107175117300959), field.NewFieldElement(14823581113270528881)},
|
||||
{field.NewFieldElement(4989727169526686805), field.NewFieldElement(6246956987038299573)},
|
||||
{field.NewFieldElement(17410065909497815114), field.NewFieldElement(226319705525892670)},
|
||||
{field.NewFieldElement(4568933895769710275), field.NewFieldElement(6430695446169305195)},
|
||||
{field.NewFieldElement(8067075753959020505), field.NewFieldElement(6018662820882606998)},
|
||||
{field.NewFieldElement(9927277077277524164), field.NewFieldElement(12530942893897967446)},
|
||||
{field.NewFieldElement(404931240594605346), field.NewFieldElement(13956134990453188947)},
|
||||
{field.NewFieldElement(12279755093013597997), field.NewFieldElement(13891866662848929655)},
|
||||
{field.NewFieldElement(3995291408937855383), field.NewFieldElement(7649506537726031013)},
|
||||
{field.NewFieldElement(1975344541433284175), field.NewFieldElement(11787783246524974192)},
|
||||
{field.NewFieldElement(9352725388265956899), field.NewFieldElement(1878641993746760905)},
|
||||
{field.NewFieldElement(4386025806925594020), field.NewFieldElement(7199468962263347888)},
|
||||
{field.NewFieldElement(457758515510439949), field.NewFieldElement(8295940174808817473)},
|
||||
{field.NewFieldElement(3721711968672629644), field.NewFieldElement(13268744315779792869)},
|
||||
{field.NewFieldElement(14873968601320376905), field.NewFieldElement(14469960382794471278)},
|
||||
{field.NewFieldElement(16643239035786323413), field.NewFieldElement(14266572255541493756)},
|
||||
{field.NewFieldElement(9756649839930289884), field.NewFieldElement(14084246204123262540)},
|
||||
{field.NewFieldElement(805087434192149117), field.NewFieldElement(5551650411462295908)},
|
||||
{field.NewFieldElement(3121050229008788536), field.NewFieldElement(315617444959225213)},
|
||||
{field.NewFieldElement(18164560008695666572), field.NewFieldElement(6915918288299894752)},
|
||||
{field.NewFieldElement(17656666988744688487), field.NewFieldElement(9787463123892858839)},
|
||||
{field.NewFieldElement(9992120570629943241), field.NewFieldElement(18182369503102252267)},
|
||||
{field.NewFieldElement(15220763248754170044), field.NewFieldElement(1854765527825350374)},
|
||||
{field.NewFieldElement(15616805521198580886), field.NewFieldElement(8948185005335797211)},
|
||||
{field.NewFieldElement(5104021995850318050), field.NewFieldElement(10884053699840350390)},
|
||||
{field.NewFieldElement(14387430073456386871), field.NewFieldElement(3987323970221931246)},
|
||||
{field.NewFieldElement(9295222033249226038), field.NewFieldElement(14533816739722288989)},
|
||||
{field.NewFieldElement(3054662272834320691), field.NewFieldElement(5799349468053737645)},
|
||||
{field.NewFieldElement(15410493100888282738), field.NewFieldElement(9030544573372043855)},
|
||||
{field.NewFieldElement(11448080360124361095), field.NewFieldElement(13429854637967689056)},
|
||||
{field.NewFieldElement(4779070979822400436), field.NewFieldElement(5404234368643419051)},
|
||||
{field.NewFieldElement(11659320767511898018), field.NewFieldElement(13702970547443564662)},
|
||||
{field.NewFieldElement(16340059712300851313), field.NewFieldElement(20171293486753699)},
|
||||
{field.NewFieldElement(1475826372470535678), field.NewFieldElement(1253469117109386509)},
|
||||
{field.NewFieldElement(7562163184139742598), field.NewFieldElement(14347739950500988111)},
|
||||
{field.NewFieldElement(15976520527988523610), field.NewFieldElement(17889280665602982933)},
|
||||
{field.NewFieldElement(8598539842276402160), field.NewFieldElement(2411306720494404310)},
|
||||
{field.NewFieldElement(15713704960139943242), field.NewFieldElement(16396602336341678687)},
|
||||
{field.NewFieldElement(7189190822731370344), field.NewFieldElement(5963822095937242833)},
|
||||
{field.NewFieldElement(5977752474999875040), field.NewFieldElement(5328103649776423975)},
|
||||
{field.NewFieldElement(12531991299101111394), field.NewFieldElement(3159886804356965397)},
|
||||
{field.NewFieldElement(16883082502877021850), field.NewFieldElement(4442238822519720348)},
|
||||
{field.NewFieldElement(4348679245531311390), field.NewFieldElement(6663472094175428592)},
|
||||
{field.NewFieldElement(7628612474113215133), field.NewFieldElement(9324555027165483004)},
|
||||
{field.NewFieldElement(1900695998785588032), field.NewFieldElement(12588745891116448183)},
|
||||
{field.NewFieldElement(2202928383842031597), field.NewFieldElement(2024867731300461655)},
|
||||
{field.NewFieldElement(9288136643086730543), field.NewFieldElement(4131544415785473139)},
|
||||
{field.NewFieldElement(14704106408467038509), field.NewFieldElement(8573856691828273)},
|
||||
{field.NewFieldElement(10154176515490297025), field.NewFieldElement(9220235036944332858)},
|
||||
{field.NewFieldElement(11339644645342271702), field.NewFieldElement(2591119884720569491)},
|
||||
{field.NewFieldElement(12952838693708363443), field.NewFieldElement(7634778748701478612)},
|
||||
{field.NewFieldElement(4151157005304656172), field.NewFieldElement(16778323503511515227)},
|
||||
{field.NewFieldElement(6326750425597671757), field.NewFieldElement(2556963653256638700)},
|
||||
{field.NewFieldElement(10167058989235599247), field.NewFieldElement(8755493046703376087)},
|
||||
{field.NewFieldElement(9610925836484089978), field.NewFieldElement(15994816336634155710)},
|
||||
{field.NewFieldElement(4153283843312210367), field.NewFieldElement(14936117891656525941)},
|
||||
{field.NewFieldElement(2708678512120193106), field.NewFieldElement(13963185898630435716)},
|
||||
{field.NewFieldElement(6555777227864205496), field.NewFieldElement(796547906377203466)},
|
||||
{field.NewFieldElement(9137905566620576524), field.NewFieldElement(5424975077133394401)},
|
||||
{field.NewFieldElement(10344710254569827655), field.NewFieldElement(5782463375043965385)},
|
||||
{field.NewFieldElement(5971898539021849982), field.NewFieldElement(8119512366912747083)},
|
||||
{field.NewFieldElement(10858355567899666102), field.NewFieldElement(18000616751093068478)},
|
||||
{field.NewFieldElement(16920330711313364238), field.NewFieldElement(8697067496869918100)},
|
||||
{field.NewFieldElement(7000103501288736536), field.NewFieldElement(10889037926963847627)},
|
||||
{field.NewFieldElement(2293930382336564785), field.NewFieldElement(1991911172589808532)},
|
||||
{field.NewFieldElement(16325792322333215740), field.NewFieldElement(10408910622457883954)},
|
||||
{field.NewFieldElement(7503118294246863546), field.NewFieldElement(3698311130768729720)},
|
||||
{field.NewFieldElement(8086040183115185263), field.NewFieldElement(5047183760990874466)},
|
||||
{field.NewFieldElement(9862182807054696027), field.NewFieldElement(1177341139111149965)},
|
||||
{field.NewFieldElement(16001172854107018622), field.NewFieldElement(10666261425617835543)},
|
||||
{field.NewFieldElement(5580184714347609844), field.NewFieldElement(12694115766192868759)},
|
||||
{field.NewFieldElement(18281558831138544975), field.NewFieldElement(3361626347282823513)},
|
||||
{field.NewFieldElement(3031997905089686532), field.NewFieldElement(15324883672435732043)},
|
||||
{field.NewFieldElement(450952121891526527), field.NewFieldElement(3760645720813651878)},
|
||||
{field.NewFieldElement(12802993704800176346), field.NewFieldElement(5762382859373230998)},
|
||||
{field.NewFieldElement(3276893202573968613), field.NewFieldElement(1800240087286854287)},
|
||||
{field.NewFieldElement(5921423446901282771), field.NewFieldElement(1701259673949139858)},
|
||||
{field.NewFieldElement(9599792256793291230), field.NewFieldElement(14953029539933413769)},
|
||||
{field.NewFieldElement(6924230983683680937), field.NewFieldElement(11341266871925411757)},
|
||||
{field.NewFieldElement(7369845262101528427), field.NewFieldElement(14511942995651504957)},
|
||||
{field.NewFieldElement(3575537879709813183), field.NewFieldElement(8500642062708926725)},
|
||||
{field.NewFieldElement(4175897998808440429), field.NewFieldElement(3374384071922541929)},
|
||||
{field.NewFieldElement(12757283027846003446), field.NewFieldElement(17905830097386863938)},
|
||||
{field.NewFieldElement(6320876143845688240), field.NewFieldElement(11931531275984972701)},
|
||||
{field.NewFieldElement(18217933064159243751), field.NewFieldElement(10071176713368801471)},
|
||||
{field.NewFieldElement(4777714881679002884), field.NewFieldElement(11864655235286620829)},
|
||||
{field.NewFieldElement(5051586433049660820), field.NewFieldElement(9706334979530647226)},
|
||||
{field.NewFieldElement(10142518025690185130), field.NewFieldElement(11625111857426302867)},
|
||||
{field.NewFieldElement(12942439955200094763), field.NewFieldElement(12974281474830386034)},
|
||||
{field.NewFieldElement(12714064210006754841), field.NewFieldElement(10541770037347437502)},
|
||||
{field.NewFieldElement(10048643184275048639), field.NewFieldElement(3986690477062097502)},
|
||||
{field.NewFieldElement(1705165528883143091), field.NewFieldElement(15274852618321664478)},
|
||||
{field.NewFieldElement(7505339430009963451), field.NewFieldElement(15833594687115464439)},
|
||||
{field.NewFieldElement(14969085142351848679), field.NewFieldElement(1313378114647584372)},
|
||||
{field.NewFieldElement(13860248504174697653), field.NewFieldElement(11813005399232850289)},
|
||||
{field.NewFieldElement(251943684565772115), field.NewFieldElement(7573719044708266257)},
|
||||
{field.NewFieldElement(3106490314923518751), field.NewFieldElement(6708785325259176544)},
|
||||
{field.NewFieldElement(16356137633407478618), field.NewFieldElement(10204772059332988569)},
|
||||
{field.NewFieldElement(6854820980459043959), field.NewFieldElement(15547517301904265885)},
|
||||
{field.NewFieldElement(11272546272005349344), field.NewFieldElement(13048057766361438654)},
|
||||
{field.NewFieldElement(1292326010164513793), field.NewFieldElement(3884499312974286465)},
|
||||
{field.NewFieldElement(13766861546348177296), field.NewFieldElement(16189793227494584882)},
|
||||
{field.NewFieldElement(17409073821234659314), field.NewFieldElement(9981103842753464857)},
|
||||
{field.NewFieldElement(9704863891305672730), field.NewFieldElement(6734589298170331622)},
|
||||
{field.NewFieldElement(12730115352516859625), field.NewFieldElement(7184752625986384624)},
|
||||
{field.NewFieldElement(11668345947294231238), field.NewFieldElement(16115042113565080691)},
|
||||
{field.NewFieldElement(14062084624592649794), field.NewFieldElement(2756332865729973692)},
|
||||
{field.NewFieldElement(3748768277402965633), field.NewFieldElement(16866814743891506413)},
|
||||
{field.NewFieldElement(10432481590948249422), field.NewFieldElement(16082227217718892532)},
|
||||
{field.NewFieldElement(491495918184990934), field.NewFieldElement(6356796615401236136)},
|
||||
{field.NewFieldElement(17901902629808882123), field.NewFieldElement(13514738065473981771)},
|
||||
{field.NewFieldElement(12660442011781098101), field.NewFieldElement(6869178288883388452)},
|
||||
{field.NewFieldElement(4393627135520874514), field.NewFieldElement(18356603129965580261)},
|
||||
{field.NewFieldElement(677707009508889751), field.NewFieldElement(12680875774839515608)},
|
||||
{field.NewFieldElement(10378933644525583340), field.NewFieldElement(13309450528739048419)},
|
||||
{field.NewFieldElement(17340442394158194152), field.NewFieldElement(2264038306172498436)},
|
||||
{field.NewFieldElement(3370239755875426470), field.NewFieldElement(16608802578078035004)},
|
||||
{field.NewFieldElement(10934853199725686361), field.NewFieldElement(16013313141655891901)},
|
||||
{field.NewFieldElement(13594205540632772459), field.NewFieldElement(2004743885124905326)},
|
||||
{field.NewFieldElement(2746704624744404227), field.NewFieldElement(16776409524391586509)},
|
||||
{field.NewFieldElement(3958873682280414366), field.NewFieldElement(1600073271711289868)},
|
||||
{field.NewFieldElement(2428249869256780385), field.NewFieldElement(4540186883415041033)},
|
||||
{field.NewFieldElement(11471613891518396403), field.NewFieldElement(12378090703999608437)},
|
||||
{field.NewFieldElement(2473054093631985558), field.NewFieldElement(6016173170699559864)},
|
||||
{field.NewFieldElement(5753078745189531749), field.NewFieldElement(7917608537613216175)},
|
||||
{field.NewFieldElement(8855440271433298214), field.NewFieldElement(16093723431433530090)},
|
||||
{field.NewFieldElement(18386320557740714138), field.NewFieldElement(8240697133069742104)},
|
||||
{field.NewFieldElement(15199992048380262587), field.NewFieldElement(2301519535136472331)},
|
||||
{field.NewFieldElement(5102771513133979026), field.NewFieldElement(12570336536575987923)},
|
||||
}
|
||||
|
||||
var publicInputsHash = poseidon.Hash{field.ZERO_F, field.ZERO_F, field.ZERO_F, field.ZERO_F}
|
||||
|
||||
var publicInputGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(10289971018233574142), field.NewFieldElement(4567684908222573778)},
|
||||
{field.NewFieldElement(11564178579868812087), field.NewFieldElement(4510091545046358953)},
|
||||
{field.NewFieldElement(2427374067806073277), field.NewFieldElement(6911441533263492425)},
|
||||
{field.NewFieldElement(7693977127287585254), field.NewFieldElement(9885192257977663560)},
|
||||
}
|
||||
|
||||
// BaseSumGate { num_limbs: 63 }), (Base: 2)
|
||||
var baseSumGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(11424008506420489027), field.NewFieldElement(2915141729320103909)},
|
||||
{field.NewFieldElement(990850510351998129), field.NewFieldElement(10775195787959069600)},
|
||||
{field.NewFieldElement(6614688617813304624), field.NewFieldElement(11090441606706959264)},
|
||||
{field.NewFieldElement(17750388994193092499), field.NewFieldElement(9822716613211085052)},
|
||||
{field.NewFieldElement(15668686535963465292), field.NewFieldElement(5860790519230132950)},
|
||||
{field.NewFieldElement(9301693563861638036), field.NewFieldElement(5759072521542705927)},
|
||||
{field.NewFieldElement(1463677617048504116), field.NewFieldElement(657088188145156737)},
|
||||
{field.NewFieldElement(11221326157331101168), field.NewFieldElement(3258353713560294154)},
|
||||
{field.NewFieldElement(6298170343528505052), field.NewFieldElement(1515404430931450244)},
|
||||
{field.NewFieldElement(10609142393996097059), field.NewFieldElement(5676353771077187085)},
|
||||
{field.NewFieldElement(15377741222281320), field.NewFieldElement(17210062473996670458)},
|
||||
{field.NewFieldElement(16623098697475668629), field.NewFieldElement(16010660943931470875)},
|
||||
{field.NewFieldElement(13742463434921610007), field.NewFieldElement(11069510319782271171)},
|
||||
{field.NewFieldElement(14872905802739821087), field.NewFieldElement(16577474870939262513)},
|
||||
{field.NewFieldElement(15699671366929256655), field.NewFieldElement(15598194197245819873)},
|
||||
{field.NewFieldElement(10679123900573339697), field.NewFieldElement(10228522398312889861)},
|
||||
{field.NewFieldElement(8872281223292031801), field.NewFieldElement(1329834573379055460)},
|
||||
{field.NewFieldElement(2535224613123191755), field.NewFieldElement(12786291812393663221)},
|
||||
{field.NewFieldElement(17788228910394641125), field.NewFieldElement(5545904820430114370)},
|
||||
{field.NewFieldElement(10489817294122939391), field.NewFieldElement(14636352222428121923)},
|
||||
{field.NewFieldElement(10852238020744398528), field.NewFieldElement(2312796082809010853)},
|
||||
{field.NewFieldElement(5067875522341132442), field.NewFieldElement(2107737958122288286)},
|
||||
{field.NewFieldElement(17283146688878926257), field.NewFieldElement(8456549639899437925)},
|
||||
{field.NewFieldElement(10637171512256553781), field.NewFieldElement(6390530901963054085)},
|
||||
{field.NewFieldElement(7586090218847390134), field.NewFieldElement(13687926314033375459)},
|
||||
{field.NewFieldElement(9523662200490053374), field.NewFieldElement(13361040406642218763)},
|
||||
{field.NewFieldElement(634822311162237689), field.NewFieldElement(9630483174624222223)},
|
||||
{field.NewFieldElement(15242934013445465604), field.NewFieldElement(1135488709061427932)},
|
||||
{field.NewFieldElement(10311174951052257420), field.NewFieldElement(524968500387403585)},
|
||||
{field.NewFieldElement(6646751050961926593), field.NewFieldElement(8684017064299024213)},
|
||||
{field.NewFieldElement(16629184374162391253), field.NewFieldElement(13745216788879851113)},
|
||||
{field.NewFieldElement(15725765914323741961), field.NewFieldElement(4607182206571650287)},
|
||||
{field.NewFieldElement(4905637093691966606), field.NewFieldElement(218562275165442331)},
|
||||
{field.NewFieldElement(15526612325511973871), field.NewFieldElement(5770955229659050735)},
|
||||
{field.NewFieldElement(9591223869277908917), field.NewFieldElement(1518900007157334701)},
|
||||
{field.NewFieldElement(14713177841944866109), field.NewFieldElement(16661134545564989407)},
|
||||
{field.NewFieldElement(4236602876840371235), field.NewFieldElement(12185730046300426061)},
|
||||
{field.NewFieldElement(14844502873470690827), field.NewFieldElement(5567680392033564858)},
|
||||
{field.NewFieldElement(5550472614893629959), field.NewFieldElement(17955875404530787722)},
|
||||
{field.NewFieldElement(9965647340229188622), field.NewFieldElement(12067752288619191155)},
|
||||
{field.NewFieldElement(15624184226617424434), field.NewFieldElement(13522086059807517857)},
|
||||
{field.NewFieldElement(6001948917737119729), field.NewFieldElement(10555349705067997421)},
|
||||
{field.NewFieldElement(7967852853408273634), field.NewFieldElement(16393445105337145265)},
|
||||
{field.NewFieldElement(13601491066758079307), field.NewFieldElement(11390709918813075818)},
|
||||
{field.NewFieldElement(5704706916270196865), field.NewFieldElement(17007264058732032659)},
|
||||
{field.NewFieldElement(18354610167186324196), field.NewFieldElement(16917152819910011122)},
|
||||
{field.NewFieldElement(6026824824087688959), field.NewFieldElement(11547555659280958524)},
|
||||
{field.NewFieldElement(15645938871784252821), field.NewFieldElement(12381341093764170444)},
|
||||
{field.NewFieldElement(1202470274460413029), field.NewFieldElement(3583599940021118482)},
|
||||
{field.NewFieldElement(5248479930891455774), field.NewFieldElement(2393692482194449448)},
|
||||
{field.NewFieldElement(13386434971986911647), field.NewFieldElement(12326376082602154018)},
|
||||
{field.NewFieldElement(11327299405009394635), field.NewFieldElement(7538844592867989882)},
|
||||
{field.NewFieldElement(7984839537656677309), field.NewFieldElement(6441274039505923023)},
|
||||
{field.NewFieldElement(3942932013374375924), field.NewFieldElement(6548354659360045418)},
|
||||
{field.NewFieldElement(10139699962065730425), field.NewFieldElement(16908585391181627242)},
|
||||
{field.NewFieldElement(18094104343668325187), field.NewFieldElement(8370083050741645827)},
|
||||
{field.NewFieldElement(12131340922292526267), field.NewFieldElement(17299488555769517106)},
|
||||
{field.NewFieldElement(11470330746430670818), field.NewFieldElement(15960507373360402879)},
|
||||
{field.NewFieldElement(386512699105836065), field.NewFieldElement(8986007306829996238)},
|
||||
{field.NewFieldElement(1834598616243509000), field.NewFieldElement(14626792908408543748)},
|
||||
{field.NewFieldElement(17890037858181404101), field.NewFieldElement(17018218424290394313)},
|
||||
{field.NewFieldElement(11758664078194540174), field.NewFieldElement(16603941107284246147)},
|
||||
{field.NewFieldElement(14022184733842887279), field.NewFieldElement(13741139908708752348)},
|
||||
{field.NewFieldElement(4836630213324422487), field.NewFieldElement(222498232493222193)},
|
||||
}
|
||||
|
||||
// ArithmeticGate { num_ops: 20 }
|
||||
var arithmeticGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(12119614175182896132), field.NewFieldElement(9100747776469133669)},
|
||||
{field.NewFieldElement(1435113994507051493), field.NewFieldElement(16937897191584383857)},
|
||||
{field.NewFieldElement(51616472710099652), field.NewFieldElement(4146295929435411488)},
|
||||
{field.NewFieldElement(92237181388579392), field.NewFieldElement(12824787281527009080)},
|
||||
{field.NewFieldElement(11063958613047368831), field.NewFieldElement(516751095582253219)},
|
||||
{field.NewFieldElement(8881502495740733965), field.NewFieldElement(5405782271334426100)},
|
||||
{field.NewFieldElement(9646745645960524278), field.NewFieldElement(6323317609176095073)},
|
||||
{field.NewFieldElement(10334354202446659881), field.NewFieldElement(17865166204439996809)},
|
||||
{field.NewFieldElement(9511789862027881130), field.NewFieldElement(17897392861017078901)},
|
||||
{field.NewFieldElement(4686618214331097217), field.NewFieldElement(7102232698145277151)},
|
||||
{field.NewFieldElement(5140381642477065044), field.NewFieldElement(15554316144351441473)},
|
||||
{field.NewFieldElement(14252043934312871974), field.NewFieldElement(1198292921407928539)},
|
||||
{field.NewFieldElement(13289413398237564138), field.NewFieldElement(15704998539419457452)},
|
||||
{field.NewFieldElement(4800979510155331538), field.NewFieldElement(14057404157182035427)},
|
||||
{field.NewFieldElement(17908028924715246889), field.NewFieldElement(8716376706845369224)},
|
||||
{field.NewFieldElement(3226678693544038862), field.NewFieldElement(5577680088492344738)},
|
||||
{field.NewFieldElement(10987852156126930017), field.NewFieldElement(16323667584216755558)},
|
||||
{field.NewFieldElement(5135981108938961064), field.NewFieldElement(6684115991562770960)},
|
||||
{field.NewFieldElement(8519638889718596339), field.NewFieldElement(7662028578892995756)},
|
||||
{field.NewFieldElement(7747323897933750795), field.NewFieldElement(6872730347313691927)},
|
||||
}
|
||||
|
||||
// RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
||||
var randomAccessGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(2891299230460455680), field.NewFieldElement(12638923114586787038)},
|
||||
{field.NewFieldElement(10369791235277272383), field.NewFieldElement(11178254747952182382)},
|
||||
{field.NewFieldElement(2609100974341658152), field.NewFieldElement(7141157629969452340)},
|
||||
{field.NewFieldElement(10885639242129231953), field.NewFieldElement(10224819739496777877)},
|
||||
{field.NewFieldElement(15486139493712450489), field.NewFieldElement(17924944477102802615)},
|
||||
{field.NewFieldElement(5969758517166950176), field.NewFieldElement(4139464862931677318)},
|
||||
{field.NewFieldElement(7251510967440451429), field.NewFieldElement(11634060506931912043)},
|
||||
{field.NewFieldElement(581371472896562405), field.NewFieldElement(1340263685452848185)},
|
||||
{field.NewFieldElement(11876289968532354241), field.NewFieldElement(39606365246086104)},
|
||||
{field.NewFieldElement(17037991399414168046), field.NewFieldElement(9356315359108087151)},
|
||||
{field.NewFieldElement(13506822543872334969), field.NewFieldElement(14166594210473057923)},
|
||||
{field.NewFieldElement(530968584207084639), field.NewFieldElement(12346975065647187607)},
|
||||
{field.NewFieldElement(8780439534301283756), field.NewFieldElement(14250307971393105395)},
|
||||
{field.NewFieldElement(5955166439403627952), field.NewFieldElement(427818832806268253)},
|
||||
{field.NewFieldElement(10383473532295208089), field.NewFieldElement(10834018170496866410)},
|
||||
{field.NewFieldElement(17770159895239813531), field.NewFieldElement(3803908573438301448)},
|
||||
{field.NewFieldElement(5230956285821863871), field.NewFieldElement(13187949446452303832)},
|
||||
{field.NewFieldElement(4082775007574051589), field.NewFieldElement(17608951079871259588)},
|
||||
{field.NewFieldElement(15832332042406144153), field.NewFieldElement(9112933169473505864)},
|
||||
{field.NewFieldElement(17289713569232165217), field.NewFieldElement(764355564171754371)},
|
||||
{field.NewFieldElement(11875388597093781742), field.NewFieldElement(17390337221018798452)},
|
||||
{field.NewFieldElement(14723779398624676305), field.NewFieldElement(4351422752569601515)},
|
||||
{field.NewFieldElement(7898206414568399642), field.NewFieldElement(3781389637016766144)},
|
||||
{field.NewFieldElement(10959059343195760030), field.NewFieldElement(17524903422154932359)},
|
||||
{field.NewFieldElement(7305896571823662942), field.NewFieldElement(12962835460398538761)},
|
||||
{field.NewFieldElement(5653738395766265725), field.NewFieldElement(8097455003461687478)},
|
||||
}
|
||||
|
||||
// PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>
|
||||
var poseidonGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(7586090218847390134), field.NewFieldElement(13687926314033375459)},
|
||||
{field.NewFieldElement(10774680496478357997), field.NewFieldElement(14419929234728022600)},
|
||||
{field.NewFieldElement(983485807903636414), field.NewFieldElement(3028876395437704592)},
|
||||
{field.NewFieldElement(5873163034459252869), field.NewFieldElement(11720300428168955402)},
|
||||
{field.NewFieldElement(16261775977438390033), field.NewFieldElement(15598817592005081227)},
|
||||
{field.NewFieldElement(3308439339359285309), field.NewFieldElement(16350160944703138332)},
|
||||
{field.NewFieldElement(2477915029208949035), field.NewFieldElement(10909058342937234971)},
|
||||
{field.NewFieldElement(2006101431747008114), field.NewFieldElement(1317396811566929515)},
|
||||
{field.NewFieldElement(5743380333218483835), field.NewFieldElement(9864892326580372485)},
|
||||
{field.NewFieldElement(4343047746155696133), field.NewFieldElement(2452956674303649004)},
|
||||
{field.NewFieldElement(18237771591472199486), field.NewFieldElement(9201720967486340889)},
|
||||
{field.NewFieldElement(7997743545022954538), field.NewFieldElement(5790905224346459337)},
|
||||
{field.NewFieldElement(7270313259765139533), field.NewFieldElement(13664497978956485388)},
|
||||
{field.NewFieldElement(11627392666242516567), field.NewFieldElement(6707531853885096654)},
|
||||
{field.NewFieldElement(14108041676779390728), field.NewFieldElement(13890317640467961363)},
|
||||
{field.NewFieldElement(10461937206408578346), field.NewFieldElement(16929842020525911045)},
|
||||
{field.NewFieldElement(14163490001894639417), field.NewFieldElement(6486250350832733344)},
|
||||
{field.NewFieldElement(6025822272051423893), field.NewFieldElement(6875599327185319749)},
|
||||
{field.NewFieldElement(11800406778761598568), field.NewFieldElement(13445736562420900345)},
|
||||
{field.NewFieldElement(8721632296347252438), field.NewFieldElement(15861696011210243831)},
|
||||
{field.NewFieldElement(13862698645551446166), field.NewFieldElement(10895802231885823011)},
|
||||
{field.NewFieldElement(9467131299943023152), field.NewFieldElement(508610840287781764)},
|
||||
{field.NewFieldElement(10369576299876905473), field.NewFieldElement(1319089684709412204)},
|
||||
{field.NewFieldElement(17202741125808968481), field.NewFieldElement(4132975454251812345)},
|
||||
{field.NewFieldElement(4939406044782203142), field.NewFieldElement(18100435685377738067)},
|
||||
{field.NewFieldElement(2662601992953696766), field.NewFieldElement(5356898997486457355)},
|
||||
{field.NewFieldElement(12240740991568526347), field.NewFieldElement(14183052793978601368)},
|
||||
{field.NewFieldElement(17267799754824241908), field.NewFieldElement(15067892579134674951)},
|
||||
{field.NewFieldElement(3885637219153712510), field.NewFieldElement(2045928245539296545)},
|
||||
{field.NewFieldElement(7614199998298216925), field.NewFieldElement(13135807303144108264)},
|
||||
{field.NewFieldElement(12232208765790877245), field.NewFieldElement(6790391920585566719)},
|
||||
{field.NewFieldElement(14027621788671850076), field.NewFieldElement(8244116705079721069)},
|
||||
{field.NewFieldElement(18361849947075265980), field.NewFieldElement(636640170174188211)},
|
||||
{field.NewFieldElement(15400723839777269850), field.NewFieldElement(7187627113110641974)},
|
||||
{field.NewFieldElement(11208418886499216060), field.NewFieldElement(1068905181682993370)},
|
||||
{field.NewFieldElement(8741978871712571992), field.NewFieldElement(11893984108008599655)},
|
||||
{field.NewFieldElement(5904231306484990036), field.NewFieldElement(10974042651195177783)},
|
||||
{field.NewFieldElement(12306264278608747297), field.NewFieldElement(6054935933756948006)},
|
||||
{field.NewFieldElement(4439661353730067518), field.NewFieldElement(13536513851562309841)},
|
||||
{field.NewFieldElement(13020734370698999772), field.NewFieldElement(163773705062531020)},
|
||||
{field.NewFieldElement(10365756846699668634), field.NewFieldElement(5245413619357449)},
|
||||
{field.NewFieldElement(15929862436085820709), field.NewFieldElement(10957910821863876318)},
|
||||
{field.NewFieldElement(977018799724983158), field.NewFieldElement(15040949766668867994)},
|
||||
{field.NewFieldElement(2993125862244950582), field.NewFieldElement(13234404554976574543)},
|
||||
{field.NewFieldElement(14122201262568632993), field.NewFieldElement(93763383340088526)},
|
||||
{field.NewFieldElement(8975477202804925208), field.NewFieldElement(1040893022864763499)},
|
||||
{field.NewFieldElement(7725813871064262870), field.NewFieldElement(14455479145922718826)},
|
||||
{field.NewFieldElement(1073062170185630790), field.NewFieldElement(16407856079088655345)},
|
||||
{field.NewFieldElement(17737117878818849535), field.NewFieldElement(1900599912944642061)},
|
||||
{field.NewFieldElement(12256168642879070567), field.NewFieldElement(8539769760609459864)},
|
||||
{field.NewFieldElement(15141228232285134803), field.NewFieldElement(897120225935075003)},
|
||||
{field.NewFieldElement(3388596123376728329), field.NewFieldElement(5128230734992475590)},
|
||||
{field.NewFieldElement(8733319491992764673), field.NewFieldElement(1928863683866117576)},
|
||||
{field.NewFieldElement(5203485787146767490), field.NewFieldElement(12954094447445057610)},
|
||||
{field.NewFieldElement(5201734155949618873), field.NewFieldElement(3995115267673262244)},
|
||||
{field.NewFieldElement(8666839426855174616), field.NewFieldElement(3659748522909014185)},
|
||||
{field.NewFieldElement(9240426493517714121), field.NewFieldElement(12895319645103780590)},
|
||||
{field.NewFieldElement(10104523192405168095), field.NewFieldElement(8335084014759232790)},
|
||||
{field.NewFieldElement(12471660706832322357), field.NewFieldElement(16692471091408210242)},
|
||||
{field.NewFieldElement(7713567301004647325), field.NewFieldElement(2346765742178693341)},
|
||||
{field.NewFieldElement(5087966313974874861), field.NewFieldElement(17995538175842083522)},
|
||||
{field.NewFieldElement(1103485120645095922), field.NewFieldElement(17358959631107792889)},
|
||||
{field.NewFieldElement(16443030134912318512), field.NewFieldElement(4694929981527462915)},
|
||||
{field.NewFieldElement(5229836547906072694), field.NewFieldElement(10529861755371621018)},
|
||||
{field.NewFieldElement(17706463046886551260), field.NewFieldElement(7014625543777947259)},
|
||||
{field.NewFieldElement(17494246083650429806), field.NewFieldElement(10059232320812188522)},
|
||||
{field.NewFieldElement(6009623857477500128), field.NewFieldElement(9041821915077023327)},
|
||||
{field.NewFieldElement(15414837134646072506), field.NewFieldElement(17735866267331281406)},
|
||||
{field.NewFieldElement(9582418254228040565), field.NewFieldElement(9475780400052940525)},
|
||||
{field.NewFieldElement(3850010214259020229), field.NewFieldElement(2344916032711572881)},
|
||||
{field.NewFieldElement(3276478492985700631), field.NewFieldElement(9347511148183965796)},
|
||||
{field.NewFieldElement(4260955157349956538), field.NewFieldElement(3737557221553060525)},
|
||||
{field.NewFieldElement(1814028760671441115), field.NewFieldElement(1709540851509897224)},
|
||||
{field.NewFieldElement(304220870213251471), field.NewFieldElement(18339319635968408171)},
|
||||
{field.NewFieldElement(6309601903165399081), field.NewFieldElement(4611660338915358676)},
|
||||
{field.NewFieldElement(5440836432197140901), field.NewFieldElement(835184832962669050)},
|
||||
{field.NewFieldElement(4132483007111889331), field.NewFieldElement(17679464861654166329)},
|
||||
{field.NewFieldElement(12071698679631585615), field.NewFieldElement(3526806430507304767)},
|
||||
{field.NewFieldElement(16570124099871162516), field.NewFieldElement(16394949299416922104)},
|
||||
{field.NewFieldElement(11779301434103087470), field.NewFieldElement(9928702854994401626)},
|
||||
{field.NewFieldElement(486097273023099818), field.NewFieldElement(1666631222233964241)},
|
||||
{field.NewFieldElement(13426511095962901265), field.NewFieldElement(16977352762229561063)},
|
||||
{field.NewFieldElement(7848259968166982335), field.NewFieldElement(8923641610835432771)},
|
||||
{field.NewFieldElement(6717523783985825261), field.NewFieldElement(8442698012198213832)},
|
||||
{field.NewFieldElement(16551829854897630528), field.NewFieldElement(1207332518477764340)},
|
||||
{field.NewFieldElement(9552262459546034571), field.NewFieldElement(4701791517562735608)},
|
||||
{field.NewFieldElement(6527201331407091692), field.NewFieldElement(10762913938781033944)},
|
||||
{field.NewFieldElement(11212416663128404375), field.NewFieldElement(6847749339754298086)},
|
||||
{field.NewFieldElement(10791247438031342492), field.NewFieldElement(3448715099533950037)},
|
||||
{field.NewFieldElement(1719220253088662156), field.NewFieldElement(15702968714187742357)},
|
||||
{field.NewFieldElement(14008817631758138024), field.NewFieldElement(17297897981954620228)},
|
||||
{field.NewFieldElement(7768014097976613936), field.NewFieldElement(15806402621409309279)},
|
||||
{field.NewFieldElement(3886721256453659755), field.NewFieldElement(16395869594056206627)},
|
||||
{field.NewFieldElement(13997073954856864246), field.NewFieldElement(1233051863712529371)},
|
||||
{field.NewFieldElement(11334349192463912274), field.NewFieldElement(5454820034730801470)},
|
||||
{field.NewFieldElement(7648426950649263998), field.NewFieldElement(9412547620105462810)},
|
||||
{field.NewFieldElement(2869115266070242006), field.NewFieldElement(9873001547032180059)},
|
||||
{field.NewFieldElement(11864269740491424738), field.NewFieldElement(3771973823544233765)},
|
||||
{field.NewFieldElement(9374340554044631499), field.NewFieldElement(11414175937704649426)},
|
||||
{field.NewFieldElement(8970748854700874383), field.NewFieldElement(2703579039677419011)},
|
||||
{field.NewFieldElement(3743841601176432106), field.NewFieldElement(11043980835019875782)},
|
||||
{field.NewFieldElement(1654705359096618107), field.NewFieldElement(4374088811382131752)},
|
||||
{field.NewFieldElement(10209435051454821145), field.NewFieldElement(4087979231575661143)},
|
||||
{field.NewFieldElement(9566392584670645438), field.NewFieldElement(5102479111558561813)},
|
||||
{field.NewFieldElement(4542214823227660682), field.NewFieldElement(16447152846983873546)},
|
||||
{field.NewFieldElement(3619667706484141693), field.NewFieldElement(3976495805371636999)},
|
||||
{field.NewFieldElement(14677559952589127978), field.NewFieldElement(1506330427474903904)},
|
||||
{field.NewFieldElement(9618330319963013853), field.NewFieldElement(7774314641304317232)},
|
||||
{field.NewFieldElement(15136595569611237026), field.NewFieldElement(6241976546079100101)},
|
||||
{field.NewFieldElement(6190131967820348937), field.NewFieldElement(8898314655028146727)},
|
||||
{field.NewFieldElement(10664902807329902141), field.NewFieldElement(399679411582475270)},
|
||||
{field.NewFieldElement(4620231951016842028), field.NewFieldElement(14227502135369964656)},
|
||||
{field.NewFieldElement(14442830168084065060), field.NewFieldElement(18194643570654368962)},
|
||||
{field.NewFieldElement(6026772169794354979), field.NewFieldElement(15538586941211648185)},
|
||||
{field.NewFieldElement(3305763071851691617), field.NewFieldElement(7414963068017211970)},
|
||||
{field.NewFieldElement(2348819716102409971), field.NewFieldElement(3414253607649082297)},
|
||||
{field.NewFieldElement(5561613987159516190), field.NewFieldElement(18108137586585031915)},
|
||||
{field.NewFieldElement(11622858756456645517), field.NewFieldElement(5481788959889711288)},
|
||||
{field.NewFieldElement(14329441999576805903), field.NewFieldElement(7316385947805485474)},
|
||||
{field.NewFieldElement(6619906970666076294), field.NewFieldElement(11606453814479815487)},
|
||||
{field.NewFieldElement(273184393202580706), field.NewFieldElement(15538333835729971074)},
|
||||
{field.NewFieldElement(16891566794426605557), field.NewFieldElement(432853148035369520)},
|
||||
{field.NewFieldElement(3134481789780853760), field.NewFieldElement(10023938129020275945)},
|
||||
}
|
||||
|
||||
var reducingExtensionGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(12512260201049243975), field.NewFieldElement(5104620179714279781)},
|
||||
{field.NewFieldElement(13013016297591764071), field.NewFieldElement(3905565448987160512)},
|
||||
{field.NewFieldElement(18168316387479509651), field.NewFieldElement(15285510648877030958)},
|
||||
{field.NewFieldElement(2704136035168106924), field.NewFieldElement(17701154289967205509)},
|
||||
{field.NewFieldElement(6350634844525158810), field.NewFieldElement(6841530668953763541)},
|
||||
{field.NewFieldElement(14558428225759052231), field.NewFieldElement(6228114011555775975)},
|
||||
{field.NewFieldElement(11984059988070020226), field.NewFieldElement(6404501976404464308)},
|
||||
{field.NewFieldElement(7499833675686066082), field.NewFieldElement(13203954482927844021)},
|
||||
{field.NewFieldElement(53729277296365862), field.NewFieldElement(11604944835579274791)},
|
||||
{field.NewFieldElement(649276793194856338), field.NewFieldElement(15769159485820654298)},
|
||||
{field.NewFieldElement(7220059241713171194), field.NewFieldElement(7593947467996717503)},
|
||||
{field.NewFieldElement(11725388872832717991), field.NewFieldElement(2472966042937251891)},
|
||||
{field.NewFieldElement(17103067711705259268), field.NewFieldElement(12741737218458998807)},
|
||||
{field.NewFieldElement(2053029714235535081), field.NewFieldElement(5621084618445985853)},
|
||||
{field.NewFieldElement(394074652594148954), field.NewFieldElement(14480160107167739683)},
|
||||
{field.NewFieldElement(16319639492172307693), field.NewFieldElement(18262596047016856354)},
|
||||
{field.NewFieldElement(7349401242823131130), field.NewFieldElement(16637643780538375248)},
|
||||
{field.NewFieldElement(2968776512542894745), field.NewFieldElement(7967382686110631950)},
|
||||
{field.NewFieldElement(4131567287142440211), field.NewFieldElement(16488573781037653146)},
|
||||
{field.NewFieldElement(3210618110340609396), field.NewFieldElement(15575562053796139855)},
|
||||
{field.NewFieldElement(866179987510198517), field.NewFieldElement(1621207644178469397)},
|
||||
{field.NewFieldElement(13787839347867512750), field.NewFieldElement(5082451965770365331)},
|
||||
{field.NewFieldElement(16727747831341625951), field.NewFieldElement(17003066965000183599)},
|
||||
{field.NewFieldElement(5844378810576570680), field.NewFieldElement(7917389141334353441)},
|
||||
{field.NewFieldElement(2806785896842529320), field.NewFieldElement(2418902247526900913)},
|
||||
{field.NewFieldElement(16911660151499877134), field.NewFieldElement(12021165187528883860)},
|
||||
{field.NewFieldElement(17281860563566587308), field.NewFieldElement(907492056629373413)},
|
||||
{field.NewFieldElement(2149753706739034128), field.NewFieldElement(12371022473774589200)},
|
||||
{field.NewFieldElement(7841056796552151745), field.NewFieldElement(3143088841967149638)},
|
||||
{field.NewFieldElement(11915031067231681577), field.NewFieldElement(18108223564563708813)},
|
||||
{field.NewFieldElement(2094314575212662773), field.NewFieldElement(188561272841399737)},
|
||||
{field.NewFieldElement(16712479120741377751), field.NewFieldElement(13153292267876520211)},
|
||||
{field.NewFieldElement(11528911604171979726), field.NewFieldElement(889050185568489714)},
|
||||
{field.NewFieldElement(13117878881472895975), field.NewFieldElement(2608864599443833112)},
|
||||
{field.NewFieldElement(310976139454954605), field.NewFieldElement(271726012479588385)},
|
||||
{field.NewFieldElement(4724981023605656141), field.NewFieldElement(7786903198345013664)},
|
||||
{field.NewFieldElement(7358470379588594806), field.NewFieldElement(5500290420069122896)},
|
||||
{field.NewFieldElement(11249736961064437940), field.NewFieldElement(7500992311029866319)},
|
||||
{field.NewFieldElement(16247982877846154545), field.NewFieldElement(18437922661172982146)},
|
||||
{field.NewFieldElement(14828806288276948771), field.NewFieldElement(161861918745757497)},
|
||||
{field.NewFieldElement(12207866405175784678), field.NewFieldElement(17882395070256177480)},
|
||||
{field.NewFieldElement(1862300191557939305), field.NewFieldElement(12946149812989300425)},
|
||||
{field.NewFieldElement(113183958399514852), field.NewFieldElement(6003153612730483196)},
|
||||
{field.NewFieldElement(17112839880895845290), field.NewFieldElement(3628345828628316007)},
|
||||
{field.NewFieldElement(8779978792406228661), field.NewFieldElement(11992923889396921201)},
|
||||
{field.NewFieldElement(6179077038148294340), field.NewFieldElement(11713998999910876710)},
|
||||
{field.NewFieldElement(13454002959297605186), field.NewFieldElement(2204743745696912515)},
|
||||
{field.NewFieldElement(15623020893752344305), field.NewFieldElement(13749522681861530980)},
|
||||
{field.NewFieldElement(6206230970377487041), field.NewFieldElement(16389331421791613953)},
|
||||
{field.NewFieldElement(2425462828014799977), field.NewFieldElement(1558769431852532736)},
|
||||
{field.NewFieldElement(2327926263345738065), field.NewFieldElement(8779034796068602190)},
|
||||
{field.NewFieldElement(14563770135458078041), field.NewFieldElement(6494115966350812505)},
|
||||
{field.NewFieldElement(8082502921781233722), field.NewFieldElement(7935499582140944140)},
|
||||
{field.NewFieldElement(14539277379887693704), field.NewFieldElement(5161629331161118775)},
|
||||
{field.NewFieldElement(13736527598285458228), field.NewFieldElement(7309962536813433388)},
|
||||
{field.NewFieldElement(13933813405709515396), field.NewFieldElement(17798686485131016236)},
|
||||
{field.NewFieldElement(8897530535975229493), field.NewFieldElement(14404791097089986313)},
|
||||
{field.NewFieldElement(18088311324021484864), field.NewFieldElement(11991882587468162630)},
|
||||
{field.NewFieldElement(8956488301372897339), field.NewFieldElement(8045253716620738816)},
|
||||
{field.NewFieldElement(16016384501418916541), field.NewFieldElement(3181272893128323084)},
|
||||
{field.NewFieldElement(2517080075900745791), field.NewFieldElement(18241855168616334247)},
|
||||
{field.NewFieldElement(17868385271737172979), field.NewFieldElement(3149251797904840387)},
|
||||
{field.NewFieldElement(16240211689398081741), field.NewFieldElement(12595579002758809850)},
|
||||
{field.NewFieldElement(15129425055871583477), field.NewFieldElement(16556688233744925655)},
|
||||
{field.NewFieldElement(12118068802024437752), field.NewFieldElement(1415394251822514067)},
|
||||
{field.NewFieldElement(9998982344935417389), field.NewFieldElement(1388414311221312252)},
|
||||
}
|
||||
|
||||
// ReducingGate { num_coeffs: 44 }
|
||||
var reducingGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(2762695979854660261), field.NewFieldElement(6188975775006680731)},
|
||||
{field.NewFieldElement(1791331417935738626), field.NewFieldElement(17085037714198081810)},
|
||||
{field.NewFieldElement(2937679508710033736), field.NewFieldElement(5129621779087684534)},
|
||||
{field.NewFieldElement(481168721643876637), field.NewFieldElement(7141872137498120988)},
|
||||
{field.NewFieldElement(17254181100047942156), field.NewFieldElement(17775174281554210440)},
|
||||
{field.NewFieldElement(5198890470471443302), field.NewFieldElement(14888425516661975457)},
|
||||
{field.NewFieldElement(13028786198899252632), field.NewFieldElement(10937447292538980197)},
|
||||
{field.NewFieldElement(2265158031754703100), field.NewFieldElement(12577502307628934155)},
|
||||
{field.NewFieldElement(15551968276096003032), field.NewFieldElement(15292448269321193280)},
|
||||
{field.NewFieldElement(17365969756658867370), field.NewFieldElement(17369305944822545977)},
|
||||
{field.NewFieldElement(7080686817257839256), field.NewFieldElement(593963095520237279)},
|
||||
{field.NewFieldElement(9676311908112124362), field.NewFieldElement(15674622921902422959)},
|
||||
{field.NewFieldElement(11251136116732324348), field.NewFieldElement(18440217803596221468)},
|
||||
{field.NewFieldElement(3735056268905622852), field.NewFieldElement(13863980656029437128)},
|
||||
{field.NewFieldElement(8027041826265159623), field.NewFieldElement(11754189465873578671)},
|
||||
{field.NewFieldElement(17583392801264300641), field.NewFieldElement(6466906893845676112)},
|
||||
{field.NewFieldElement(10453982665201242303), field.NewFieldElement(10957427537661178463)},
|
||||
{field.NewFieldElement(8008073576872573103), field.NewFieldElement(15936946455243860971)},
|
||||
{field.NewFieldElement(10779255795330506743), field.NewFieldElement(1425676337306283564)},
|
||||
{field.NewFieldElement(13500038741878953694), field.NewFieldElement(5693690628820948906)},
|
||||
{field.NewFieldElement(6987584139748553407), field.NewFieldElement(4433192799815624764)},
|
||||
{field.NewFieldElement(3618013197373611562), field.NewFieldElement(15641412670596115335)},
|
||||
{field.NewFieldElement(4523765518023087797), field.NewFieldElement(5497960888090896635)},
|
||||
{field.NewFieldElement(8750545727419259671), field.NewFieldElement(17422860419602722677)},
|
||||
{field.NewFieldElement(17564615024878416866), field.NewFieldElement(16238022624102079273)},
|
||||
{field.NewFieldElement(3740814195084876131), field.NewFieldElement(17474834584441312839)},
|
||||
{field.NewFieldElement(2239459464265888484), field.NewFieldElement(8706775397593275819)},
|
||||
{field.NewFieldElement(6491352471800031726), field.NewFieldElement(209451190673168977)},
|
||||
{field.NewFieldElement(5778494879465125706), field.NewFieldElement(7142303398286289731)},
|
||||
{field.NewFieldElement(7094902435091460736), field.NewFieldElement(17694563561889239395)},
|
||||
{field.NewFieldElement(2647942785603144770), field.NewFieldElement(12183038555524816414)},
|
||||
{field.NewFieldElement(15100729453671585276), field.NewFieldElement(8119652948094623285)},
|
||||
{field.NewFieldElement(3441209666651626111), field.NewFieldElement(10072736477013237067)},
|
||||
{field.NewFieldElement(2372663484566761092), field.NewFieldElement(594324049190490986)},
|
||||
{field.NewFieldElement(4026947675295370811), field.NewFieldElement(1179770390904329138)},
|
||||
{field.NewFieldElement(1595271198725095132), field.NewFieldElement(15771888513051752701)},
|
||||
{field.NewFieldElement(15924194187528252748), field.NewFieldElement(6763066202850242722)},
|
||||
{field.NewFieldElement(1445670890851930788), field.NewFieldElement(3792635664222385076)},
|
||||
{field.NewFieldElement(12273956505460180574), field.NewFieldElement(2686688969956106705)},
|
||||
{field.NewFieldElement(11658870742027189182), field.NewFieldElement(12329880551401953731)},
|
||||
{field.NewFieldElement(3044295792231373345), field.NewFieldElement(17852841657875251990)},
|
||||
{field.NewFieldElement(89567881331820860), field.NewFieldElement(15259944608836914642)},
|
||||
{field.NewFieldElement(358286967559220432), field.NewFieldElement(4492752479771433484)},
|
||||
{field.NewFieldElement(14577916428537408584), field.NewFieldElement(13741732911292090813)},
|
||||
{field.NewFieldElement(16727747831341625951), field.NewFieldElement(17003066965000183599)},
|
||||
{field.NewFieldElement(9070359631236984957), field.NewFieldElement(6062623613509003067)},
|
||||
{field.NewFieldElement(2410743624398118478), field.NewFieldElement(13772226839431038397)},
|
||||
{field.NewFieldElement(11807638155649559084), field.NewFieldElement(1137111487688533470)},
|
||||
{field.NewFieldElement(64491941894197002), field.NewFieldElement(5868353091743239378)},
|
||||
{field.NewFieldElement(11301275742904392411), field.NewFieldElement(16283949803466884532)},
|
||||
{field.NewFieldElement(9890416519568149104), field.NewFieldElement(8227793073753762383)},
|
||||
{field.NewFieldElement(14951282035757983160), field.NewFieldElement(9077678991191664958)},
|
||||
{field.NewFieldElement(5033664288544688549), field.NewFieldElement(9192774674510226248)},
|
||||
{field.NewFieldElement(11933408140918977315), field.NewFieldElement(7749057899233101160)},
|
||||
{field.NewFieldElement(9164812869909307746), field.NewFieldElement(1719896377847214041)},
|
||||
{field.NewFieldElement(15224563238586628983), field.NewFieldElement(2588693305957079413)},
|
||||
{field.NewFieldElement(1889812039818739618), field.NewFieldElement(4817606363423939521)},
|
||||
{field.NewFieldElement(15609561908880497864), field.NewFieldElement(11885907317258609874)},
|
||||
{field.NewFieldElement(6792442952488353934), field.NewFieldElement(15088298397252768139)},
|
||||
{field.NewFieldElement(2651197118788035780), field.NewFieldElement(5089685590535462009)},
|
||||
{field.NewFieldElement(11982358277830572398), field.NewFieldElement(15471174962798992515)},
|
||||
{field.NewFieldElement(7639615465545578427), field.NewFieldElement(12644783892223098985)},
|
||||
{field.NewFieldElement(11009184909998310074), field.NewFieldElement(17958525789123172556)},
|
||||
{field.NewFieldElement(7777052961871412232), field.NewFieldElement(9786263008632335028)},
|
||||
{field.NewFieldElement(13336166292448975341), field.NewFieldElement(15263885337654327510)},
|
||||
{field.NewFieldElement(12764160635364533900), field.NewFieldElement(15411617803867471736)},
|
||||
{field.NewFieldElement(17491426030593864841), field.NewFieldElement(2688540155718191896)},
|
||||
{field.NewFieldElement(4278381039362706308), field.NewFieldElement(17571997178209012848)},
|
||||
{field.NewFieldElement(12726900947926109267), field.NewFieldElement(1433345131505837369)},
|
||||
{field.NewFieldElement(6334884250665613762), field.NewFieldElement(9617978266076057841)},
|
||||
{field.NewFieldElement(17511031815464775451), field.NewFieldElement(12281753446186189470)},
|
||||
{field.NewFieldElement(10718030381939087273), field.NewFieldElement(10785278464322784199)},
|
||||
{field.NewFieldElement(6964802145991989973), field.NewFieldElement(5630451507536431311)},
|
||||
{field.NewFieldElement(1610931441749714598), field.NewFieldElement(17306081287063918214)},
|
||||
{field.NewFieldElement(12529885758752979710), field.NewFieldElement(12015226868538417544)},
|
||||
{field.NewFieldElement(8212526954290021947), field.NewFieldElement(2604665677904480075)},
|
||||
{field.NewFieldElement(836429499775217902), field.NewFieldElement(14951071826451735988)},
|
||||
{field.NewFieldElement(4322887569225425418), field.NewFieldElement(1803870148496860526)},
|
||||
{field.NewFieldElement(11933437515394389470), field.NewFieldElement(5432495301370703205)},
|
||||
{field.NewFieldElement(15379632811901291758), field.NewFieldElement(16475440758252311235)},
|
||||
{field.NewFieldElement(8378463548508566883), field.NewFieldElement(12576809460019959325)},
|
||||
{field.NewFieldElement(6878478934798340017), field.NewFieldElement(16203041885409513004)},
|
||||
{field.NewFieldElement(4704361120432029530), field.NewFieldElement(15619278597929334259)},
|
||||
{field.NewFieldElement(11896486732715322997), field.NewFieldElement(13476483500406677625)},
|
||||
{field.NewFieldElement(3818194554960853168), field.NewFieldElement(17483945143600046041)},
|
||||
{field.NewFieldElement(16655838413972803560), field.NewFieldElement(7859620736875007555)},
|
||||
{field.NewFieldElement(9466644546267012606), field.NewFieldElement(15636572488448679353)},
|
||||
{field.NewFieldElement(7705051962598852604), field.NewFieldElement(17843247208046088041)},
|
||||
}
|
||||
|
||||
// ArithmeticExtensionGate { num_ops: 10 }
|
||||
var arithmeticExtensionGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(18152046378789398239), field.NewFieldElement(835198655627980634)},
|
||||
{field.NewFieldElement(14941458349516937745), field.NewFieldElement(195899842055585620)},
|
||||
{field.NewFieldElement(11444294347859626222), field.NewFieldElement(7618743177769594838)},
|
||||
{field.NewFieldElement(6847392923782354441), field.NewFieldElement(3129968840755754688)},
|
||||
{field.NewFieldElement(11707145384221145922), field.NewFieldElement(286105987739288036)},
|
||||
{field.NewFieldElement(2582465953258947981), field.NewFieldElement(9032385332294381140)},
|
||||
{field.NewFieldElement(13238521192691745149), field.NewFieldElement(9704746731861618809)},
|
||||
{field.NewFieldElement(1830772271680123935), field.NewFieldElement(2037318884130759975)},
|
||||
{field.NewFieldElement(5532751095564029866), field.NewFieldElement(11560707807043359130)},
|
||||
{field.NewFieldElement(4749576916935014495), field.NewFieldElement(2144864975020203842)},
|
||||
{field.NewFieldElement(18162899505828592791), field.NewFieldElement(13853020020051211390)},
|
||||
{field.NewFieldElement(16196741394015376387), field.NewFieldElement(16087121152637055080)},
|
||||
{field.NewFieldElement(15478783842112089677), field.NewFieldElement(8151788319455760610)},
|
||||
{field.NewFieldElement(4962260057365923941), field.NewFieldElement(12155107209004037964)},
|
||||
{field.NewFieldElement(18192514584072489162), field.NewFieldElement(2336293494478946065)},
|
||||
{field.NewFieldElement(3747540982963754880), field.NewFieldElement(5650114101530259911)},
|
||||
{field.NewFieldElement(17757207146926514655), field.NewFieldElement(13461601821205159205)},
|
||||
{field.NewFieldElement(17921720474545785568), field.NewFieldElement(4718996085070502683)},
|
||||
{field.NewFieldElement(4443998758263224376), field.NewFieldElement(13890461367328975727)},
|
||||
{field.NewFieldElement(13990958094457190244), field.NewFieldElement(3783673559976842909)},
|
||||
}
|
||||
|
||||
// MulExtensionGate { num_ops: 13 }
|
||||
var mulExtensionGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(7181113876231745794), field.NewFieldElement(7868884260109104825)},
|
||||
{field.NewFieldElement(14067639069854412134), field.NewFieldElement(2094238260641413106)},
|
||||
{field.NewFieldElement(3160167686452082144), field.NewFieldElement(15508587061137009544)},
|
||||
{field.NewFieldElement(2701966180261760724), field.NewFieldElement(49742798193009777)},
|
||||
{field.NewFieldElement(16965594259972472645), field.NewFieldElement(15119035756932709035)},
|
||||
{field.NewFieldElement(8587305003975146248), field.NewFieldElement(11788991692426475292)},
|
||||
{field.NewFieldElement(13134841191650990099), field.NewFieldElement(12468857767882216027)},
|
||||
{field.NewFieldElement(5079312787147663415), field.NewFieldElement(315076378722635206)},
|
||||
{field.NewFieldElement(4656603487897834248), field.NewFieldElement(4455086801173740459)},
|
||||
{field.NewFieldElement(3630077482584148572), field.NewFieldElement(3283664780554963370)},
|
||||
{field.NewFieldElement(1781217475359761081), field.NewFieldElement(17627776820166298232)},
|
||||
{field.NewFieldElement(5917159494270473360), field.NewFieldElement(6025450051539258087)},
|
||||
{field.NewFieldElement(6450855110748081528), field.NewFieldElement(7446684637376438458)},
|
||||
{field.NewFieldElement(8607810652222212781), field.NewFieldElement(7298919685405344815)},
|
||||
{field.NewFieldElement(13906434081686233303), field.NewFieldElement(13101189135710264580)},
|
||||
{field.NewFieldElement(6489826249831576523), field.NewFieldElement(11224737887667008267)},
|
||||
{field.NewFieldElement(3580221348553931303), field.NewFieldElement(4662435202527050543)},
|
||||
{field.NewFieldElement(7286527320055156837), field.NewFieldElement(15670292738296412147)},
|
||||
{field.NewFieldElement(2095892346123668330), field.NewFieldElement(5572639395382198548)},
|
||||
{field.NewFieldElement(11836511250144945185), field.NewFieldElement(6212767141717037414)},
|
||||
{field.NewFieldElement(12781535798978127236), field.NewFieldElement(14467390350363203888)},
|
||||
{field.NewFieldElement(2635017860820288214), field.NewFieldElement(6092079726747224779)},
|
||||
{field.NewFieldElement(18057143820634196774), field.NewFieldElement(16137749920970128474)},
|
||||
{field.NewFieldElement(16754543715625171524), field.NewFieldElement(15674433195919785024)},
|
||||
{field.NewFieldElement(2135423350522303111), field.NewFieldElement(32407260862438164)},
|
||||
{field.NewFieldElement(14956506296276270245), field.NewFieldElement(1145919757338314609)},
|
||||
}
|
||||
|
||||
// ExponentiationGate { num_power_bits: 67, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
||||
var exponentiationGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(11917134172330913896), field.NewFieldElement(17387498340632768165)},
|
||||
{field.NewFieldElement(1312379412936626785), field.NewFieldElement(8487972230502205858)},
|
||||
{field.NewFieldElement(1034346392193469803), field.NewFieldElement(10387255969849204765)},
|
||||
{field.NewFieldElement(8975374558919785259), field.NewFieldElement(8379061308496297909)},
|
||||
{field.NewFieldElement(5137354887085653470), field.NewFieldElement(18342299770587131344)},
|
||||
{field.NewFieldElement(11284168756796657450), field.NewFieldElement(13822895496426653701)},
|
||||
{field.NewFieldElement(235168160386175185), field.NewFieldElement(17356178727442490793)},
|
||||
{field.NewFieldElement(11012326969983488833), field.NewFieldElement(13315935561725076264)},
|
||||
{field.NewFieldElement(11064160789252923988), field.NewFieldElement(243775009899162201)},
|
||||
{field.NewFieldElement(17368303548433332975), field.NewFieldElement(15625080509274199608)},
|
||||
{field.NewFieldElement(5849122830228985352), field.NewFieldElement(5103229940930953650)},
|
||||
{field.NewFieldElement(14713362802405597126), field.NewFieldElement(8157398625845036781)},
|
||||
{field.NewFieldElement(16495373179302807753), field.NewFieldElement(4597863041430416411)},
|
||||
{field.NewFieldElement(3274329863393011112), field.NewFieldElement(8955190641874111502)},
|
||||
{field.NewFieldElement(4704531612240997322), field.NewFieldElement(2253948388369651634)},
|
||||
{field.NewFieldElement(13333514818352143222), field.NewFieldElement(4999457874559250243)},
|
||||
{field.NewFieldElement(2284463506187861590), field.NewFieldElement(13765412523042072026)},
|
||||
{field.NewFieldElement(16636340184626646426), field.NewFieldElement(3174763529046637372)},
|
||||
{field.NewFieldElement(5336400619848923540), field.NewFieldElement(10513883740898299385)},
|
||||
{field.NewFieldElement(14200134528033869480), field.NewFieldElement(11039588311485209657)},
|
||||
{field.NewFieldElement(18377155443679293884), field.NewFieldElement(13521764320839726823)},
|
||||
{field.NewFieldElement(242773453939591946), field.NewFieldElement(6326451192242543829)},
|
||||
{field.NewFieldElement(1296949085249594883), field.NewFieldElement(7990211688523987915)},
|
||||
{field.NewFieldElement(5510982641888481009), field.NewFieldElement(10552089306004766754)},
|
||||
{field.NewFieldElement(10914255593671877946), field.NewFieldElement(18175495064507840841)},
|
||||
{field.NewFieldElement(7575617967752753230), field.NewFieldElement(9665518441862148402)},
|
||||
{field.NewFieldElement(14351249981525100362), field.NewFieldElement(5763278800672952095)},
|
||||
{field.NewFieldElement(16319397571073742470), field.NewFieldElement(1318308384414985616)},
|
||||
{field.NewFieldElement(12030088917335470405), field.NewFieldElement(6668172884819717021)},
|
||||
{field.NewFieldElement(17509060699703766693), field.NewFieldElement(1489607021074587548)},
|
||||
{field.NewFieldElement(1096695845774334385), field.NewFieldElement(6122861634465429123)},
|
||||
{field.NewFieldElement(13460252757128783693), field.NewFieldElement(17777045084091738197)},
|
||||
{field.NewFieldElement(14557885155010631641), field.NewFieldElement(4298885986874834349)},
|
||||
{field.NewFieldElement(3635088766034344822), field.NewFieldElement(8827496887313967507)},
|
||||
{field.NewFieldElement(6550916348715580989), field.NewFieldElement(4180030543088252998)},
|
||||
{field.NewFieldElement(16051569484464055768), field.NewFieldElement(2121040925634405127)},
|
||||
{field.NewFieldElement(1788913367411914907), field.NewFieldElement(10745316805250218547)},
|
||||
{field.NewFieldElement(4832917661842853637), field.NewFieldElement(1148465658973892394)},
|
||||
{field.NewFieldElement(9162757057100424164), field.NewFieldElement(7814738929773741429)},
|
||||
{field.NewFieldElement(13840071942242698046), field.NewFieldElement(12500211120922811757)},
|
||||
{field.NewFieldElement(10699948139249128560), field.NewFieldElement(4891144553679573560)},
|
||||
{field.NewFieldElement(14602444997841482522), field.NewFieldElement(17017251371157941125)},
|
||||
{field.NewFieldElement(586839629673374241), field.NewFieldElement(3363863469002405744)},
|
||||
{field.NewFieldElement(9011045001648305113), field.NewFieldElement(7085187243048562102)},
|
||||
{field.NewFieldElement(13032999395920684322), field.NewFieldElement(6189400872664562846)},
|
||||
{field.NewFieldElement(8971070287177655421), field.NewFieldElement(12582676780734324056)},
|
||||
{field.NewFieldElement(558400378011382278), field.NewFieldElement(6298195151594790629)},
|
||||
{field.NewFieldElement(17192073729541567806), field.NewFieldElement(5497805500866221538)},
|
||||
{field.NewFieldElement(5728605922884243514), field.NewFieldElement(18070340533610014206)},
|
||||
{field.NewFieldElement(15473455953886985277), field.NewFieldElement(11635823818659992567)},
|
||||
{field.NewFieldElement(7477545430207969908), field.NewFieldElement(2742755471302540300)},
|
||||
{field.NewFieldElement(12407179232895419141), field.NewFieldElement(17302315821428133291)},
|
||||
{field.NewFieldElement(12858531909631903407), field.NewFieldElement(14746185565916474858)},
|
||||
{field.NewFieldElement(12872867896453911017), field.NewFieldElement(6563250576201773751)},
|
||||
{field.NewFieldElement(3384183107205264844), field.NewFieldElement(11512795156033923138)},
|
||||
{field.NewFieldElement(8430135350637925522), field.NewFieldElement(10199901650713033996)},
|
||||
{field.NewFieldElement(11167364659650598214), field.NewFieldElement(447394121422751322)},
|
||||
{field.NewFieldElement(4931438368828291722), field.NewFieldElement(16717867949669373753)},
|
||||
{field.NewFieldElement(5151270559741115914), field.NewFieldElement(45949586886299827)},
|
||||
{field.NewFieldElement(11159644559144981603), field.NewFieldElement(2120703503452727949)},
|
||||
{field.NewFieldElement(8830601119784247875), field.NewFieldElement(8542262650554393830)},
|
||||
{field.NewFieldElement(6142186624494698182), field.NewFieldElement(7120939306807396235)},
|
||||
{field.NewFieldElement(11716893898091265261), field.NewFieldElement(4311673012489504666)},
|
||||
{field.NewFieldElement(2133003157459487893), field.NewFieldElement(1909522153859214178)},
|
||||
{field.NewFieldElement(427412581044646901), field.NewFieldElement(15454912207372224939)},
|
||||
{field.NewFieldElement(1842301960762096227), field.NewFieldElement(12476329615991638721)},
|
||||
{field.NewFieldElement(696538585954127499), field.NewFieldElement(2702122491633241201)},
|
||||
{field.NewFieldElement(5755584054765687076), field.NewFieldElement(5430280214517080555)},
|
||||
}
|
||||
|
||||
// CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>
|
||||
var cosetInterpolationGateExpectedConstraints = []field.QuadraticExtension{
|
||||
{field.NewFieldElement(13782516617623808439), field.NewFieldElement(15116825128522139629)},
|
||||
{field.NewFieldElement(10605488313706531843), field.NewFieldElement(16124703860676816956)},
|
||||
{field.NewFieldElement(2725554495824998780), field.NewFieldElement(13477621298303015045)},
|
||||
{field.NewFieldElement(2936187345854242438), field.NewFieldElement(5827982872566017395)},
|
||||
{field.NewFieldElement(11223822863576777799), field.NewFieldElement(2143123911507599653)},
|
||||
{field.NewFieldElement(4839015650475288776), field.NewFieldElement(745790217755162273)},
|
||||
{field.NewFieldElement(2205634412980832213), field.NewFieldElement(15767892564871259137)},
|
||||
{field.NewFieldElement(9091626478775122653), field.NewFieldElement(9730482292097571809)},
|
||||
{field.NewFieldElement(10636787321971723634), field.NewFieldElement(14666593583448965088)},
|
||||
{field.NewFieldElement(7179924177530514890), field.NewFieldElement(10610536358289043895)},
|
||||
{field.NewFieldElement(15067680125330943902), field.NewFieldElement(17960901266185771082)},
|
||||
{field.NewFieldElement(5184847499291037169), field.NewFieldElement(16061742535733361053)},
|
||||
}
|
||||
|
||||
type TestGateCircuit struct {
|
||||
testGate gates.Gate
|
||||
expectedConstraints []field.QuadraticExtension
|
||||
}
|
||||
|
||||
func (circuit *TestGateCircuit) Define(api frontend.API) error {
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData("../../data/recursive_step/common_circuit_data.json")
|
||||
numSelectors := commonCircuitData.SelectorsInfo.NumSelectors()
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
|
||||
|
||||
vars := gates.NewEvaluationVars(localConstants[numSelectors:], localWires, publicInputsHash)
|
||||
|
||||
constraints := circuit.testGate.EvalUnfiltered(api, qeAPI, *vars)
|
||||
|
||||
if len(constraints) != len(circuit.expectedConstraints) {
|
||||
return errors.New("gate constraints length mismatch")
|
||||
}
|
||||
for i := 0; i < len(constraints); i++ {
|
||||
qeAPI.AssertIsEqual(constraints[i], circuit.expectedConstraints[i])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestGates(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func(testGate gates.Gate, expectedConstraints []field.QuadraticExtension) {
|
||||
circuit := &TestGateCircuit{testGate: testGate, expectedConstraints: expectedConstraints}
|
||||
witness := &TestGateCircuit{testGate: testGate, expectedConstraints: expectedConstraints}
|
||||
err := test.IsSolved(circuit, witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
type gateTest struct {
|
||||
testGate gates.Gate
|
||||
expectedConstraints []field.QuadraticExtension
|
||||
}
|
||||
|
||||
gateTests := []gateTest{
|
||||
{gates.NewPublicInputGate(), publicInputGateExpectedConstraints},
|
||||
{gates.NewArithmeticGate(20), arithmeticGateExpectedConstraints},
|
||||
{gates.NewBaseSumGate(63, 2), baseSumGateExpectedConstraints},
|
||||
{gates.NewRandomAccessGate(4, 4, 2), randomAccessGateExpectedConstraints},
|
||||
{gates.NewPoseidonGate(), poseidonGateExpectedConstraints},
|
||||
{gates.NewArithmeticExtensionGate(10), arithmeticExtensionGateExpectedConstraints},
|
||||
{gates.NewMultiplicationExtensionGate(13), mulExtensionGateExpectedConstraints},
|
||||
{gates.NewReducingExtensionGate(33), reducingExtensionGateExpectedConstraints},
|
||||
{gates.NewReducingGate(44), reducingGateExpectedConstraints},
|
||||
{gates.NewExponentiationGate(67), exponentiationGateExpectedConstraints},
|
||||
{gates.NewCosetInterpolationGate(
|
||||
4,
|
||||
6,
|
||||
[]goldilocks.Element{
|
||||
goldilocks.NewElement(17293822565076172801),
|
||||
goldilocks.NewElement(18374686475376656385),
|
||||
goldilocks.NewElement(18446744069413535745),
|
||||
goldilocks.NewElement(281474976645120),
|
||||
goldilocks.NewElement(17592186044416),
|
||||
goldilocks.NewElement(18446744069414584577),
|
||||
goldilocks.NewElement(18446744000695107601),
|
||||
goldilocks.NewElement(18446744065119617025),
|
||||
goldilocks.NewElement(1152921504338411520),
|
||||
goldilocks.NewElement(72057594037927936),
|
||||
goldilocks.NewElement(18446744069415632897),
|
||||
goldilocks.NewElement(18446462594437939201),
|
||||
goldilocks.NewElement(18446726477228539905),
|
||||
goldilocks.NewElement(18446744069414584065),
|
||||
goldilocks.NewElement(68719476720),
|
||||
goldilocks.NewElement(4294967296),
|
||||
},
|
||||
), cosetInterpolationGateExpectedConstraints},
|
||||
}
|
||||
|
||||
for _, test := range gateTests {
|
||||
testCase(
|
||||
test.testGate,
|
||||
test.expectedConstraints,
|
||||
)
|
||||
}
|
||||
}
|
||||
74
verifier/internal/gates/multiplication_extension_gate.go
Normal file
74
verifier/internal/gates/multiplication_extension_gate.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var mulExtensionGateRegex = regexp.MustCompile("MulExtensionGate { num_ops: (?P<numOps>[0-9]+) }")
|
||||
|
||||
func deserializeMulExtensionGate(parameters map[string]string) Gate {
|
||||
// Has the format "MulExtensionGate { num_ops: 13 }"
|
||||
numOps, hasNumOps := parameters["numOps"]
|
||||
if !hasNumOps {
|
||||
panic("Missing field num_ops in MulExtensionGate")
|
||||
}
|
||||
|
||||
numOpsInt, err := strconv.Atoi(numOps)
|
||||
if err != nil {
|
||||
panic("Invalid num_ops field in MulExtensionGate")
|
||||
}
|
||||
|
||||
return NewMultiplicationExtensionGate(uint64(numOpsInt))
|
||||
}
|
||||
|
||||
type MultiplicationExtensionGate struct {
|
||||
numOps uint64
|
||||
}
|
||||
|
||||
func NewMultiplicationExtensionGate(numOps uint64) *MultiplicationExtensionGate {
|
||||
return &MultiplicationExtensionGate{
|
||||
numOps: numOps,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) Id() string {
|
||||
return fmt.Sprintf("ArithmeticExtensionGate { num_ops: %d }", g.numOps)
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) wiresIthMultiplicand0(i uint64) Range {
|
||||
return Range{3 * field.D * i, 3*field.D*i + field.D}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) wiresIthMultiplicand1(i uint64) Range {
|
||||
return Range{3*field.D*i + field.D, 3*field.D*i + 2*field.D}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) wiresIthOutput(i uint64) Range {
|
||||
return Range{3*field.D*i + 2*field.D, 3*field.D*i + 3*field.D}
|
||||
}
|
||||
|
||||
func (g *MultiplicationExtensionGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
const0 := vars.localConstants[0]
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.numOps; i++ {
|
||||
multiplicand0 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand0(i))
|
||||
multiplicand1 := vars.GetLocalExtAlgebra(g.wiresIthMultiplicand1(i))
|
||||
output := vars.GetLocalExtAlgebra(g.wiresIthOutput(i))
|
||||
|
||||
mul := qeAPI.MulExtensionAlgebra(multiplicand0, multiplicand1)
|
||||
computed_output := qeAPI.ScalarMulExtensionAlgebra(const0, mul)
|
||||
|
||||
diff := qeAPI.SubExtensionAlgebra(output, computed_output)
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, diff[j])
|
||||
}
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
30
verifier/internal/gates/noop_gate.go
Normal file
30
verifier/internal/gates/noop_gate.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var noopGateRegex = regexp.MustCompile("NoopGate")
|
||||
|
||||
func deserializeNoopGate(parameters map[string]string) Gate {
|
||||
// Has the format "NoopGate"
|
||||
return NewNoopGate()
|
||||
}
|
||||
|
||||
type NoopGate struct {
|
||||
}
|
||||
|
||||
func NewNoopGate() *NoopGate {
|
||||
return &NoopGate{}
|
||||
}
|
||||
|
||||
func (g *NoopGate) Id() string {
|
||||
return "NoopGate"
|
||||
}
|
||||
|
||||
func (g *NoopGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
return []field.QuadraticExtension{}
|
||||
}
|
||||
177
verifier/internal/gates/poseidon_gate.go
Normal file
177
verifier/internal/gates/poseidon_gate.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
)
|
||||
|
||||
var poseidonGateRegex = regexp.MustCompile("PoseidonGate.*")
|
||||
|
||||
func deserializePoseidonGate(parameters map[string]string) Gate {
|
||||
// Has the format "PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
||||
return NewPoseidonGate()
|
||||
}
|
||||
|
||||
type PoseidonGate struct {
|
||||
}
|
||||
|
||||
func NewPoseidonGate() *PoseidonGate {
|
||||
return &PoseidonGate{}
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) Id() string {
|
||||
return "PoseidonGate"
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WireInput(i uint64) uint64 {
|
||||
return i
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WireOutput(i uint64) uint64 {
|
||||
return poseidon.SPONGE_WIDTH + i
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WireSwap() uint64 {
|
||||
return 2 * poseidon.SPONGE_WIDTH
|
||||
}
|
||||
|
||||
const START_DELTA = 2*poseidon.SPONGE_WIDTH + 1
|
||||
|
||||
func (g *PoseidonGate) WireDelta(i uint64) uint64 {
|
||||
if i >= 4 {
|
||||
panic("Delta index out of range")
|
||||
}
|
||||
return START_DELTA + i
|
||||
}
|
||||
|
||||
const START_FULL_0 = START_DELTA + 4
|
||||
|
||||
func (g *PoseidonGate) WireFullSBox0(round uint64, i uint64) uint64 {
|
||||
if round == 0 {
|
||||
panic("First-round S-box inputs are not stored as wires")
|
||||
}
|
||||
if round >= poseidon.HALF_N_FULL_ROUNDS {
|
||||
panic("S-box input round out of range")
|
||||
}
|
||||
if i >= poseidon.SPONGE_WIDTH {
|
||||
panic("S-box input index out of range")
|
||||
}
|
||||
|
||||
return START_FULL_0 + (round-1)*poseidon.SPONGE_WIDTH + i
|
||||
}
|
||||
|
||||
const START_PARTIAL = START_FULL_0 + (poseidon.HALF_N_FULL_ROUNDS-1)*poseidon.SPONGE_WIDTH
|
||||
|
||||
func (g *PoseidonGate) WirePartialSBox(round uint64) uint64 {
|
||||
if round >= poseidon.N_PARTIAL_ROUNDS {
|
||||
panic("S-box input round out of range")
|
||||
}
|
||||
return START_PARTIAL + round
|
||||
}
|
||||
|
||||
const START_FULL_1 = START_PARTIAL + poseidon.N_PARTIAL_ROUNDS
|
||||
|
||||
func (g *PoseidonGate) WireFullSBox1(round uint64, i uint64) uint64 {
|
||||
if round >= poseidon.HALF_N_FULL_ROUNDS {
|
||||
panic("S-box input round out of range")
|
||||
}
|
||||
if i >= poseidon.SPONGE_WIDTH {
|
||||
panic("S-box input index out of range")
|
||||
}
|
||||
|
||||
return START_FULL_1 + round*poseidon.SPONGE_WIDTH + i
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) WiresEnd() uint64 {
|
||||
return START_FULL_1 + poseidon.HALF_N_FULL_ROUNDS*poseidon.SPONGE_WIDTH
|
||||
}
|
||||
|
||||
func (g *PoseidonGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, field.NewFieldAPI(api), qeAPI)
|
||||
|
||||
// Assert that `swap` is binary.
|
||||
swap := vars.localWires[g.WireSwap()]
|
||||
swapMinusOne := qeAPI.SubExtension(swap, qeAPI.FieldToQE(field.ONE_F))
|
||||
constraints = append(constraints, qeAPI.MulExtension(swap, swapMinusOne))
|
||||
|
||||
// Assert that each delta wire is set properly: `delta_i = swap * (rhs - lhs)`.
|
||||
for i := uint64(0); i < 4; i++ {
|
||||
inputLhs := vars.localWires[g.WireInput(i)]
|
||||
inputRhs := vars.localWires[g.WireInput(i+4)]
|
||||
deltaI := vars.localWires[g.WireDelta(i)]
|
||||
diff := qeAPI.SubExtension(inputRhs, inputLhs)
|
||||
expectedDeltaI := qeAPI.MulExtension(swap, diff)
|
||||
constraints = append(constraints, qeAPI.SubExtension(expectedDeltaI, deltaI))
|
||||
}
|
||||
|
||||
// Compute the possibly-swapped input layer.
|
||||
var state [poseidon.SPONGE_WIDTH]field.QuadraticExtension
|
||||
for i := uint64(0); i < 4; i++ {
|
||||
deltaI := vars.localWires[g.WireDelta(i)]
|
||||
inputLhs := vars.localWires[g.WireInput(i)]
|
||||
inputRhs := vars.localWires[g.WireInput(i+4)]
|
||||
state[i] = qeAPI.AddExtension(inputLhs, deltaI)
|
||||
state[i+4] = qeAPI.SubExtension(inputRhs, deltaI)
|
||||
}
|
||||
for i := uint64(8); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
state[i] = vars.localWires[g.WireInput(i)]
|
||||
}
|
||||
|
||||
roundCounter := 0
|
||||
|
||||
// First set of full rounds.
|
||||
for r := uint64(0); r < poseidon.HALF_N_FULL_ROUNDS; r++ {
|
||||
state = poseidonChip.ConstantLayerExtension(state, &roundCounter)
|
||||
if r != 0 {
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
sBoxIn := vars.localWires[g.WireFullSBox0(r, i)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[i], sBoxIn))
|
||||
state[i] = sBoxIn
|
||||
}
|
||||
}
|
||||
state = poseidonChip.SBoxLayerExtension(state)
|
||||
state = poseidonChip.MdsLayerExtension(state)
|
||||
roundCounter++
|
||||
}
|
||||
|
||||
// Partial rounds.
|
||||
state = poseidonChip.PartialFirstConstantLayerExtension(state)
|
||||
state = poseidonChip.MdsPartialLayerInitExtension(state)
|
||||
|
||||
for r := uint64(0); r < poseidon.N_PARTIAL_ROUNDS-1; r++ {
|
||||
sBoxIn := vars.localWires[g.WirePartialSBox(r)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[0], sBoxIn))
|
||||
state[0] = poseidonChip.SBoxMonomialExtension(sBoxIn)
|
||||
state[0] = qeAPI.AddExtension(state[0], qeAPI.FieldToQE(field.NewFieldElement(poseidon.FAST_PARTIAL_ROUND_CONSTANTS[r])))
|
||||
state = poseidonChip.MdsPartialLayerFastExtension(state, int(r))
|
||||
}
|
||||
sBoxIn := vars.localWires[g.WirePartialSBox(poseidon.N_PARTIAL_ROUNDS-1)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[0], sBoxIn))
|
||||
state[0] = poseidonChip.SBoxMonomialExtension(sBoxIn)
|
||||
state = poseidonChip.MdsPartialLayerFastExtension(state, poseidon.N_PARTIAL_ROUNDS-1)
|
||||
roundCounter += poseidon.N_PARTIAL_ROUNDS
|
||||
|
||||
// Second set of full rounds.
|
||||
for r := uint64(0); r < poseidon.HALF_N_FULL_ROUNDS; r++ {
|
||||
state = poseidonChip.ConstantLayerExtension(state, &roundCounter)
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
sBoxIn := vars.localWires[g.WireFullSBox1(r, i)]
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[i], sBoxIn))
|
||||
state[i] = sBoxIn
|
||||
}
|
||||
state = poseidonChip.SBoxLayerExtension(state)
|
||||
state = poseidonChip.MdsLayerExtension(state)
|
||||
roundCounter++
|
||||
}
|
||||
|
||||
for i := uint64(0); i < poseidon.SPONGE_WIDTH; i++ {
|
||||
constraints = append(constraints, qeAPI.SubExtension(state[i], vars.localWires[g.WireOutput(i)]))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
46
verifier/internal/gates/public_input_gate.go
Normal file
46
verifier/internal/gates/public_input_gate.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var publicInputGateRegex = regexp.MustCompile("PublicInputGate")
|
||||
|
||||
func deserializePublicInputGate(parameters map[string]string) Gate {
|
||||
// Has the format "PublicInputGate"
|
||||
return NewPublicInputGate()
|
||||
}
|
||||
|
||||
type PublicInputGate struct {
|
||||
}
|
||||
|
||||
func NewPublicInputGate() *PublicInputGate {
|
||||
return &PublicInputGate{}
|
||||
}
|
||||
|
||||
func (g *PublicInputGate) Id() string {
|
||||
return "PublicInputGate"
|
||||
}
|
||||
|
||||
func (g *PublicInputGate) WiresPublicInputsHash() []uint64 {
|
||||
return []uint64{0, 1, 2, 3}
|
||||
}
|
||||
|
||||
func (g *PublicInputGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
wires := g.WiresPublicInputsHash()
|
||||
hash_parts := vars.publicInputsHash
|
||||
for i := 0; i < 4; i++ {
|
||||
wire := wires[i]
|
||||
hash_part := hash_parts[i]
|
||||
|
||||
diff := qeAPI.SubExtension(vars.localWires[wire], qeAPI.FieldToQE(hash_part))
|
||||
constraints = append(constraints, diff)
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
174
verifier/internal/gates/random_access_gate.go
Normal file
174
verifier/internal/gates/random_access_gate.go
Normal file
@@ -0,0 +1,174 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var randomAccessGateRegex = regexp.MustCompile("RandomAccessGate { bits: (?P<bits>[0-9]+), num_copies: (?P<numCopies>[0-9]+), num_extra_constants: (?P<numExtraConstants>[0-9]+), _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=(?P<base>[0-9]+)>")
|
||||
|
||||
func deserializeRandomAccessGate(parameters map[string]string) Gate {
|
||||
// Has the format "RandomAccessGate { bits: 2, num_copies: 13, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>"
|
||||
bits, hasBits := parameters["bits"]
|
||||
numCopies, hasNumCopies := parameters["numCopies"]
|
||||
numExtraConstants, hasNumExtraConstants := parameters["numExtraConstants"]
|
||||
|
||||
if !hasBits || !hasNumCopies || !hasNumExtraConstants {
|
||||
panic("missing bits, numCopies, numExtraConstants or base in RandomAccessGate")
|
||||
}
|
||||
|
||||
bitsInt, err := strconv.ParseUint(bits, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid bits in RandomAccessGate")
|
||||
}
|
||||
|
||||
numCopiesInt, err := strconv.ParseUint(numCopies, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid numCopies in RandomAccessGate")
|
||||
}
|
||||
|
||||
numExtraConstantsInt, err := strconv.ParseUint(numExtraConstants, 10, 64)
|
||||
if err != nil {
|
||||
panic("invalid numExtraConstants in RandomAccessGate")
|
||||
}
|
||||
|
||||
return NewRandomAccessGate(bitsInt, numCopiesInt, numExtraConstantsInt)
|
||||
}
|
||||
|
||||
type RandomAccessGate struct {
|
||||
bits uint64
|
||||
numCopies uint64
|
||||
numExtraConstants uint64
|
||||
}
|
||||
|
||||
func NewRandomAccessGate(bits uint64, numCopies uint64, numExtraConstants uint64) *RandomAccessGate {
|
||||
return &RandomAccessGate{
|
||||
bits: bits,
|
||||
numCopies: numCopies,
|
||||
numExtraConstants: numExtraConstants,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) Id() string {
|
||||
return fmt.Sprintf("RandomAccessGate { bits: %d, num_copies: %d, num_extra_constants: %d }", g.bits, g.numCopies, g.numExtraConstants)
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) vecSize() uint64 {
|
||||
return 1 << g.bits
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireAccessIndex(copy uint64) uint64 {
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireAccessIndex called with copy >= num_copies")
|
||||
}
|
||||
return (2 + g.vecSize()) * copy
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireClaimedElement(copy uint64) uint64 {
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireClaimedElement called with copy >= num_copies")
|
||||
}
|
||||
|
||||
return (2+g.vecSize())*copy + 1
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireListItem(i uint64, copy uint64) uint64 {
|
||||
if i >= g.vecSize() {
|
||||
panic("RandomAccessGate.WireListItem called with i >= vec_size")
|
||||
}
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireListItem called with copy >= num_copies")
|
||||
}
|
||||
|
||||
return (2+g.vecSize())*copy + 2 + i
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) startExtraConstants() uint64 {
|
||||
return (2 + g.vecSize()) * g.numCopies
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) wireExtraConstant(i uint64) uint64 {
|
||||
if i >= g.numExtraConstants {
|
||||
panic("RandomAccessGate.wireExtraConstant called with i >= num_extra_constants")
|
||||
}
|
||||
|
||||
return g.startExtraConstants() + i
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) NumRoutedWires() uint64 {
|
||||
return g.startExtraConstants() + g.numExtraConstants
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) WireBit(i uint64, copy uint64) uint64 {
|
||||
if i >= g.bits {
|
||||
panic("RandomAccessGate.WireBit called with i >= bits")
|
||||
}
|
||||
if copy >= g.numCopies {
|
||||
panic("RandomAccessGate.WireBit called with copy >= num_copies")
|
||||
}
|
||||
|
||||
return g.NumRoutedWires() + copy*g.bits + i
|
||||
}
|
||||
|
||||
func (g *RandomAccessGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
two := field.QuadraticExtension{field.NewFieldElement(2), field.NewFieldElement(0)}
|
||||
constraints := []field.QuadraticExtension{}
|
||||
|
||||
for copy := uint64(0); copy < g.numCopies; copy++ {
|
||||
accessIndex := vars.localWires[g.WireAccessIndex(copy)]
|
||||
listItems := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.vecSize(); i++ {
|
||||
listItems = append(listItems, vars.localWires[g.WireListItem(i, copy)])
|
||||
}
|
||||
claimedElement := vars.localWires[g.WireClaimedElement(copy)]
|
||||
bits := []field.QuadraticExtension{}
|
||||
for i := uint64(0); i < g.bits; i++ {
|
||||
bits = append(bits, vars.localWires[g.WireBit(i, copy)])
|
||||
}
|
||||
|
||||
// Assert that each bit wire value is indeed boolean.
|
||||
for _, b := range bits {
|
||||
bSquared := qeAPI.MulExtension(b, b)
|
||||
constraints = append(constraints, qeAPI.SubExtension(bSquared, b))
|
||||
}
|
||||
|
||||
// Assert that the binary decomposition was correct.
|
||||
reconstructedIndex := qeAPI.ReduceWithPowers(bits, two)
|
||||
constraints = append(constraints, qeAPI.SubExtension(reconstructedIndex, accessIndex))
|
||||
|
||||
for _, b := range bits {
|
||||
listItemsTmp := []field.QuadraticExtension{}
|
||||
for i := 0; i < len(listItems); i += 2 {
|
||||
x := listItems[i]
|
||||
y := listItems[i+1]
|
||||
|
||||
// This is computing `if b { x } else { y }`
|
||||
// i.e. `bx - (by-y)`.
|
||||
mul1 := qeAPI.MulExtension(b, x)
|
||||
sub1 := qeAPI.SubExtension(mul1, x)
|
||||
|
||||
mul2 := qeAPI.MulExtension(b, y)
|
||||
sub2 := qeAPI.SubExtension(mul2, sub1)
|
||||
|
||||
listItemsTmp = append(listItemsTmp, sub2)
|
||||
}
|
||||
listItems = listItemsTmp
|
||||
}
|
||||
|
||||
if len(listItems) != 1 {
|
||||
panic("listItems(len) != 1")
|
||||
}
|
||||
|
||||
constraints = append(constraints, qeAPI.SubExtension(listItems[0], claimedElement))
|
||||
}
|
||||
|
||||
for i := uint64(0); i < g.numExtraConstants; i++ {
|
||||
constraints = append(constraints, qeAPI.SubExtension(vars.localConstants[i], vars.localWires[g.wireExtraConstant(i)]))
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
105
verifier/internal/gates/reducing_extension_gate.go
Normal file
105
verifier/internal/gates/reducing_extension_gate.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var reducingExtensionGateRegex = regexp.MustCompile("ReducingExtensionGate { num_coeffs: (?P<numCoeffs>[0-9]+) }")
|
||||
|
||||
func deserializeReducingExtensionGate(parameters map[string]string) Gate {
|
||||
// Has the format "ReducingGate { num_coeffs: 33 }"
|
||||
numCoeffs, hasNumCoeffs := parameters["numCoeffs"]
|
||||
if !hasNumCoeffs {
|
||||
panic("Missing field num_coeffs in ReducingExtensionGate")
|
||||
}
|
||||
|
||||
numCoeffsInt, err := strconv.Atoi(numCoeffs)
|
||||
if err != nil {
|
||||
panic("Invalid num_coeffs field in ReducingExtensionGate")
|
||||
}
|
||||
|
||||
return NewReducingExtensionGate(uint64(numCoeffsInt))
|
||||
}
|
||||
|
||||
type ReducingExtensionGate struct {
|
||||
numCoeffs uint64
|
||||
}
|
||||
|
||||
const START_COEFFS_REDUCING_EXTENSION_GATE = 3 * field.D
|
||||
|
||||
func NewReducingExtensionGate(numCoeffs uint64) *ReducingExtensionGate {
|
||||
return &ReducingExtensionGate{
|
||||
numCoeffs: numCoeffs,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) Id() string {
|
||||
return fmt.Sprintf("ReducingExtensionGate { num_ops: %d }", g.numCoeffs)
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresOutput() Range {
|
||||
return Range{0, field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresAlpha() Range {
|
||||
return Range{field.D, 2 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresOldAcc() Range {
|
||||
return Range{2 * field.D, 3 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresCoeff(i uint64) Range {
|
||||
return Range{START_COEFFS_REDUCING_EXTENSION_GATE + field.D*i, START_COEFFS_REDUCING_EXTENSION_GATE + field.D*(i+1)}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) startAccs() uint64 {
|
||||
return START_COEFFS_REDUCING_EXTENSION_GATE + g.numCoeffs*field.D
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) wiresAccs(i uint64) Range {
|
||||
if i >= g.numCoeffs {
|
||||
panic("Accumulator index out of bounds")
|
||||
}
|
||||
|
||||
if i == g.numCoeffs-1 {
|
||||
return g.wiresOutput()
|
||||
}
|
||||
|
||||
return Range{g.startAccs() + field.D*i, g.startAccs() + field.D*(i+1)}
|
||||
}
|
||||
|
||||
func (g *ReducingExtensionGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
alpha := vars.GetLocalExtAlgebra(g.wiresAlpha())
|
||||
oldAcc := vars.GetLocalExtAlgebra(g.wiresOldAcc())
|
||||
|
||||
coeffs := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
coeffs = append(coeffs, vars.GetLocalExtAlgebra(g.wiresCoeff(i)))
|
||||
}
|
||||
|
||||
accs := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
accs = append(accs, vars.GetLocalExtAlgebra(g.wiresAccs(i)))
|
||||
}
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
acc := oldAcc
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
coeff := coeffs[i]
|
||||
tmp := qeAPI.MulExtensionAlgebra(acc, alpha)
|
||||
tmp = qeAPI.AddExtensionAlgebra(tmp, coeff)
|
||||
tmp = qeAPI.SubExtensionAlgebra(tmp, accs[i])
|
||||
for j := uint64(0); j < field.D; j++ {
|
||||
constraints = append(constraints, tmp[j])
|
||||
}
|
||||
acc = accs[i]
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
110
verifier/internal/gates/reducing_gate.go
Normal file
110
verifier/internal/gates/reducing_gate.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
)
|
||||
|
||||
var reducingGateRegex = regexp.MustCompile("ReducingGate { num_coeffs: (?P<numCoeffs>[0-9]+) }")
|
||||
|
||||
func deserializeReducingGate(parameters map[string]string) Gate {
|
||||
// Has the format "ReducingGate { num_coeffs: 33 }"
|
||||
numCoeffs, hasNumCoeffs := parameters["numCoeffs"]
|
||||
if !hasNumCoeffs {
|
||||
panic("Missing field num_coeffs in ReducingGate")
|
||||
}
|
||||
|
||||
numCoeffsInt, err := strconv.Atoi(numCoeffs)
|
||||
if err != nil {
|
||||
panic("Invalid num_coeffs field in ReducingGate")
|
||||
}
|
||||
|
||||
return NewReducingGate(uint64(numCoeffsInt))
|
||||
}
|
||||
|
||||
type ReducingGate struct {
|
||||
numCoeffs uint64
|
||||
}
|
||||
|
||||
const START_COEFFS_REDUCING_GATE = 3 * field.D
|
||||
|
||||
func NewReducingGate(numCoeffs uint64) *ReducingGate {
|
||||
return &ReducingGate{
|
||||
numCoeffs: numCoeffs,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) Id() string {
|
||||
return fmt.Sprintf("ReducingExtensionGate { num_ops: %d }", g.numCoeffs)
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresOutput() Range {
|
||||
return Range{0, field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresAlpha() Range {
|
||||
return Range{field.D, 2 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresOldAcc() Range {
|
||||
return Range{2 * field.D, 3 * field.D}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresCoeff() Range {
|
||||
return Range{START_COEFFS_REDUCING_GATE, START_COEFFS_REDUCING_GATE + g.numCoeffs}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) startAccs() uint64 {
|
||||
return START_COEFFS_REDUCING_GATE + g.numCoeffs
|
||||
}
|
||||
|
||||
func (g *ReducingGate) wiresAccs(i uint64) Range {
|
||||
if i >= g.numCoeffs {
|
||||
panic("Accumulator index out of bounds")
|
||||
}
|
||||
|
||||
if i == g.numCoeffs-1 {
|
||||
return g.wiresOutput()
|
||||
}
|
||||
|
||||
return Range{g.startAccs() + field.D*i, g.startAccs() + field.D*(i+1)}
|
||||
}
|
||||
|
||||
func (g *ReducingGate) EvalUnfiltered(api frontend.API, qeAPI *field.QuadraticExtensionAPI, vars EvaluationVars) []field.QuadraticExtension {
|
||||
alpha := vars.GetLocalExtAlgebra(g.wiresAlpha())
|
||||
oldAcc := vars.GetLocalExtAlgebra(g.wiresOldAcc())
|
||||
|
||||
coeffs := []field.QuadraticExtension{}
|
||||
coeffsRange := g.wiresCoeff()
|
||||
for i := coeffsRange.start; i < coeffsRange.end; i++ {
|
||||
coeffs = append(coeffs, vars.localWires[i])
|
||||
}
|
||||
|
||||
accs := []field.QEAlgebra{}
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
accs = append(accs, vars.GetLocalExtAlgebra(g.wiresAccs(i)))
|
||||
}
|
||||
|
||||
constraints := []field.QuadraticExtension{}
|
||||
acc := oldAcc
|
||||
for i := uint64(0); i < g.numCoeffs; i++ {
|
||||
var coeff field.QEAlgebra
|
||||
for j := 0; j < field.D; j++ {
|
||||
coeff[j] = qeAPI.ZERO_QE
|
||||
}
|
||||
coeff[0] = coeffs[i]
|
||||
tmp := qeAPI.MulExtensionAlgebra(acc, alpha)
|
||||
tmp = qeAPI.AddExtensionAlgebra(tmp, coeff)
|
||||
tmp = qeAPI.SubExtensionAlgebra(tmp, accs[i])
|
||||
for j := 0; j < field.D; j++ {
|
||||
constraints = append(constraints, tmp[j])
|
||||
}
|
||||
acc = accs[i]
|
||||
}
|
||||
|
||||
return constraints
|
||||
}
|
||||
36
verifier/internal/gates/selectors.go
Normal file
36
verifier/internal/gates/selectors.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package gates
|
||||
|
||||
const UNUSED_SELECTOR = uint64(^uint32(0)) // max uint32
|
||||
|
||||
type Range struct {
|
||||
start uint64
|
||||
end uint64
|
||||
}
|
||||
|
||||
type SelectorsInfo struct {
|
||||
selectorIndices []uint64
|
||||
groups []Range
|
||||
}
|
||||
|
||||
func NewSelectorsInfo(selectorIndices []uint64, groupStarts []uint64, groupEnds []uint64) *SelectorsInfo {
|
||||
if len(groupStarts) != len(groupEnds) {
|
||||
panic("groupStarts and groupEnds must have the same length")
|
||||
}
|
||||
|
||||
groups := []Range{}
|
||||
for i := range groupStarts {
|
||||
groups = append(groups, Range{
|
||||
start: groupStarts[i],
|
||||
end: groupEnds[i],
|
||||
})
|
||||
}
|
||||
|
||||
return &SelectorsInfo{
|
||||
selectorIndices: selectorIndices,
|
||||
groups: groups,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SelectorsInfo) NumSelectors() uint64 {
|
||||
return uint64(len(s.groups))
|
||||
}
|
||||
42
verifier/internal/gates/vars.go
Normal file
42
verifier/internal/gates/vars.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package gates
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
)
|
||||
|
||||
type EvaluationVars struct {
|
||||
localConstants []field.QuadraticExtension
|
||||
localWires []field.QuadraticExtension
|
||||
publicInputsHash poseidon.Hash
|
||||
}
|
||||
|
||||
func NewEvaluationVars(
|
||||
localConstants []field.QuadraticExtension,
|
||||
localWires []field.QuadraticExtension,
|
||||
publicInputsHash poseidon.Hash,
|
||||
) *EvaluationVars {
|
||||
return &EvaluationVars{
|
||||
localConstants: localConstants,
|
||||
localWires: localWires,
|
||||
publicInputsHash: publicInputsHash,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EvaluationVars) RemovePrefix(numSelectors uint64) {
|
||||
e.localConstants = e.localConstants[numSelectors:]
|
||||
}
|
||||
|
||||
func (e *EvaluationVars) GetLocalExtAlgebra(wireRange Range) field.QEAlgebra {
|
||||
// For now, only support degree 2
|
||||
if wireRange.end-wireRange.start != field.D {
|
||||
panic("Range must be of size D")
|
||||
}
|
||||
|
||||
var ret field.QEAlgebra
|
||||
for i := wireRange.start; i < wireRange.end; i++ {
|
||||
ret[i-wireRange.start] = e.localWires[i]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
153
verifier/internal/plonk/challenger.go
Normal file
153
verifier/internal/plonk/challenger.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package plonk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
|
||||
)
|
||||
|
||||
type ChallengerChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
field frontend.API `gnark:"-"`
|
||||
poseidonChip *poseidon.PoseidonChip
|
||||
spongeState [poseidon.SPONGE_WIDTH]field.F
|
||||
inputBuffer []field.F
|
||||
outputBuffer []field.F
|
||||
}
|
||||
|
||||
func NewChallengerChip(api frontend.API, fieldAPI frontend.API, poseidonChip *poseidon.PoseidonChip) *ChallengerChip {
|
||||
var spongeState [poseidon.SPONGE_WIDTH]field.F
|
||||
var inputBuffer []field.F
|
||||
var outputBuffer []field.F
|
||||
|
||||
for i := 0; i < poseidon.SPONGE_WIDTH; i++ {
|
||||
spongeState[i] = field.ZERO_F
|
||||
}
|
||||
|
||||
return &ChallengerChip{
|
||||
api: api,
|
||||
field: fieldAPI,
|
||||
poseidonChip: poseidonChip,
|
||||
spongeState: spongeState,
|
||||
inputBuffer: inputBuffer,
|
||||
outputBuffer: outputBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveElement(element field.F) {
|
||||
c.outputBuffer = clearBuffer(c.outputBuffer)
|
||||
c.inputBuffer = append(c.inputBuffer, element)
|
||||
if len(c.inputBuffer) == poseidon.SPONGE_RATE {
|
||||
c.duplexing()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveElements(elements []field.F) {
|
||||
for i := 0; i < len(elements); i++ {
|
||||
c.ObserveElement(elements[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveHash(hash poseidon.Hash) {
|
||||
c.ObserveElements(hash[:])
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveCap(cap []poseidon.Hash) {
|
||||
for i := 0; i < len(cap); i++ {
|
||||
c.ObserveHash(cap[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveExtensionElement(element field.QuadraticExtension) {
|
||||
c.ObserveElements(element[:])
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveExtensionElements(elements []field.QuadraticExtension) {
|
||||
for i := 0; i < len(elements); i++ {
|
||||
c.ObserveExtensionElement(elements[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) ObserveOpenings(openings fri.FriOpenings) {
|
||||
for i := 0; i < len(openings.Batches); i++ {
|
||||
c.ObserveExtensionElements(openings.Batches[i].Values)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetChallenge() field.F {
|
||||
if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
|
||||
c.duplexing()
|
||||
}
|
||||
|
||||
challenge := c.outputBuffer[len(c.outputBuffer)-1]
|
||||
c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1]
|
||||
|
||||
return challenge
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetNChallenges(n uint64) []field.F {
|
||||
challenges := make([]field.F, n)
|
||||
for i := uint64(0); i < n; i++ {
|
||||
challenges[i] = c.GetChallenge()
|
||||
}
|
||||
return challenges
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetExtensionChallenge() field.QuadraticExtension {
|
||||
values := c.GetNChallenges(2)
|
||||
return field.QuadraticExtension{values[0], values[1]}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetHash() poseidon.Hash {
|
||||
return [4]field.F{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()}
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) GetFriChallenges(commitPhaseMerkleCaps []common.MerkleCap, finalPoly common.PolynomialCoeffs, powWitness field.F, degreeBits uint64, config common.FriConfig) common.FriChallenges {
|
||||
numFriQueries := config.NumQueryRounds
|
||||
friAlpha := c.GetExtensionChallenge()
|
||||
|
||||
var friBetas []field.QuadraticExtension
|
||||
for i := 0; i < len(commitPhaseMerkleCaps); i++ {
|
||||
c.ObserveCap(commitPhaseMerkleCaps[i])
|
||||
friBetas = append(friBetas, c.GetExtensionChallenge())
|
||||
}
|
||||
|
||||
c.ObserveExtensionElements(finalPoly.Coeffs)
|
||||
c.ObserveElement(powWitness)
|
||||
|
||||
friPowResponse := c.GetChallenge()
|
||||
friQueryIndices := c.GetNChallenges(numFriQueries)
|
||||
|
||||
return common.FriChallenges{
|
||||
FriAlpha: friAlpha,
|
||||
FriBetas: friBetas,
|
||||
FriPowResponse: friPowResponse,
|
||||
FriQueryIndices: friQueryIndices,
|
||||
}
|
||||
}
|
||||
|
||||
func clearBuffer(buffer []field.F) []field.F {
|
||||
return make([]field.F, 0)
|
||||
}
|
||||
|
||||
func (c *ChallengerChip) duplexing() {
|
||||
if len(c.inputBuffer) > poseidon.SPONGE_RATE {
|
||||
fmt.Println(len(c.inputBuffer))
|
||||
panic("something went wrong")
|
||||
}
|
||||
|
||||
for i := 0; i < len(c.inputBuffer); i++ {
|
||||
c.spongeState[i] = c.inputBuffer[i]
|
||||
}
|
||||
c.inputBuffer = clearBuffer(c.inputBuffer)
|
||||
c.spongeState = c.poseidonChip.Poseidon(c.spongeState)
|
||||
clearBuffer(c.outputBuffer)
|
||||
for i := 0; i < poseidon.SPONGE_RATE; i++ {
|
||||
c.outputBuffer = append(c.outputBuffer, c.spongeState[i])
|
||||
// c.outputBuffer[i] = c.spongeState[i]
|
||||
}
|
||||
}
|
||||
225
verifier/internal/plonk/challenger_test.go
Normal file
225
verifier/internal/plonk/challenger_test.go
Normal file
@@ -0,0 +1,225 @@
|
||||
package plonk
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/utils"
|
||||
)
|
||||
|
||||
type TestChallengerCircuit struct {
|
||||
PublicInputs [3]frontend.Variable
|
||||
CircuitDigest [4]frontend.Variable
|
||||
WiresCap [16][4]frontend.Variable
|
||||
PlonkZsPartialProductsCap [16][4]frontend.Variable
|
||||
QuotientPolysCap [16][4]frontend.Variable
|
||||
}
|
||||
|
||||
func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
degreeBits := 3
|
||||
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, uint64(degreeBits))
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
|
||||
challengerChip := NewChallengerChip(api, fieldAPI, poseidonChip)
|
||||
|
||||
var circuitDigest [4]field.F
|
||||
for i := 0; i < len(circuitDigest); i++ {
|
||||
circuitDigest[i] = fieldAPI.FromBinary(api.ToBinary(circuit.CircuitDigest[i], 64)).(field.F)
|
||||
}
|
||||
|
||||
var publicInputs [3]field.F
|
||||
for i := 0; i < len(publicInputs); i++ {
|
||||
publicInputs[i] = fieldAPI.FromBinary(api.ToBinary(circuit.PublicInputs[i], 64)).(field.F)
|
||||
}
|
||||
|
||||
var wiresCap [16][4]field.F
|
||||
for i := 0; i < len(wiresCap); i++ {
|
||||
for j := 0; j < len(wiresCap[0]); j++ {
|
||||
wiresCap[i][j] = fieldAPI.FromBinary(api.ToBinary(circuit.WiresCap[i][j], 64)).(field.F)
|
||||
}
|
||||
}
|
||||
|
||||
var plonkZsPartialProductsCap [16][4]field.F
|
||||
for i := 0; i < len(plonkZsPartialProductsCap); i++ {
|
||||
for j := 0; j < len(plonkZsPartialProductsCap[0]); j++ {
|
||||
plonkZsPartialProductsCap[i][j] = fieldAPI.FromBinary(api.ToBinary(circuit.PlonkZsPartialProductsCap[i][j], 64)).(field.F)
|
||||
}
|
||||
}
|
||||
|
||||
var quotientPolysCap [16][4]field.F
|
||||
for i := 0; i < len(quotientPolysCap); i++ {
|
||||
for j := 0; j < len(quotientPolysCap[0]); j++ {
|
||||
quotientPolysCap[i][j] = fieldAPI.FromBinary(api.ToBinary(circuit.QuotientPolysCap[i][j], 64)).(field.F)
|
||||
}
|
||||
}
|
||||
|
||||
publicInputHash := poseidonChip.HashNoPad(publicInputs[:])
|
||||
challengerChip.ObserveHash(circuitDigest)
|
||||
challengerChip.ObserveHash(publicInputHash)
|
||||
challengerChip.ObserveCap(wiresCap[:])
|
||||
|
||||
numChallenges := uint64(2)
|
||||
plonkBetas := challengerChip.GetNChallenges(numChallenges)
|
||||
plonkGammas := challengerChip.GetNChallenges(numChallenges)
|
||||
|
||||
expectedPublicInputHash := [4]field.F{
|
||||
field.NewFieldElementFromString("8416658900775745054"),
|
||||
field.NewFieldElementFromString("12574228347150446423"),
|
||||
field.NewFieldElementFromString("9629056739760131473"),
|
||||
field.NewFieldElementFromString("3119289788404190010"),
|
||||
}
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
fieldAPI.AssertIsEqual(publicInputHash[i], expectedPublicInputHash[i])
|
||||
}
|
||||
|
||||
expectedPlonkBetas := [2]field.F{
|
||||
field.NewFieldElementFromString("4678728155650926271"),
|
||||
field.NewFieldElementFromString("13611962404289024887"),
|
||||
}
|
||||
|
||||
expectedPlonkGammas := [2]frontend.Variable{
|
||||
field.NewFieldElementFromString("13237663823305715949"),
|
||||
field.NewFieldElementFromString("15389314098328235145"),
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
fieldAPI.AssertIsEqual(plonkBetas[i], expectedPlonkBetas[i])
|
||||
fieldAPI.AssertIsEqual(plonkGammas[i], expectedPlonkGammas[i])
|
||||
}
|
||||
|
||||
challengerChip.ObserveCap(plonkZsPartialProductsCap[:])
|
||||
plonkAlphas := challengerChip.GetNChallenges(numChallenges)
|
||||
|
||||
expectedPlonkAlphas := [2]field.F{
|
||||
field.NewFieldElementFromString("14505919539124304197"),
|
||||
field.NewFieldElementFromString("1695455639263736117"),
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
fieldAPI.AssertIsEqual(plonkAlphas[i], expectedPlonkAlphas[i])
|
||||
}
|
||||
|
||||
challengerChip.ObserveCap(quotientPolysCap[:])
|
||||
plonkZeta := challengerChip.GetExtensionChallenge()
|
||||
|
||||
expectedPlonkZeta := field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("14887793628029982930"),
|
||||
field.NewFieldElementFromString("1136137158284059037"),
|
||||
}
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
fieldAPI.AssertIsEqual(plonkZeta[i], expectedPlonkZeta[i])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestChallengerWitness(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func(
|
||||
publicInputs [3]frontend.Variable,
|
||||
circuitDigest [4]frontend.Variable,
|
||||
wiresCap [16][4]frontend.Variable,
|
||||
plonkZsPartialProductsCap [16][4]frontend.Variable,
|
||||
quotientPolysCap [16][4]frontend.Variable,
|
||||
) {
|
||||
circuit := TestChallengerCircuit{
|
||||
PublicInputs: publicInputs,
|
||||
CircuitDigest: circuitDigest,
|
||||
WiresCap: wiresCap,
|
||||
PlonkZsPartialProductsCap: plonkZsPartialProductsCap,
|
||||
QuotientPolysCap: quotientPolysCap,
|
||||
}
|
||||
witness := TestChallengerCircuit{
|
||||
PublicInputs: publicInputs,
|
||||
CircuitDigest: circuitDigest,
|
||||
WiresCap: wiresCap,
|
||||
PlonkZsPartialProductsCap: plonkZsPartialProductsCap,
|
||||
QuotientPolysCap: quotientPolysCap,
|
||||
}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
publicInputsStr := []string{"0", "1", "3736710860384812976"}
|
||||
circuitDigestStr := []string{"7754113318730736048", "18436136620016916513", "18054530212389526288", "5893739326632906028"}
|
||||
wiresCapStr := [][]string{
|
||||
{"13884351014873073118", "5174249846243191862", "2208632528791973868", "1071582828677910652"},
|
||||
{"11475361245556894879", "14867351574926692044", "17013374066934071379", "1027671036932569748"},
|
||||
{"5604634992452399010", "3684464596850094189", "5565599237356852406", "4136295609943151014"},
|
||||
{"8463721840990025805", "5922588965472526198", "8096699027533803435", "2210089353004111478"},
|
||||
{"17531628199677307555", "11513452064460680964", "1482441508929181375", "5139566233781982440"},
|
||||
{"13271417993289093233", "17257193898955790413", "16883807866578566670", "7423179920948669117"},
|
||||
{"13462567520785358202", "15555103598281658890", "5859961276885232601", "4464568704709749394"},
|
||||
{"153012620162729043", "14072764618167122665", "3025694603779494447", "15948104906680148838"},
|
||||
{"18050235253694287284", "11467396424826912141", "11302553396166323353", "10976271719722841224"},
|
||||
{"15208241660644051470", "8520722208187871063", "10775022596056682771", "16048513824198271730"},
|
||||
{"6929477084755896240", "11382029470138215117", "13205948643259905511", "9421863267852221772"},
|
||||
{"15449187573546292268", "10216729601353604194", "9493934392442974211", "9848643714440191835"},
|
||||
{"2172475758127444753", "16681095938683502188", "9983383760611275566", "2603547977557388755"},
|
||||
{"17440301588003279095", "11799356585691460705", "1386003375936412946", "11059100806278290279"},
|
||||
{"10758265002546797581", "1374136260999724547", "7200401521491969338", "219493657547391496"},
|
||||
{"5995963332181008902", "4442996285152250372", "2005936434281221193", "6869325719052666642"},
|
||||
}
|
||||
plonkZsPartialProductsCapStr := [][]string{
|
||||
{"1209867952068639569", "4958824272276746373", "8278739766347565702", "1966940898171663504"},
|
||||
{"12599305286358028697", "8932511136775685440", "5376267558248004641", "6313904687311555884"},
|
||||
{"11190791343943249124", "4016631697385248176", "10356629842603047568", "10968099068686195317"},
|
||||
{"1963983823153667719", "6333891613271539690", "12318891063769180636", "10443318253972130654"},
|
||||
{"7799898099378084347", "2751829638242157622", "8351904444410446701", "5284662773710644867"},
|
||||
{"1588568181448440843", "10836321455257423751", "5543952383542989142", "12946954522116753258"},
|
||||
{"15710202198621978057", "13746115173212319217", "6103259182317700987", "17589471289629134988"},
|
||||
{"12877950969971815168", "4963889190939310439", "8868772654550990048", "11774978531783219015"},
|
||||
{"16832740767463005599", "15040340114131672027", "7469306538360789573", "3154855824233652432"},
|
||||
{"9383568437827143152", "1741060064145647394", "17668587021570420286", "5241789470902809114"},
|
||||
{"2087729156816989530", "8248918881937854542", "8673194597758568216", "10710697836634846115"},
|
||||
{"11253371860840267365", "16818881664594712299", "11933553751682199585", "1936353232880935379"},
|
||||
{"12163553231829171860", "17244267969759347515", "2003902333564157189", "6934019871173840760"},
|
||||
{"2082141893879862527", "18267460725569427782", "1129651898415533808", "14011240934155569890"},
|
||||
{"2526273401266876282", "6955959191669943337", "5926536548217021446", "17949337312612691782"},
|
||||
{"8858882459906353593", "5813258279939597857", "6320047506247573502", "15969724232572328561"},
|
||||
}
|
||||
quotientPolysCapStr := [][]string{
|
||||
{"9435614145733021495", "1742717829476348934", "11178548223985487003", "14531951007568589725"},
|
||||
{"11747844681527676730", "3089691012847802165", "5887135310661642077", "13943570416123664971"},
|
||||
{"11150071448774479229", "4486829025930200476", "9369448886033958276", "15757606153229850783"},
|
||||
{"14603194410536469617", "11776185929725558373", "3122936423686490326", "10128277488128872810"},
|
||||
{"4990578700975083076", "4997575606014863069", "14499603187047727337", "14028694557236527137"},
|
||||
{"2279147899956815983", "16034899207717647338", "14763350037932939672", "10075834812570828076"},
|
||||
{"1102006741007271956", "15242779529961262072", "6900547375301951311", "8631780317175902419"},
|
||||
{"6299112770394539219", "6297397453582105768", "14148031335065995704", "3794733067587629405"},
|
||||
{"7891039548997763820", "4260484126440019022", "6493066317319943586", "14775252570136307979"},
|
||||
{"10790514248728420789", "14444029601980227412", "17514190309172155536", "12973059492411164965"},
|
||||
{"8940755416742726696", "8469566845539112244", "7642612722784522739", "15276772682665052607"},
|
||||
{"18306931819862706026", "14374659904694625207", "8609543532143656606", "17350044275494282679"},
|
||||
{"9062024023737444614", "13780128979028684176", "6115495431779737008", "7170446003855284754"},
|
||||
{"6191400598853400595", "7806485717076924017", "3225145303141729264", "3644550749005104128"},
|
||||
{"15759718266801608721", "2406060174022670585", "15679263832775538866", "18066847192985300443"},
|
||||
{"9184823221361582966", "4767786405185004644", "9827047623720647370", "993615002460432327"},
|
||||
}
|
||||
|
||||
var publicInputs [3]frontend.Variable
|
||||
var circuitDigest [4]frontend.Variable
|
||||
var wiresCap [16][4]frontend.Variable
|
||||
var plonkZsPartialProductsCap [16][4]frontend.Variable
|
||||
var quotientPolysCap [16][4]frontend.Variable
|
||||
|
||||
copy(publicInputs[:], utils.StrArrayToFrontendVariableArray(publicInputsStr))
|
||||
copy(circuitDigest[:], utils.StrArrayToFrontendVariableArray(circuitDigestStr))
|
||||
for i := 0; i < len(wiresCapStr); i++ {
|
||||
copy(wiresCap[i][:], utils.StrArrayToFrontendVariableArray(wiresCapStr[i]))
|
||||
}
|
||||
for i := 0; i < len(plonkZsPartialProductsCapStr); i++ {
|
||||
copy(plonkZsPartialProductsCap[i][:], utils.StrArrayToFrontendVariableArray(plonkZsPartialProductsCapStr[i]))
|
||||
}
|
||||
for i := 0; i < len(quotientPolysCapStr); i++ {
|
||||
copy(quotientPolysCap[i][:], utils.StrArrayToFrontendVariableArray(quotientPolysCapStr[i]))
|
||||
}
|
||||
|
||||
testCase(publicInputs, circuitDigest, wiresCap, plonkZsPartialProductsCap, quotientPolysCap)
|
||||
}
|
||||
225
verifier/internal/plonk/plonk.go
Normal file
225
verifier/internal/plonk/plonk.go
Normal file
@@ -0,0 +1,225 @@
|
||||
package plonk
|
||||
|
||||
import (
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
)
|
||||
|
||||
type PlonkChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
|
||||
|
||||
commonData common.CommonCircuitData `gnark:"-"`
|
||||
|
||||
DEGREE field.F `gnark:"-"`
|
||||
DEGREE_BITS_F field.F `gnark:"-"`
|
||||
DEGREE_QE field.QuadraticExtension `gnark:"-"`
|
||||
|
||||
evaluateGatesChip *gates.EvaluateGatesChip
|
||||
}
|
||||
|
||||
func NewPlonkChip(api frontend.API, qeAPI *field.QuadraticExtensionAPI, commonData common.CommonCircuitData) *PlonkChip {
|
||||
// TODO: Should degreeBits be verified that it fits within the field and that degree is within uint64?
|
||||
|
||||
evaluateGatesChip := gates.NewEvaluateGatesChip(
|
||||
api,
|
||||
qeAPI,
|
||||
commonData.Gates,
|
||||
commonData.NumGateConstraints,
|
||||
commonData.SelectorsInfo,
|
||||
)
|
||||
|
||||
return &PlonkChip{
|
||||
api: api,
|
||||
qeAPI: qeAPI,
|
||||
|
||||
commonData: commonData,
|
||||
|
||||
DEGREE: field.NewFieldElement(1 << commonData.DegreeBits),
|
||||
DEGREE_BITS_F: field.NewFieldElement(commonData.DegreeBits),
|
||||
DEGREE_QE: field.QuadraticExtension{field.NewFieldElement(1 << commonData.DegreeBits), field.ZERO_F},
|
||||
|
||||
evaluateGatesChip: evaluateGatesChip,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PlonkChip) expPowerOf2Extension(x field.QuadraticExtension) field.QuadraticExtension {
|
||||
for i := uint64(0); i < p.commonData.DegreeBits; i++ {
|
||||
x = p.qeAPI.SquareExtension(x)
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
func (p *PlonkChip) evalL0(x field.QuadraticExtension, xPowN field.QuadraticExtension) field.QuadraticExtension {
|
||||
// L_0(x) = (x^n - 1) / (n * (x - 1))
|
||||
evalZeroPoly := p.qeAPI.SubExtension(
|
||||
xPowN,
|
||||
p.qeAPI.ONE_QE,
|
||||
)
|
||||
denominator := p.qeAPI.SubExtension(
|
||||
p.qeAPI.ScalarMulExtension(x, p.DEGREE),
|
||||
p.DEGREE_QE,
|
||||
)
|
||||
return p.qeAPI.DivExtension(
|
||||
evalZeroPoly,
|
||||
denominator,
|
||||
)
|
||||
}
|
||||
|
||||
func (p *PlonkChip) checkPartialProducts(
|
||||
numerators []field.QuadraticExtension,
|
||||
denominators []field.QuadraticExtension,
|
||||
challengeNum uint64,
|
||||
openings common.OpeningSet,
|
||||
) []field.QuadraticExtension {
|
||||
numPartProds := p.commonData.NumPartialProducts
|
||||
quotDegreeFactor := p.commonData.QuotientDegreeFactor
|
||||
|
||||
productAccs := make([]field.QuadraticExtension, 0, numPartProds+2)
|
||||
productAccs = append(productAccs, openings.PlonkZs[challengeNum])
|
||||
productAccs = append(productAccs, openings.PartialProducts[challengeNum*numPartProds:(challengeNum+1)*numPartProds]...)
|
||||
productAccs = append(productAccs, openings.PlonkZsNext[challengeNum])
|
||||
|
||||
partialProductChecks := make([]field.QuadraticExtension, 0, numPartProds)
|
||||
|
||||
for i := uint64(0); i <= numPartProds; i += 1 {
|
||||
ppStartIdx := i * quotDegreeFactor
|
||||
numeProduct := numerators[ppStartIdx]
|
||||
denoProduct := denominators[ppStartIdx]
|
||||
for j := uint64(1); j < quotDegreeFactor; j++ {
|
||||
numeProduct = p.qeAPI.MulExtension(numeProduct, numerators[ppStartIdx+j])
|
||||
denoProduct = p.qeAPI.MulExtension(denoProduct, denominators[ppStartIdx+j])
|
||||
}
|
||||
|
||||
partialProductCheck := p.qeAPI.SubExtension(
|
||||
p.qeAPI.MulExtension(productAccs[i], numeProduct),
|
||||
p.qeAPI.MulExtension(productAccs[i+1], denoProduct),
|
||||
)
|
||||
|
||||
partialProductChecks = append(partialProductChecks, partialProductCheck)
|
||||
}
|
||||
return partialProductChecks
|
||||
}
|
||||
|
||||
func (p *PlonkChip) evalVanishingPoly(vars gates.EvaluationVars, proofChallenges common.ProofChallenges, openings common.OpeningSet, zetaPowN field.QuadraticExtension) []field.QuadraticExtension {
|
||||
constraintTerms := p.evaluateGatesChip.EvaluateGateConstraints(vars)
|
||||
|
||||
// Calculate the k[i] * x
|
||||
sIDs := make([]field.QuadraticExtension, p.commonData.Config.NumRoutedWires)
|
||||
|
||||
for i := uint64(0); i < p.commonData.Config.NumRoutedWires; i++ {
|
||||
sIDs[i] = p.qeAPI.ScalarMulExtension(proofChallenges.PlonkZeta, p.commonData.KIs[i])
|
||||
}
|
||||
|
||||
// Calculate L_0(zeta)
|
||||
l0Zeta := p.evalL0(proofChallenges.PlonkZeta, zetaPowN)
|
||||
|
||||
vanishingZ1Terms := make([]field.QuadraticExtension, 0, p.commonData.Config.NumChallenges)
|
||||
vanishingPartialProductsTerms := make([]field.QuadraticExtension, 0, p.commonData.Config.NumChallenges*p.commonData.NumPartialProducts)
|
||||
for i := uint64(0); i < p.commonData.Config.NumChallenges; i++ {
|
||||
// L_0(zeta) (Z(zeta) - 1) = 0
|
||||
z1_term := p.qeAPI.MulExtension(
|
||||
l0Zeta,
|
||||
p.qeAPI.SubExtension(openings.PlonkZs[i], p.qeAPI.ONE_QE))
|
||||
vanishingZ1Terms = append(vanishingZ1Terms, z1_term)
|
||||
|
||||
numeratorValues := make([]field.QuadraticExtension, 0, p.commonData.Config.NumRoutedWires)
|
||||
denominatorValues := make([]field.QuadraticExtension, 0, p.commonData.Config.NumRoutedWires)
|
||||
for j := uint64(0); j < p.commonData.Config.NumRoutedWires; j++ {
|
||||
// The numerator is `beta * s_id + wire_value + gamma`, and the denominator is
|
||||
// `beta * s_sigma + wire_value + gamma`.
|
||||
wireValuePlusGamma := p.qeAPI.AddExtension(
|
||||
openings.Wires[j],
|
||||
p.qeAPI.FieldToQE(proofChallenges.PlonkGammas[i]),
|
||||
)
|
||||
|
||||
numerator := p.qeAPI.AddExtension(
|
||||
p.qeAPI.MulExtension(
|
||||
p.qeAPI.FieldToQE(proofChallenges.PlonkBetas[i]),
|
||||
sIDs[j],
|
||||
),
|
||||
wireValuePlusGamma,
|
||||
)
|
||||
|
||||
denominator := p.qeAPI.AddExtension(
|
||||
p.qeAPI.MulExtension(
|
||||
p.qeAPI.FieldToQE(proofChallenges.PlonkBetas[i]),
|
||||
openings.PlonkSigmas[j],
|
||||
),
|
||||
wireValuePlusGamma,
|
||||
)
|
||||
|
||||
numeratorValues = append(numeratorValues, numerator)
|
||||
denominatorValues = append(denominatorValues, denominator)
|
||||
}
|
||||
|
||||
vanishingPartialProductsTerms = append(
|
||||
vanishingPartialProductsTerms,
|
||||
p.checkPartialProducts(numeratorValues, denominatorValues, i, openings)...,
|
||||
)
|
||||
}
|
||||
|
||||
vanishingTerms := append(vanishingZ1Terms, vanishingPartialProductsTerms...)
|
||||
vanishingTerms = append(vanishingTerms, constraintTerms...)
|
||||
|
||||
reducedValues := make([]field.QuadraticExtension, p.commonData.Config.NumChallenges)
|
||||
for i := uint64(0); i < p.commonData.Config.NumChallenges; i++ {
|
||||
reducedValues[i] = p.qeAPI.ZERO_QE
|
||||
}
|
||||
|
||||
// reverse iterate the vanishingPartialProductsTerms array
|
||||
for i := len(vanishingTerms) - 1; i >= 0; i-- {
|
||||
for j := uint64(0); j < p.commonData.Config.NumChallenges; j++ {
|
||||
reducedValues[j] = p.qeAPI.AddExtension(
|
||||
vanishingTerms[i],
|
||||
p.qeAPI.ScalarMulExtension(
|
||||
reducedValues[j],
|
||||
proofChallenges.PlonkAlphas[j],
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return reducedValues
|
||||
}
|
||||
|
||||
func (p *PlonkChip) Verify(proofChallenges common.ProofChallenges, openings common.OpeningSet, publicInputsHash poseidon.Hash) {
|
||||
// Calculate zeta^n
|
||||
zetaPowN := p.expPowerOf2Extension(proofChallenges.PlonkZeta)
|
||||
|
||||
localConstants := openings.Constants
|
||||
localWires := openings.Wires
|
||||
vars := gates.NewEvaluationVars(
|
||||
localConstants,
|
||||
localWires,
|
||||
publicInputsHash,
|
||||
)
|
||||
|
||||
vanishingPolysZeta := p.evalVanishingPoly(*vars, proofChallenges, openings, zetaPowN)
|
||||
|
||||
// Calculate Z(H)
|
||||
zHZeta := p.qeAPI.SubExtension(zetaPowN, p.qeAPI.ONE_QE)
|
||||
|
||||
// `quotient_polys_zeta` holds `num_challenges * quotient_degree_factor` evaluations.
|
||||
// Each chunk of `quotient_degree_factor` holds the evaluations of `t_0(zeta),...,t_{quotient_degree_factor-1}(zeta)`
|
||||
// where the "real" quotient polynomial is `t(X) = t_0(X) + t_1(X)*X^n + t_2(X)*X^{2n} + ...`.
|
||||
// So to reconstruct `t(zeta)` we can compute `reduce_with_powers(chunk, zeta^n)` for each
|
||||
// `quotient_degree_factor`-sized chunk of the original evaluations.
|
||||
for i := 0; i < len(vanishingPolysZeta); i++ {
|
||||
quotientPolysStartIdx := i * int(p.commonData.QuotientDegreeFactor)
|
||||
quotientPolysEndIdx := quotientPolysStartIdx + int(p.commonData.QuotientDegreeFactor)
|
||||
prod := p.qeAPI.MulExtension(
|
||||
zHZeta,
|
||||
p.qeAPI.ReduceWithPowers(
|
||||
openings.QuotientPolys[quotientPolysStartIdx:quotientPolysEndIdx],
|
||||
zetaPowN,
|
||||
),
|
||||
)
|
||||
|
||||
p.qeAPI.AssertIsEqual(vanishingPolysZeta[i], prod)
|
||||
}
|
||||
}
|
||||
73
verifier/internal/plonk/plonk_test.go
Normal file
73
verifier/internal/plonk/plonk_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package plonk_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestPlonkCircuit struct {
|
||||
proofWithPIsFilename string `gnark:"-"`
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
verifierOnlyCircuitDataFilename string `gnark:"-"`
|
||||
}
|
||||
|
||||
func (circuit *TestPlonkCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs(circuit.proofWithPIsFilename)
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename)
|
||||
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuit.verifierOnlyCircuitDataFilename)
|
||||
|
||||
verifierChip := verifier.NewVerifierChip(api, commonCircuitData)
|
||||
publicInputsHash := verifierChip.GetPublicInputsHash(proofWithPis.PublicInputs)
|
||||
proofChallenges := verifierChip.GetChallenges(proofWithPis, publicInputsHash, commonCircuitData, verifierOnlyCircuitData)
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
|
||||
plonkChip := plonk.NewPlonkChip(
|
||||
api,
|
||||
qeAPI,
|
||||
commonCircuitData,
|
||||
)
|
||||
|
||||
plonkChip.Verify(proofChallenges, proofWithPis.Proof.Openings, publicInputsHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPlonkFibonacci(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestPlonkCircuit{
|
||||
proofWithPIsFilename: "./data/fibonacci/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/fibonacci/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/fibonacci/verifier_only_circuit_data.json",
|
||||
}
|
||||
witness := TestPlonkCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
|
||||
func TestPlonkDummy(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestPlonkCircuit{
|
||||
proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json",
|
||||
}
|
||||
witness := TestPlonkCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
13
verifier/internal/plonk/types.go
Normal file
13
verifier/internal/plonk/types.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package plonk
|
||||
|
||||
import "github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
|
||||
type OpeningSet struct {
|
||||
Constants []field.QuadraticExtension
|
||||
PlonkSigmas []field.QuadraticExtension
|
||||
Wires []field.QuadraticExtension
|
||||
PlonkZs []field.QuadraticExtension
|
||||
PlonkZsNext []field.QuadraticExtension
|
||||
PartialProducts []field.QuadraticExtension
|
||||
QuotientPolys []field.QuadraticExtension
|
||||
}
|
||||
28
verifier/types.go
Normal file
28
verifier/types.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk"
|
||||
)
|
||||
|
||||
type Proof struct {
|
||||
WiresCap common.MerkleCap
|
||||
PlonkZsPartialProductsCap common.MerkleCap
|
||||
QuotientPolysCap common.MerkleCap
|
||||
Openings plonk.OpeningSet
|
||||
OpeningProof common.FriProof
|
||||
}
|
||||
|
||||
type ProofWithPublicInputs struct {
|
||||
Proof Proof
|
||||
PublicInputs []field.F
|
||||
}
|
||||
|
||||
type ProofChallenges struct {
|
||||
PlonkBetas []field.F
|
||||
PlonkGammas []field.F
|
||||
PlonkAlphas []field.F
|
||||
PlonkZeta field.QuadraticExtension
|
||||
FriChallenges common.FriChallenges
|
||||
}
|
||||
443
verifier/utils/deserialize.go
Normal file
443
verifier/utils/deserialize.go
Normal file
@@ -0,0 +1,443 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/utils"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/gates"
|
||||
)
|
||||
|
||||
type ProofWithPublicInputsRaw struct {
|
||||
Proof struct {
|
||||
WiresCap []struct {
|
||||
Elements []uint64 `json:"elements"`
|
||||
} `json:"wires_cap"`
|
||||
PlonkZsPartialProductsCap []struct {
|
||||
Elements []uint64 `json:"elements"`
|
||||
} `json:"plonk_zs_partial_products_cap"`
|
||||
QuotientPolysCap []struct {
|
||||
Elements []uint64 `json:"elements"`
|
||||
} `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 []MerkleCapsRaw `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 MerkleProofRaw `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 MerkleCapsRaw struct {
|
||||
hashes [][]uint64
|
||||
}
|
||||
|
||||
func (m *MerkleCapsRaw) UnmarshalJSON(data []byte) error {
|
||||
var merkleCaps []map[string][]uint64
|
||||
if err := json.Unmarshal(data, &merkleCaps); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
m.hashes = make([][]uint64, len(merkleCaps))
|
||||
for i := 0; i < len(merkleCaps); i++ {
|
||||
m.hashes[i] = merkleCaps[i]["elements"]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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 [][]uint64
|
||||
}
|
||||
|
||||
func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error {
|
||||
type SiblingObject struct {
|
||||
Siblings []map[string][]uint64 // "siblings"
|
||||
}
|
||||
|
||||
var siblings SiblingObject
|
||||
if err := json.Unmarshal(data, &siblings); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
m.hash = make([][]uint64, len(siblings.Siblings))
|
||||
for siblingIdx, sibling := range siblings.Siblings {
|
||||
m.hash[siblingIdx] = sibling["elements"]
|
||||
}
|
||||
|
||||
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 []struct {
|
||||
Elements []uint64 `json:"elements"`
|
||||
} `json:"constants_sigmas_cap"`
|
||||
CircuitDigest struct {
|
||||
Elements []uint64 `json:"elements"`
|
||||
} `json:"circuit_digest"`
|
||||
}
|
||||
|
||||
func DeserializeMerkleCap(merkleCapRaw []struct{ Elements []uint64 }) common.MerkleCap {
|
||||
n := len(merkleCapRaw)
|
||||
merkleCap := make([]poseidon.Hash, n)
|
||||
for i := 0; i < n; i++ {
|
||||
copy(merkleCap[i][:], utils.Uint64ArrayToFArray(merkleCapRaw[i].Elements))
|
||||
}
|
||||
return merkleCap
|
||||
}
|
||||
|
||||
func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) common.MerkleProof {
|
||||
n := len(merkleProofRaw.Siblings)
|
||||
var mp common.MerkleProof
|
||||
mp.Siblings = make([]poseidon.Hash, n)
|
||||
for i := 0; i < n; i++ {
|
||||
element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 })
|
||||
copy(mp.Siblings[i][:], utils.Uint64ArrayToFArray(element.Elements))
|
||||
}
|
||||
return mp
|
||||
}
|
||||
|
||||
func DeserializeOpeningSet(openingSetRaw struct {
|
||||
Constants [][]uint64
|
||||
PlonkSigmas [][]uint64
|
||||
Wires [][]uint64
|
||||
PlonkZs [][]uint64
|
||||
PlonkZsNext [][]uint64
|
||||
PartialProducts [][]uint64
|
||||
QuotientPolys [][]uint64
|
||||
}) common.OpeningSet {
|
||||
return common.OpeningSet{
|
||||
Constants: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants),
|
||||
PlonkSigmas: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas),
|
||||
Wires: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires),
|
||||
PlonkZs: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs),
|
||||
PlonkZsNext: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext),
|
||||
PartialProducts: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts),
|
||||
QuotientPolys: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys),
|
||||
}
|
||||
}
|
||||
|
||||
func DeserializeFriProof(openingProofRaw struct {
|
||||
CommitPhaseMerkleCaps []MerkleCapsRaw
|
||||
QueryRoundProofs []struct {
|
||||
InitialTreesProof struct {
|
||||
EvalsProofs []EvalProofRaw
|
||||
}
|
||||
Steps []struct {
|
||||
Evals [][]uint64
|
||||
MerkleProof MerkleProofRaw
|
||||
}
|
||||
}
|
||||
FinalPoly struct {
|
||||
Coeffs [][]uint64
|
||||
}
|
||||
PowWitness uint64
|
||||
}) common.FriProof {
|
||||
var openingProof common.FriProof
|
||||
openingProof.PowWitness = field.NewFieldElement(openingProofRaw.PowWitness)
|
||||
openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
|
||||
|
||||
openingProof.CommitPhaseMerkleCaps = make([]common.MerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps))
|
||||
for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ {
|
||||
openingProof.CommitPhaseMerkleCaps[i] = poseidon.Uint64ArrayToHashArray(openingProofRaw.CommitPhaseMerkleCaps[i].hashes)
|
||||
}
|
||||
|
||||
numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs)
|
||||
openingProof.QueryRoundProofs = make([]common.FriQueryRound, numQueryRoundProofs)
|
||||
|
||||
for i := 0; i < numQueryRoundProofs; i++ {
|
||||
numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs)
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]common.EvalProof, numEvalProofs)
|
||||
for j := 0; j < numEvalProofs; j++ {
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = utils.Uint64ArrayToFArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].leafElements)
|
||||
openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = poseidon.Uint64ArrayToHashArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].merkleProof.hash)
|
||||
}
|
||||
|
||||
numSteps := len(openingProofRaw.QueryRoundProofs[i].Steps)
|
||||
openingProof.QueryRoundProofs[i].Steps = make([]common.FriQueryStep, numSteps)
|
||||
for j := 0; j < numSteps; j++ {
|
||||
openingProof.QueryRoundProofs[i].Steps[j].Evals = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.QueryRoundProofs[i].Steps[j].Evals)
|
||||
openingProof.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings = poseidon.Uint64ArrayToHashArray(openingProofRaw.QueryRoundProofs[i].Steps[j].MerkleProof.hash)
|
||||
}
|
||||
}
|
||||
|
||||
return openingProof
|
||||
}
|
||||
|
||||
func DeserializeProofWithPublicInputs(path string) common.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 common.ProofWithPublicInputs
|
||||
proofWithPis.Proof.WiresCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.WiresCap))
|
||||
proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.PlonkZsPartialProductsCap))
|
||||
proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(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 []MerkleCapsRaw
|
||||
QueryRoundProofs []struct {
|
||||
InitialTreesProof struct {
|
||||
EvalsProofs []EvalProofRaw
|
||||
}
|
||||
Steps []struct {
|
||||
Evals [][]uint64
|
||||
MerkleProof MerkleProofRaw
|
||||
}
|
||||
}
|
||||
FinalPoly struct{ Coeffs [][]uint64 }
|
||||
PowWitness uint64
|
||||
}(raw.Proof.OpeningProof))
|
||||
proofWithPis.PublicInputs = utils.Uint64ArrayToFArray(raw.PublicInputs)
|
||||
|
||||
return proofWithPis
|
||||
}
|
||||
|
||||
func DeserializeProofChallenges(path string) common.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 common.ProofChallenges
|
||||
proofChallenges.PlonkBetas = utils.Uint64ArrayToFArray(raw.PlonkBetas)
|
||||
proofChallenges.PlonkGammas = utils.Uint64ArrayToFArray(raw.PlonkGammas)
|
||||
proofChallenges.PlonkAlphas = utils.Uint64ArrayToFArray(raw.PlonkAlphas)
|
||||
proofChallenges.PlonkZeta = utils.Uint64ArrayToQuadraticExtension(raw.PlonkZeta)
|
||||
proofChallenges.FriChallenges.FriAlpha = utils.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha)
|
||||
proofChallenges.FriChallenges.FriBetas = utils.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas)
|
||||
proofChallenges.FriChallenges.FriPowResponse = field.NewFieldElement(raw.FriChallenges.FriPowResponse)
|
||||
proofChallenges.FriChallenges.FriQueryIndices = utils.Uint64ArrayToFArray(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) common.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 common.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 = utils.Uint64ArrayToFArray(raw.KIs)
|
||||
commonCircuitData.NumPartialProducts = raw.NumPartialProducts
|
||||
|
||||
return commonCircuitData
|
||||
}
|
||||
|
||||
func DeserializeVerifierOnlyCircuitData(path string) common.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 common.VerifierOnlyCircuitData
|
||||
verifierOnlyCircuitData.ConstantSigmasCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.ConstantsSigmasCap))
|
||||
copy(verifierOnlyCircuitData.CircuitDigest[:], utils.Uint64ArrayToFArray(raw.CircuitDigest.Elements))
|
||||
|
||||
return verifierOnlyCircuitData
|
||||
}
|
||||
24
verifier/utils/deserialize_test.go
Normal file
24
verifier/utils/deserialize_test.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeserializeProofWithPublicInputs(t *testing.T) {
|
||||
proofWithPis := DeserializeProofWithPublicInputs("./data/fibonacci/proof_with_public_inputs.json")
|
||||
fmt.Printf("%+v\n", proofWithPis)
|
||||
panic("look at stdout")
|
||||
}
|
||||
|
||||
func TestDeserializeCommonCircuitData(t *testing.T) {
|
||||
commonCircuitData := DeserializeCommonCircuitData("./data/fibonacci/common_circuit_data.json")
|
||||
fmt.Printf("%+v\n", commonCircuitData)
|
||||
panic("look at stdout")
|
||||
}
|
||||
|
||||
func TestDeserializeVerifierOnlyCircuitData(t *testing.T) {
|
||||
verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./data/fibonacci/verifier_only_circuit_data.json")
|
||||
fmt.Printf("%+v\n", verifierOnlyCircuitData)
|
||||
panic("look at stdout")
|
||||
}
|
||||
127
verifier/verifier.go
Normal file
127
verifier/verifier.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/plonk"
|
||||
)
|
||||
|
||||
type VerifierChip struct {
|
||||
api frontend.API `gnark:"-"`
|
||||
fieldAPI frontend.API `gnark:"-"`
|
||||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
|
||||
poseidonChip *poseidon.PoseidonChip
|
||||
plonkChip *plonk.PlonkChip
|
||||
friChip *fri.FriChip
|
||||
}
|
||||
|
||||
func NewVerifierChip(api frontend.API, commonCircuitData common.CommonCircuitData) *VerifierChip {
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits)
|
||||
hashAPI := poseidon.NewHashAPI(fieldAPI)
|
||||
poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
|
||||
|
||||
friChip := fri.NewFriChip(api, fieldAPI, qeAPI, hashAPI, poseidonChip, &commonCircuitData.FriParams)
|
||||
plonkChip := plonk.NewPlonkChip(api, qeAPI, commonCircuitData)
|
||||
|
||||
return &VerifierChip{
|
||||
api: api,
|
||||
fieldAPI: fieldAPI,
|
||||
qeAPI: qeAPI,
|
||||
poseidonChip: poseidonChip,
|
||||
plonkChip: plonkChip,
|
||||
friChip: friChip,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *VerifierChip) GetPublicInputsHash(publicInputs []field.F) poseidon.Hash {
|
||||
return c.poseidonChip.HashNoPad(publicInputs)
|
||||
}
|
||||
|
||||
func (c *VerifierChip) GetChallenges(
|
||||
proofWithPis common.ProofWithPublicInputs,
|
||||
publicInputsHash poseidon.Hash,
|
||||
commonData common.CommonCircuitData,
|
||||
verifierData common.VerifierOnlyCircuitData,
|
||||
) common.ProofChallenges {
|
||||
config := commonData.Config
|
||||
numChallenges := config.NumChallenges
|
||||
challenger := plonk.NewChallengerChip(c.api, c.fieldAPI, c.poseidonChip)
|
||||
|
||||
var circuitDigest = verifierData.CircuitDigest
|
||||
|
||||
challenger.ObserveHash(circuitDigest)
|
||||
challenger.ObserveHash(publicInputsHash)
|
||||
challenger.ObserveCap(proofWithPis.Proof.WiresCap)
|
||||
plonkBetas := challenger.GetNChallenges(numChallenges)
|
||||
plonkGammas := challenger.GetNChallenges(numChallenges)
|
||||
|
||||
challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap)
|
||||
plonkAlphas := challenger.GetNChallenges(numChallenges)
|
||||
|
||||
challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap)
|
||||
plonkZeta := challenger.GetExtensionChallenge()
|
||||
|
||||
challenger.ObserveOpenings(fri.ToFriOpenings(proofWithPis.Proof.Openings))
|
||||
|
||||
return common.ProofChallenges{
|
||||
PlonkBetas: plonkBetas,
|
||||
PlonkGammas: plonkGammas,
|
||||
PlonkAlphas: plonkAlphas,
|
||||
PlonkZeta: plonkZeta,
|
||||
FriChallenges: challenger.GetFriChallenges(
|
||||
proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||
proofWithPis.Proof.OpeningProof.PowWitness,
|
||||
commonData.DegreeBits,
|
||||
config.FriConfig,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *VerifierChip) Verify(proofWithPis common.ProofWithPublicInputs, verifierData common.VerifierOnlyCircuitData, commonData common.CommonCircuitData) {
|
||||
// TODO: Verify shape of the proof?
|
||||
|
||||
publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs)
|
||||
proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData, verifierData)
|
||||
|
||||
c.plonkChip.Verify(proofChallenges, proofWithPis.Proof.Openings, publicInputsHash)
|
||||
|
||||
initialMerkleCaps := []common.MerkleCap{
|
||||
verifierData.ConstantSigmasCap,
|
||||
proofWithPis.Proof.WiresCap,
|
||||
proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
proofWithPis.Proof.QuotientPolysCap,
|
||||
}
|
||||
|
||||
// Seems like there is a bug in the emulated field code.
|
||||
// Add ZERO to all of the fri challenges values to reduce them.
|
||||
proofChallenges.PlonkZeta[0] = c.fieldAPI.Add(proofChallenges.PlonkZeta[0], field.ZERO_F).(field.F)
|
||||
proofChallenges.PlonkZeta[1] = c.fieldAPI.Add(proofChallenges.PlonkZeta[1], field.ZERO_F).(field.F)
|
||||
|
||||
proofChallenges.FriChallenges.FriAlpha[0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[0], field.ZERO_F).(field.F)
|
||||
proofChallenges.FriChallenges.FriAlpha[1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriAlpha[1], field.ZERO_F).(field.F)
|
||||
|
||||
for i := 0; i < len(proofChallenges.FriChallenges.FriBetas); i++ {
|
||||
proofChallenges.FriChallenges.FriBetas[i][0] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][0], field.ZERO_F).(field.F)
|
||||
proofChallenges.FriChallenges.FriBetas[i][1] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriBetas[i][1], field.ZERO_F).(field.F)
|
||||
}
|
||||
|
||||
proofChallenges.FriChallenges.FriPowResponse = c.fieldAPI.Add(proofChallenges.FriChallenges.FriPowResponse, field.ZERO_F).(field.F)
|
||||
|
||||
for i := 0; i < len(proofChallenges.FriChallenges.FriQueryIndices); i++ {
|
||||
proofChallenges.FriChallenges.FriQueryIndices[i] = c.fieldAPI.Add(proofChallenges.FriChallenges.FriQueryIndices[i], field.ZERO_F).(field.F)
|
||||
}
|
||||
|
||||
c.friChip.VerifyFriProof(
|
||||
fri.GetFriInstance(&commonData, c.qeAPI, proofChallenges.PlonkZeta, commonData.DegreeBits),
|
||||
fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
&proofChallenges.FriChallenges,
|
||||
initialMerkleCaps,
|
||||
&proofWithPis.Proof.OpeningProof,
|
||||
)
|
||||
}
|
||||
320
verifier/verifier_test.go
Normal file
320
verifier/verifier_test.go
Normal file
@@ -0,0 +1,320 @@
|
||||
package verifier_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestVerifierChallengesCircuit struct {
|
||||
fieldAPI frontend.API `gnark:"-"`
|
||||
qeAPI *field.QuadraticExtensionAPI `gnark:"-"`
|
||||
hashAPI *poseidon.HashAPI `gnark:"-"`
|
||||
|
||||
proofWithPIsFilename string `gnark:"-"`
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
verifierOnlyCircuitDataFilename string `gnark:"-"`
|
||||
|
||||
numChallenges uint64 `gnark:"-"`
|
||||
numFriQueries uint64 `gnark:"-"`
|
||||
|
||||
t *testing.T `gnark:"-"`
|
||||
|
||||
expectedPublicInputsHash poseidon.Hash
|
||||
expectedPlonkBetas []field.F // slice length == num challenges
|
||||
expectedPlonkGammas []field.F // slice length == num challenges
|
||||
expectedPlonkAlphas []field.F // slice length == num challenges
|
||||
expectedPlonkZeta field.QuadraticExtension
|
||||
expectedFriAlpha field.QuadraticExtension
|
||||
expectedFriBetas []field.QuadraticExtension // slice length == num fri rounds
|
||||
expectedFriQueryIndices []field.F // slice length == num fri queries
|
||||
|
||||
verifierChip *verifier.VerifierChip
|
||||
}
|
||||
|
||||
func (c *TestVerifierChallengesCircuit) GetChallengesSanityCheck(
|
||||
proofWithPis common.ProofWithPublicInputs,
|
||||
verifierData common.VerifierOnlyCircuitData,
|
||||
commonData common.CommonCircuitData,
|
||||
) {
|
||||
publicInputsHash := c.verifierChip.GetPublicInputsHash(proofWithPis.PublicInputs)
|
||||
proofChallenges := c.verifierChip.GetChallenges(proofWithPis, publicInputsHash, commonData, verifierData)
|
||||
|
||||
c.hashAPI.AssertIsEqualHash(publicInputsHash, c.expectedPublicInputsHash)
|
||||
|
||||
if len(proofChallenges.PlonkBetas) != int(c.numChallenges) {
|
||||
c.t.Errorf("len(PlonkBetas) should equal numChallenges")
|
||||
}
|
||||
for i := 0; i < int(c.numChallenges); i++ {
|
||||
c.fieldAPI.AssertIsEqual(proofChallenges.PlonkBetas[i], c.expectedPlonkBetas[i])
|
||||
}
|
||||
|
||||
if len(proofChallenges.PlonkGammas) != int(c.numChallenges) {
|
||||
c.t.Errorf("len(PlonkGammas) should equal numChallenges")
|
||||
}
|
||||
for i := 0; i < int(c.numChallenges); i++ {
|
||||
c.fieldAPI.AssertIsEqual(proofChallenges.PlonkGammas[i], c.expectedPlonkGammas[i])
|
||||
}
|
||||
|
||||
if len(proofChallenges.PlonkAlphas) != int(c.numChallenges) {
|
||||
c.t.Errorf("len(PlonkAlphas) should equal numChallenges")
|
||||
}
|
||||
for i := 0; i < int(c.numChallenges); i++ {
|
||||
c.fieldAPI.AssertIsEqual(proofChallenges.PlonkAlphas[i], c.expectedPlonkAlphas[i])
|
||||
}
|
||||
|
||||
c.qeAPI.AssertIsEqual(proofChallenges.PlonkZeta, c.expectedPlonkZeta)
|
||||
|
||||
c.qeAPI.AssertIsEqual(proofChallenges.FriChallenges.FriAlpha, c.expectedFriAlpha)
|
||||
|
||||
if len(proofChallenges.FriChallenges.FriBetas) != len(commonData.FriParams.ReductionArityBits) {
|
||||
c.t.Errorf("len(PlonkAlphas) should equal num fri rounds")
|
||||
}
|
||||
for i := 0; i < len(commonData.FriParams.ReductionArityBits); i++ {
|
||||
c.qeAPI.AssertIsEqual(proofChallenges.FriChallenges.FriBetas[i], c.expectedFriBetas[i])
|
||||
}
|
||||
|
||||
// This test is commented out because pow_witness is randomized between runs of the prover.
|
||||
// expectedPowResponse := field.NewFieldElementFromString("92909863298412")
|
||||
// c.field.AssertIsEqual(proofChallenges.FriChallenges.FriPowResponse, expectedPowResponse)
|
||||
|
||||
if len(proofChallenges.FriChallenges.FriQueryIndices) != int(c.numFriQueries) {
|
||||
c.t.Errorf("len(expectedFriQueryIndices) should equal num fri queries")
|
||||
}
|
||||
|
||||
for i := 0; i < int(c.numFriQueries); i++ {
|
||||
c.fieldAPI.AssertIsEqual(c.expectedFriQueryIndices[i], proofChallenges.FriChallenges.FriQueryIndices[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *TestVerifierChallengesCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs(c.proofWithPIsFilename)
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(c.commonCircuitDataFilename)
|
||||
verfierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename)
|
||||
|
||||
c.numChallenges = commonCircuitData.Config.NumChallenges
|
||||
c.numFriQueries = commonCircuitData.FriParams.Config.NumQueryRounds
|
||||
|
||||
c.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
|
||||
|
||||
c.GetChallengesSanityCheck(proofWithPis, verfierOnlyCircuitData, commonCircuitData)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFibonacciVerifierWitness(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestVerifierChallengesCircuit{
|
||||
proofWithPIsFilename: "./data/fibonacci/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/fibonacci/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/fibonacci/verifier_only_circuit_data.json",
|
||||
t: t,
|
||||
|
||||
expectedPublicInputsHash: poseidon.Hash{
|
||||
field.NewFieldElementFromString("8416658900775745054"),
|
||||
field.NewFieldElementFromString("12574228347150446423"),
|
||||
field.NewFieldElementFromString("9629056739760131473"),
|
||||
field.NewFieldElementFromString("3119289788404190010"),
|
||||
},
|
||||
|
||||
expectedPlonkBetas: []field.F{
|
||||
field.NewFieldElementFromString("4678728155650926271"),
|
||||
field.NewFieldElementFromString("13611962404289024887"),
|
||||
},
|
||||
|
||||
expectedPlonkGammas: []field.F{
|
||||
field.NewFieldElementFromString("13237663823305715949"),
|
||||
field.NewFieldElementFromString("15389314098328235145"),
|
||||
},
|
||||
|
||||
expectedPlonkAlphas: []field.F{
|
||||
field.NewFieldElementFromString("14505919539124304197"),
|
||||
field.NewFieldElementFromString("1695455639263736117"),
|
||||
},
|
||||
|
||||
expectedPlonkZeta: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("14887793628029982930"),
|
||||
field.NewFieldElementFromString("1136137158284059037"),
|
||||
},
|
||||
|
||||
expectedFriAlpha: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("14641715242626918707"),
|
||||
field.NewFieldElementFromString("10574243340537902930"),
|
||||
},
|
||||
|
||||
expectedFriBetas: []field.QuadraticExtension{},
|
||||
|
||||
expectedFriQueryIndices: []field.F{
|
||||
field.NewFieldElement(6790812084677375942),
|
||||
field.NewFieldElement(12394212020331474798),
|
||||
field.NewFieldElement(16457600747000998582),
|
||||
field.NewFieldElement(1543271328932331916),
|
||||
field.NewFieldElement(12115726870906958644),
|
||||
field.NewFieldElement(6775897107605342797),
|
||||
field.NewFieldElement(15989401564746021030),
|
||||
field.NewFieldElement(10691676456016926845),
|
||||
field.NewFieldElement(1632499470630032007),
|
||||
field.NewFieldElement(1317292355445098328),
|
||||
field.NewFieldElement(18391440812534384252),
|
||||
field.NewFieldElement(17321705613231354333),
|
||||
field.NewFieldElement(6176487551308859603),
|
||||
field.NewFieldElement(7119835651572002873),
|
||||
field.NewFieldElement(3903019169623116693),
|
||||
field.NewFieldElement(4886491111111487546),
|
||||
field.NewFieldElement(4087641893164620518),
|
||||
field.NewFieldElement(13801643080324181364),
|
||||
field.NewFieldElement(16993775312274189321),
|
||||
field.NewFieldElement(9268202926222765679),
|
||||
field.NewFieldElement(10683001302406181735),
|
||||
field.NewFieldElement(13359465725531647963),
|
||||
field.NewFieldElement(4523327590105620849),
|
||||
field.NewFieldElement(4883588003760409588),
|
||||
field.NewFieldElement(187699146998097671),
|
||||
field.NewFieldElement(14489263557623716717),
|
||||
field.NewFieldElement(11748359318238148146),
|
||||
field.NewFieldElement(13636347200053048758),
|
||||
},
|
||||
}
|
||||
witness := TestVerifierChallengesCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
|
||||
func TestDummyVerifierWitness(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestVerifierChallengesCircuit{
|
||||
proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json",
|
||||
t: t,
|
||||
|
||||
expectedPublicInputsHash: poseidon.Hash{
|
||||
field.NewFieldElementFromString("0"),
|
||||
field.NewFieldElementFromString("0"),
|
||||
field.NewFieldElementFromString("0"),
|
||||
field.NewFieldElementFromString("0"),
|
||||
},
|
||||
|
||||
expectedPlonkBetas: []field.F{
|
||||
field.NewFieldElementFromString("11216469004148781751"),
|
||||
field.NewFieldElementFromString("6201977337075152249"),
|
||||
},
|
||||
|
||||
expectedPlonkGammas: []field.F{
|
||||
field.NewFieldElementFromString("8369751006669847974"),
|
||||
field.NewFieldElementFromString("3610024170884289835"),
|
||||
},
|
||||
|
||||
expectedPlonkAlphas: []field.F{
|
||||
field.NewFieldElementFromString("970160439138448145"),
|
||||
field.NewFieldElementFromString("2402201283787401921"),
|
||||
},
|
||||
|
||||
expectedPlonkZeta: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("17377750363769967882"),
|
||||
field.NewFieldElementFromString("11921191651424768462"),
|
||||
},
|
||||
|
||||
expectedFriAlpha: field.QuadraticExtension{
|
||||
field.NewFieldElementFromString("16721004555774385479"),
|
||||
field.NewFieldElementFromString("10688151135543754663"),
|
||||
},
|
||||
|
||||
expectedFriBetas: []field.QuadraticExtension{
|
||||
{
|
||||
field.NewFieldElementFromString("3312441922957827805"),
|
||||
field.NewFieldElementFromString("15128092514958289671"),
|
||||
},
|
||||
{
|
||||
field.NewFieldElementFromString("13630530769060141802"),
|
||||
field.NewFieldElementFromString("14559883974933163008"),
|
||||
},
|
||||
{
|
||||
field.NewFieldElementFromString("16146508250083930687"),
|
||||
field.NewFieldElementFromString("5176346568444408396"),
|
||||
},
|
||||
},
|
||||
|
||||
expectedFriQueryIndices: []field.F{
|
||||
field.NewFieldElement(16334967868590615051),
|
||||
field.NewFieldElement(2911473540496037915),
|
||||
field.NewFieldElement(14887216056886344225),
|
||||
field.NewFieldElement(7808811227805914295),
|
||||
field.NewFieldElement(2018594961417375749),
|
||||
field.NewFieldElement(3733368398777208435),
|
||||
field.NewFieldElement(2623035669037055104),
|
||||
field.NewFieldElement(299243030573481514),
|
||||
field.NewFieldElement(7189789717962704433),
|
||||
field.NewFieldElement(14566344026886816268),
|
||||
field.NewFieldElement(12555390069003437453),
|
||||
field.NewFieldElement(17225508403199418233),
|
||||
field.NewFieldElement(5088797913879903292),
|
||||
field.NewFieldElement(9715691392773433023),
|
||||
field.NewFieldElement(7565836764713256165),
|
||||
field.NewFieldElement(1500143546029322929),
|
||||
field.NewFieldElement(1245802417104422080),
|
||||
field.NewFieldElement(6831959786661245110),
|
||||
field.NewFieldElement(17271054758535453780),
|
||||
field.NewFieldElement(6225460404576395409),
|
||||
field.NewFieldElement(15932661092896277351),
|
||||
field.NewFieldElement(12452534049198240575),
|
||||
field.NewFieldElement(4225199666055520177),
|
||||
field.NewFieldElement(13235091290587791090),
|
||||
field.NewFieldElement(2562357622728700774),
|
||||
field.NewFieldElement(17676678042980201498),
|
||||
field.NewFieldElement(5837067135702409874),
|
||||
field.NewFieldElement(11238419549114325157),
|
||||
},
|
||||
}
|
||||
witness := TestVerifierChallengesCircuit{} // No real witness as the test circuit's Define function will inject in the witness
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
|
||||
type TestVerifierCircuit struct {
|
||||
proofWithPIsFilename string `gnark:"-"`
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
verifierOnlyCircuitDataFilename string `gnark:"-"`
|
||||
}
|
||||
|
||||
func (c *TestVerifierCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs(c.proofWithPIsFilename)
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(c.commonCircuitDataFilename)
|
||||
verfierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename)
|
||||
|
||||
verifierChip := verifier.NewVerifierChip(api, commonCircuitData)
|
||||
verifierChip.Verify(proofWithPis, verfierOnlyCircuitData, commonCircuitData)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDummyVerifier(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestVerifierCircuit{
|
||||
proofWithPIsFilename: "./data/dummy_2^14_gates/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/dummy_2^14_gates/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/dummy_2^14_gates/verifier_only_circuit_data.json",
|
||||
}
|
||||
|
||||
witness := TestVerifierCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
testCase()
|
||||
}
|
||||
Reference in New Issue
Block a user