gnark-plonky2-verifier/plonky2_verifier/challenger.go
plonky2_verifier/challenger.goRaw
1package plonky2_verifier
2
3import (
4 "fmt"
5 . "gnark-plonky2-verifier/field"
6 "gnark-plonky2-verifier/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 c.ObserveElement(powWitness)
119
120 friPowResponse := c.GetChallenge()
121 friQueryIndices := c.GetNChallenges(numFriQueries)
122
123 return FriChallenges{
124 FriAlpha: friAlpha,
125 FriBetas: friBetas,
126 FriPowResponse: friPowResponse,
127 FriQueryIndices: friQueryIndices,
128 }
129}
130
131func clearBuffer(buffer []F) []F {
132 return make([]F, 0)
133}
134
135func (c *ChallengerChip) duplexing() {
136 if len(c.inputBuffer) > poseidon.SPONGE_RATE {
137 fmt.Println(len(c.inputBuffer))
138 panic("something went wrong")
139 }
140 for i := 0; i < len(c.inputBuffer); i++ {
141 c.spongeState[i] = c.inputBuffer[i]
142 }
143 c.inputBuffer = clearBuffer(c.inputBuffer)
144 c.spongeState = c.poseidonChip.Poseidon(c.spongeState)
145 clearBuffer(c.outputBuffer)
146 for i := 0; i < poseidon.SPONGE_RATE; i++ {
147 c.outputBuffer = append(c.outputBuffer, c.spongeState[i])
148 // c.outputBuffer[i] = c.spongeState[i]
149 }
150}