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
 13	field        frontend.API
 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	return &ChallengerChip{
 25		api:          api,
 26		field:        field,
 27		poseidonChip: poseidonChip,
 28		spongeState:  spongeState,
 29		inputBuffer:  inputBuffer,
 30		outputBuffer: outputBuffer,
 31	}
 32}
 33
 34func (c *ChallengerChip) ObserveElement(element F) {
 35	c.outputBuffer = clearBuffer(c.outputBuffer)
 36	c.inputBuffer = append(c.inputBuffer, element)
 37	if len(c.inputBuffer) == poseidon.SPONGE_RATE {
 38		c.duplexing()
 39	}
 40}
 41
 42func (c *ChallengerChip) ObserveElements(elements []F) {
 43	for i := 0; i < len(elements); i++ {
 44		c.ObserveElement(elements[i])
 45	}
 46}
 47
 48func (c *ChallengerChip) ObserveHash(hash Hash) {
 49	c.ObserveElements(hash[:])
 50}
 51
 52func (c *ChallengerChip) ObserveCap(cap []Hash) {
 53	for i := 0; i < len(cap); i++ {
 54		c.ObserveHash(cap[i])
 55	}
 56}
 57
 58func (c *ChallengerChip) ObserveExtensionElement(element QuadraticExtension) {
 59	c.ObserveElements(element[:])
 60}
 61
 62func (c *ChallengerChip) ObserveExtensionElements(elements []QuadraticExtension) {
 63	for i := 0; i < len(elements); i++ {
 64		c.ObserveExtensionElement(elements[i])
 65	}
 66}
 67
 68func (c *ChallengerChip) ObserveOpenings(openings FriOpenings) {
 69	for i := 0; i < len(openings.Batches); i++ {
 70		c.ObserveExtensionElements(openings.Batches[i].values)
 71	}
 72}
 73
 74func (c *ChallengerChip) GetChallenge() F {
 75	if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
 76		c.duplexing()
 77	}
 78
 79	challenge := c.outputBuffer[len(c.outputBuffer)-1]
 80	c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1]
 81
 82	return challenge
 83}
 84
 85func (c *ChallengerChip) GetNChallenges(n uint64) []F {
 86	challenges := make([]F, n)
 87	for i := uint64(0); i < n; i++ {
 88		challenges[i] = c.GetChallenge()
 89	}
 90	return challenges
 91}
 92
 93func (c *ChallengerChip) GetExtensionChallenge() QuadraticExtension {
 94	values := c.GetNChallenges(2)
 95	return QuadraticExtension{values[0], values[1]}
 96}
 97
 98func (c *ChallengerChip) GetHash() Hash {
 99	return [4]F{c.GetChallenge(), c.GetChallenge(), c.GetChallenge(), c.GetChallenge()}
100}
101
102func (c *ChallengerChip) GetFriChallenges(commitPhaseMerkleCaps []MerkleCap, finalPoly PolynomialCoeffs, powWitness F, degreeBits uint64, config struct {
103	RateBits          uint64 "json:\"rate_bits\""
104	CapHeight         uint64 "json:\"cap_height\""
105	ProofOfWorkBits   uint64 "json:\"proof_of_work_bits\""
106	ReductionStrategy struct {
107		ConstantArityBits []int "json:\"ConstantArityBits\""
108	} "json:\"reduction_strategy\""
109	NumQueryRounds uint64 "json:\"num_query_rounds\""
110}) FriChallenges {
111	numFriQueries := config.NumQueryRounds
112	friAlpha := c.GetExtensionChallenge()
113
114	var friBetas []QuadraticExtension
115	for i := 0; i < len(commitPhaseMerkleCaps); i++ {
116		c.ObserveCap(commitPhaseMerkleCaps[i])
117		friBetas = append(friBetas, c.GetExtensionChallenge())
118	}
119
120	c.ObserveExtensionElements(finalPoly.Coeffs)
121
122	hash := c.GetHash()
123	powInputs := append(hash[:], powWitness)
124
125	friPowResponse := c.poseidonChip.HashNoPad(powInputs)[0]
126	friQueryIndices := c.GetNChallenges(numFriQueries)
127
128	return FriChallenges{
129		FriAlpha:         friAlpha,
130		FriBetas:         friBetas,
131		FriPowResponse:   friPowResponse,
132		FriQueryIndicies: friQueryIndices,
133	}
134}
135
136func clearBuffer(buffer []F) []F {
137	return make([]F, 0)
138}
139
140func (c *ChallengerChip) duplexing() {
141	if len(c.inputBuffer) > poseidon.SPONGE_RATE {
142		fmt.Println(len(c.inputBuffer))
143		panic("something went wrong")
144	}
145	for i := 0; i < len(c.inputBuffer); i++ {
146		c.spongeState[i] = c.inputBuffer[i]
147	}
148	c.inputBuffer = clearBuffer(c.inputBuffer)
149	c.spongeState = c.poseidonChip.Poseidon(c.spongeState)
150	clearBuffer(c.outputBuffer)
151	for i := 0; i < poseidon.SPONGE_RATE; i++ {
152		c.outputBuffer = append(c.outputBuffer, c.spongeState[i])
153		// c.outputBuffer[i] = c.spongeState[i]
154	}
155}