@ -1,8 +1,7 @@ |
|||||
package plonky2_verifier |
|
||||
|
package field |
||||
|
|
||||
import ( |
import ( |
||||
"fmt" |
"fmt" |
||||
. "gnark-plonky2-verifier/field" |
|
||||
"math/bits" |
"math/bits" |
||||
|
|
||||
"github.com/consensys/gnark/frontend" |
"github.com/consensys/gnark/frontend" |
@ -0,0 +1,58 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
. "gnark-plonky2-verifier/field" |
||||
|
) |
||||
|
|
||||
|
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(p *PlonkChip, vars EvaluationVars) []QuadraticExtension { |
||||
|
const0 := vars.localConstants[0] |
||||
|
const1 := vars.localConstants[1] |
||||
|
|
||||
|
constraints := []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 := p.qeAPI.AddExtension( |
||||
|
p.qeAPI.MulExtension(p.qeAPI.MulExtension(multiplicand0, multiplicand1), const0), |
||||
|
p.qeAPI.MulExtension(addend, const1), |
||||
|
) |
||||
|
|
||||
|
constraints = append(constraints, p.qeAPI.SubExtension(output, computedOutput)) |
||||
|
} |
||||
|
|
||||
|
return constraints |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
. "gnark-plonky2-verifier/field" |
||||
|
) |
||||
|
|
||||
|
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(p *PlonkChip, vars EvaluationVars) []QuadraticExtension { |
||||
|
constraints := []QuadraticExtension{} |
||||
|
|
||||
|
for i := uint64(0); i < g.numConsts; i++ { |
||||
|
constraints = append(constraints, p.qeAPI.SubExtension(vars.localConstants[g.ConstInput(i)], vars.localWires[g.WireOutput(i)])) |
||||
|
} |
||||
|
|
||||
|
return constraints |
||||
|
} |
@ -1 +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":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":[]},"degree_bits":3,"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,"circuit_digest":{"elements":[7754113318730736048,18436136620016916513,18054530212389526288,5893739326632906028]}} |
|
||||
|
{"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} |
@ -1 +1 @@ |
|||||
{"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]}]} |
|
||||
|
{"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]}} |
@ -0,0 +1,92 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
. "gnark-plonky2-verifier/field" |
||||
|
"strconv" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
type gate interface { |
||||
|
Id() string |
||||
|
EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension |
||||
|
} |
||||
|
|
||||
|
func GateInstanceFromId(gateId string) gate { |
||||
|
if strings.HasPrefix(gateId, "ArithmeticGate") { |
||||
|
numOpsRaw := strings.Split(gateId, ":")[1] |
||||
|
numOpsRaw = strings.Split(numOpsRaw, "}")[0] |
||||
|
numOpsRaw = strings.TrimSpace(numOpsRaw) |
||||
|
numOps, err := strconv.Atoi(numOpsRaw) |
||||
|
if err != nil { |
||||
|
panic("Invalid gate ID for ArithmeticGate") |
||||
|
} |
||||
|
return NewArithmeticGate(uint64(numOps)) |
||||
|
} |
||||
|
|
||||
|
if strings.HasPrefix(gateId, "ConstantGate") { |
||||
|
numConstsRaw := strings.Split(gateId, ":")[1] |
||||
|
numConstsRaw = strings.Split(numConstsRaw, "}")[0] |
||||
|
numConstsRaw = strings.TrimSpace(numConstsRaw) |
||||
|
numConsts, err := strconv.Atoi(numConstsRaw) |
||||
|
if err != nil { |
||||
|
panic("Invalid gate ID") |
||||
|
} |
||||
|
return NewConstantGate(uint64(numConsts)) |
||||
|
} |
||||
|
|
||||
|
if gateId == "NoopGate" { |
||||
|
return NewNoopGate() |
||||
|
} |
||||
|
|
||||
|
if gateId == "PublicInputGate" { |
||||
|
return NewPublicInputGate() |
||||
|
} |
||||
|
|
||||
|
if strings.HasPrefix(gateId, "PoseidonGate") { |
||||
|
return NewPoseidonGate() |
||||
|
} |
||||
|
|
||||
|
panic(fmt.Sprintf("Unknown gate ID %s", gateId)) |
||||
|
} |
||||
|
|
||||
|
func (p *PlonkChip) computeFilter( |
||||
|
row uint64, |
||||
|
groupRange Range, |
||||
|
s QuadraticExtension, |
||||
|
manySelector bool, |
||||
|
) QuadraticExtension { |
||||
|
product := p.qeAPI.ONE_QE |
||||
|
for i := groupRange.start; i < groupRange.end; i++ { |
||||
|
if i == uint64(row) { |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
product = p.qeAPI.MulExtension(product, p.qeAPI.SubExtension(p.qeAPI.FieldToQE(NewFieldElement(i)), s)) |
||||
|
} |
||||
|
|
||||
|
if manySelector { |
||||
|
product = p.qeAPI.MulExtension(product, p.qeAPI.SubExtension(p.qeAPI.FieldToQE(NewFieldElement(UNUSED_SELECTOR)), s)) |
||||
|
} |
||||
|
|
||||
|
return product |
||||
|
} |
||||
|
|
||||
|
func (p *PlonkChip) evalFiltered( |
||||
|
g gate, |
||||
|
vars EvaluationVars, |
||||
|
row uint64, |
||||
|
selectorIndex uint64, |
||||
|
groupRange Range, |
||||
|
numSelectors uint64, |
||||
|
) []QuadraticExtension { |
||||
|
filter := p.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1) |
||||
|
|
||||
|
vars.RemovePrefix(numSelectors) |
||||
|
|
||||
|
unfiltered := g.EvalUnfiltered(p, vars) |
||||
|
for i := range unfiltered { |
||||
|
unfiltered[i] = p.qeAPI.MulExtension(unfiltered[i], filter) |
||||
|
} |
||||
|
return unfiltered |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
import ( |
||||
|
. "gnark-plonky2-verifier/field" |
||||
|
) |
||||
|
|
||||
|
type NoopGate struct { |
||||
|
} |
||||
|
|
||||
|
func NewNoopGate() *NoopGate { |
||||
|
return &NoopGate{} |
||||
|
} |
||||
|
|
||||
|
func (g *NoopGate) Id() string { |
||||
|
return "NoopGate" |
||||
|
} |
||||
|
|
||||
|
func (g *NoopGate) EvalUnfiltered(p *PlonkChip, vars EvaluationVars) []QuadraticExtension { |
||||
|
return []QuadraticExtension{} |
||||
|
} |
@ -0,0 +1,167 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
import ( |
||||
|
. "gnark-plonky2-verifier/field" |
||||
|
"gnark-plonky2-verifier/poseidon" |
||||
|
) |
||||
|
|
||||
|
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(p *PlonkChip, vars EvaluationVars) []QuadraticExtension { |
||||
|
constraints := []QuadraticExtension{} |
||||
|
|
||||
|
poseidonChip := poseidon.NewPoseidonChip(p.api, NewFieldAPI(p.api), p.qeAPI) |
||||
|
|
||||
|
// Assert that `swap` is binary.
|
||||
|
swap := vars.localWires[g.WireSwap()] |
||||
|
swapMinusOne := p.qeAPI.SubExtension(swap, p.qeAPI.FieldToQE(ONE_F)) |
||||
|
constraints = append(constraints, p.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 := p.qeAPI.SubExtension(inputRhs, inputLhs) |
||||
|
expectedDeltaI := p.qeAPI.MulExtension(swap, diff) |
||||
|
constraints = append(constraints, p.qeAPI.SubExtension(expectedDeltaI, deltaI)) |
||||
|
} |
||||
|
|
||||
|
// Compute the possibly-swapped input layer.
|
||||
|
var state [poseidon.SPONGE_WIDTH]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] = p.qeAPI.AddExtension(inputLhs, deltaI) |
||||
|
state[i+4] = p.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, p.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, p.qeAPI.SubExtension(state[0], sBoxIn)) |
||||
|
state[0] = poseidonChip.SBoxMonomialExtension(sBoxIn) |
||||
|
state[0] = p.qeAPI.AddExtension(state[0], p.qeAPI.FieldToQE(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, p.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, p.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, p.qeAPI.SubExtension(state[i], vars.localWires[g.WireOutput(i)])) |
||||
|
} |
||||
|
|
||||
|
return constraints |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
import ( |
||||
|
. "gnark-plonky2-verifier/field" |
||||
|
) |
||||
|
|
||||
|
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(p *PlonkChip, vars EvaluationVars) []QuadraticExtension { |
||||
|
constraints := []QuadraticExtension{} |
||||
|
|
||||
|
wires := g.WiresPublicInputsHash() |
||||
|
hash_parts := vars.publicInputsHash |
||||
|
for i := 0; i < 4; i++ { |
||||
|
wire := wires[i] |
||||
|
hash_part := hash_parts[i] |
||||
|
|
||||
|
diff := p.qeAPI.SubExtension(vars.localWires[wire], p.qeAPI.FieldToQE(hash_part)) |
||||
|
constraints = append(constraints, diff) |
||||
|
} |
||||
|
|
||||
|
return constraints |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
const UNUSED_SELECTOR = uint64(^uint32(0)) // max uint32
|
||||
|
|
||||
|
type Range struct { |
||||
|
start uint64 |
||||
|
end uint64 |
||||
|
} |
||||
|
|
||||
|
type SelectorsInfo struct { |
||||
|
selectorIndices []uint64 |
||||
|
groups []Range |
||||
|
} |
||||
|
|
||||
|
func (s *SelectorsInfo) NumSelectors() uint64 { |
||||
|
return uint64(len(s.groups)) |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
package plonky2_verifier |
||||
|
|
||||
|
import ( |
||||
|
. "gnark-plonky2-verifier/field" |
||||
|
) |
||||
|
|
||||
|
type EvaluationVars struct { |
||||
|
localConstants []QuadraticExtension |
||||
|
localWires []QuadraticExtension |
||||
|
publicInputsHash Hash |
||||
|
} |
||||
|
|
||||
|
func (e *EvaluationVars) RemovePrefix(numSelectors uint64) { |
||||
|
e.localConstants = e.localConstants[numSelectors:] |
||||
|
} |