From 7091e1e1b20efff0f8f45bce3b6d7cea2462ae8e Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 4 Apr 2023 13:15:27 -0700 Subject: [PATCH] initial work: gate interface and PublicInput --- plonky2_verifier/gate.go | 50 ++++++++++++++++++++++++++++++++ plonky2_verifier/plonk.go | 32 +++++++++++++++++++- plonky2_verifier/public_input.go | 32 ++++++++++++++++++++ plonky2_verifier/selectors.go | 17 +++++++++++ plonky2_verifier/structs.go | 2 ++ plonky2_verifier/vars.go | 19 ++++++++++++ 6 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 plonky2_verifier/gate.go create mode 100644 plonky2_verifier/public_input.go create mode 100644 plonky2_verifier/selectors.go create mode 100644 plonky2_verifier/vars.go diff --git a/plonky2_verifier/gate.go b/plonky2_verifier/gate.go new file mode 100644 index 0000000..49f2dd7 --- /dev/null +++ b/plonky2_verifier/gate.go @@ -0,0 +1,50 @@ +package plonky2_verifier + +import ( + . "gnark-plonky2-verifier/field" +) + +type gate interface { + EvalUnfiltered(vars EvaluationVars) []QuadraticExtension +} + +func (p *PlonkChip) computeFilter( + row int, + 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 int, + selectorIndex int, + groupRange Range, + numSelectors int, +) []QuadraticExtension { + filter := p.computeFilter(row, groupRange, vars.localConstants[selectorIndex], numSelectors > 1) + + vars.RemovePrefix(numSelectors) + + unfiltered := g.EvalUnfiltered(vars) + for i := range unfiltered { + unfiltered[i] = p.qeAPI.MulExtension(unfiltered[i], filter) + } + return unfiltered +} diff --git a/plonky2_verifier/plonk.go b/plonky2_verifier/plonk.go index 5c0f9de..439e5c6 100644 --- a/plonky2_verifier/plonk.go +++ b/plonky2_verifier/plonk.go @@ -116,8 +116,38 @@ func (p *PlonkChip) checkPartialProducts( return partialProductChecks } +func (p *PlonkChip) evalFiltered( + g gate, + vars EvaluationVars, + row int, + selectorIndex int, + groupRange Range, + numSelectors int +) []QuadraticExtension { + +} + +func (p *PlonkChip) evaluateGateConstraints( + commonData CommonCircuitData, + x QuadraticExtension, + vars EvaluationVars, + localZs []QuadraticExtension, + nextZs []QuadraticExtension, + partialProducts []QuadraticExtension, + sSigmas []QuadraticExtension, + betas []F, + gammas []F, + alphas []F, +) []QuadraticExtension { + constraints := make([]QuadraticExtension, commonData.NumGateConstraints) + + for i, gate := range commonData.Gates { + selectorIndex := commonData.selector + } +} + func (p *PlonkChip) evalVanishingPoly(proofChallenges ProofChallenges, openings OpeningSet, zetaPowN QuadraticExtension) []QuadraticExtension { - // TODO: evaluate_gate_contraints logic should be implemented here. See https://github.com/mir-protocol/plonky2/blob/main/plonky2/src/plonk/vanishing_poly.rs#L39 + // TODO: evaluate_gate_constraints logic should be implemented here. See https://github.com/mir-protocol/plonky2/blob/main/plonky2/src/plonk/vanishing_poly.rs#L39 // Calculate the k[i] * x sIDs := make([]QuadraticExtension, p.commonData.Config.NumRoutedWires) diff --git a/plonky2_verifier/public_input.go b/plonky2_verifier/public_input.go new file mode 100644 index 0000000..211873b --- /dev/null +++ b/plonky2_verifier/public_input.go @@ -0,0 +1,32 @@ +package plonky2_verifier + +import ( + . "gnark-plonky2-verifier/field" +) + +type PublicInputGate struct { +} + +func (p *PublicInputGate) WiresPublicInputsHash() []int { + return []int{0, 1, 2, 3} +} + +func (p *PublicInputGate) EvalUnfiltered(pc *PlonkChip, vars EvaluationVars) []QuadraticExtension { + constraints := []QuadraticExtension{} + + wires := p.WiresPublicInputsHash() + hash_parts := vars.publicInputsHash.elements + for i := 0; i < 4; i++ { + wire := wires[i] + hash_part := hash_parts[i] + + diff := pc.qeAPI.SubExtension(vars.localWires[wire], pc.qeAPI.FieldToQE(hash_part)) + constraints = append(constraints, diff) + } + + return constraints +} + +func (p *PublicInputGate) EvalFiltered(vars EvaluationVars) []QuadraticExtension { + return nil +} diff --git a/plonky2_verifier/selectors.go b/plonky2_verifier/selectors.go new file mode 100644 index 0000000..a29e750 --- /dev/null +++ b/plonky2_verifier/selectors.go @@ -0,0 +1,17 @@ +package plonky2_verifier + +const UNUSED_SELECTOR = ^uint64(0) // max uint + +type Range struct { + start uint64 + end uint64 +} + +type SelectorsInfo struct { + selectorIndices []uint64 + groups []Range +} + +func (s *SelectorsInfo) NumSelectors() int { + return len(s.groups) +} diff --git a/plonky2_verifier/structs.go b/plonky2_verifier/structs.go index 50e1c7b..5395f97 100644 --- a/plonky2_verifier/structs.go +++ b/plonky2_verifier/structs.go @@ -101,6 +101,8 @@ type CircuitConfig struct { type CommonCircuitData struct { Config CircuitConfig FriParams FriParams + Gates []gate + SelectorsInfo SelectorsInfo DegreeBits uint64 QuotientDegreeFactor uint64 NumGateConstraints uint64 diff --git a/plonky2_verifier/vars.go b/plonky2_verifier/vars.go new file mode 100644 index 0000000..8f04a2d --- /dev/null +++ b/plonky2_verifier/vars.go @@ -0,0 +1,19 @@ +package plonky2_verifier + +import ( + . "gnark-plonky2-verifier/field" +) + +type HashOut struct { + elements [4]F +} + +type EvaluationVars struct { + localConstants []QuadraticExtension + localWires []QuadraticExtension + publicInputsHash HashOut +} + +func (e *EvaluationVars) RemovePrefix(numSelectors int) { + e.localConstants = e.localConstants[numSelectors:] +}