arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/plonky2_verifier/challenger.go
plonky2_verifier/challenger.goRaw
  1package plonky2_verifier
  2
  3import (
  4	"fmt"
  5	. "gnark-ed25519/field"
  6	"gnark-ed25519/poseidon"
  7
  8	"github.com/consensys/gnark/frontend"
  9)
 10
 11type ChallengerChip struct {
 12	api          frontend.API `gnark:"-"`
 13	field        frontend.API `gnark:"-"`
 14	poseidonChip *poseidon.PoseidonChip
 15	spongeState  [poseidon.SPONGE_WIDTH]F
 16	inputBuffer  []F
 17	outputBuffer []F
 18}
 19
 20func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip *poseidon.PoseidonChip) *ChallengerChip {
 21	var spongeState [poseidon.SPONGE_WIDTH]F
 22	var inputBuffer []F
 23	var outputBuffer []F
 24
 25	for i := 0; i < poseidon.SPONGE_WIDTH; i++ {
 26		spongeState[i] = ZERO_F
 27	}
 28
 29	return &ChallengerChip{
 30		api:          api,
 31		field:        field,
 32		poseidonChip: poseidonChip,
 33		spongeState:  spongeState,
 34		inputBuffer:  inputBuffer,
 35		outputBuffer: outputBuffer,
 36	}
 37}
 38
 39func (c *ChallengerChip) ObserveElement(element F) {
 40	c.outputBuffer = clearBuffer(c.outputBuffer)
 41	c.inputBuffer = append(c.inputBuffer, element)
 42	if len(c.inputBuffer) == poseidon.SPONGE_RATE {
 43		c.duplexing()
 44	}
 45}
 46
 47func (c *ChallengerChip) ObserveElements(elements []F) {
 48	for i := 0; i < len(elements); i++ {
 49		c.ObserveElement(elements[i])
 50	}
 51}
 52
 53func (c *ChallengerChip) ObserveHash(hash Hash) {
 54	c.ObserveElements(hash[:])
 55}
 56
 57func (c *ChallengerChip) ObserveCap(cap []Hash) {
 58	for i := 0; i < len(cap); i++ {
 59		c.ObserveHash(cap[i])
 60	}
 61}
 62
 63func (c *ChallengerChip) ObserveExtensionElement(element QuadraticExtension) {
 64	c.ObserveElements(element[:])
 65}
 66
 67func (c *ChallengerChip) ObserveExtensionElements(elements []QuadraticExtension) {
 68	for i := 0; i < len(elements); i++ {
 69		c.ObserveExtensionElement(elements[i])
 70	}
 71}
 72
 73func (c *ChallengerChip) ObserveOpenings(openings FriOpenings) {
 74	for i := 0; i < len(openings.Batches); i++ {
 75		c.ObserveExtensionElements(openings.Batches[i].Values)
 76	}
 77}
 78
 79func (c *ChallengerChip) GetChallenge() F {
 80	if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
 81		c.duplexing()
 82	}
 83
 84	challenge := c.outputBuffer[len(c.outputBuffer)-1]
 85	c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1]
 86
 87	return challenge
 88}
 89
 90func (c *ChallengerChip) GetNChallenges(n uint64) []F {
 91	challenges := make([]F, n)
 92	for i := uint64(0); i < n; i++ {
 93		challenges[i] = c.GetChallenge()
 94	}
 95	return challenges
 96}
 97
 98func (c *ChallengerChip) GetExtensionChallenge() QuadraticExtension {
 99	values := c.GetNChallenges(2)
100	return QuadraticExtension{values[0], values[1]}
101}
102
103func (c *ChallengerChip) GetHash() Hash {
104	return [4]F{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()}
105}
106
107func (c *ChallengerChip) GetFriChallenges(commitPhaseMerkleCaps []MerkleCap, finalPoly PolynomialCoeffs, powWitness F, degreeBits uint64, config FriConfig) FriChallenges {
108	numFriQueries := config.NumQueryRounds
109	friAlpha := c.GetExtensionChallenge()
110
111	var friBetas []QuadraticExtension
112	for i := 0; i < len(commitPhaseMerkleCaps); i++ {
113		c.ObserveCap(commitPhaseMerkleCaps[i])
114		friBetas = append(friBetas, c.GetExtensionChallenge())
115	}
116
117	c.ObserveExtensionElements(finalPoly.Coeffs)
118
119	hash := c.GetHash()
120	powInputs := append(hash[:], powWitness)
121
122	friPowResponse := c.poseidonChip.HashNoPad(powInputs)[0]
123	friQueryIndices := c.GetNChallenges(numFriQueries)
124
125	return FriChallenges{
126		FriAlpha:         friAlpha,
127		FriBetas:         friBetas,
128		FriPowResponse:   friPowResponse,
129		FriQueryIndicies: friQueryIndices,
130	}
131}
132
133func clearBuffer(buffer []F) []F {
134	return make([]F, 0)
135}
136
137func (c *ChallengerChip) duplexing() {
138	if len(c.inputBuffer) > poseidon.SPONGE_RATE {
139		fmt.Println(len(c.inputBuffer))
140		panic("something went wrong")
141	}
142	for i := 0; i < len(c.inputBuffer); i++ {
143		c.spongeState[i] = c.inputBuffer[i]
144	}
145	c.inputBuffer = clearBuffer(c.inputBuffer)
146	c.spongeState = c.poseidonChip.Poseidon(c.spongeState)
147	clearBuffer(c.outputBuffer)
148	for i := 0; i < poseidon.SPONGE_RATE; i++ {
149		c.outputBuffer = append(c.outputBuffer, c.spongeState[i])
150		// c.outputBuffer[i] = c.spongeState[i]
151	}
152}