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/goldilocks"
 6	"gnark-ed25519/poseidon"
 7	. "gnark-ed25519/poseidon"
 8
 9	"github.com/consensys/gnark/frontend"
10)
11
12type ChallengerChip struct {
13	api          frontend.API
14	field        frontend.API
15	poseidonChip PoseidonChip
16	spongeState  [SPONGE_WIDTH]GoldilocksElement
17	inputBuffer  []GoldilocksElement
18	outputBuffer []GoldilocksElement
19}
20
21func NewChallengerChip(api frontend.API, field frontend.API, poseidonChip PoseidonChip) *ChallengerChip {
22	var spongeState [SPONGE_WIDTH]GoldilocksElement
23	var inputBuffer []GoldilocksElement
24	var outputBuffer []GoldilocksElement
25	return &ChallengerChip{
26		api:          api,
27		field:        field,
28		poseidonChip: poseidonChip,
29		spongeState:  spongeState,
30		inputBuffer:  inputBuffer,
31		outputBuffer: outputBuffer,
32	}
33}
34
35func (c *ChallengerChip) ObserveElement(element GoldilocksElement) {
36	c.outputBuffer = clearBuffer(c.outputBuffer)
37	c.inputBuffer = append(c.inputBuffer, element)
38	if len(c.inputBuffer) == SPONGE_RATE {
39		c.duplexing()
40	}
41}
42
43func (c *ChallengerChip) ObserveElements(elements []GoldilocksElement) {
44	for i := 0; i < len(elements); i++ {
45		c.ObserveElement(elements[i])
46	}
47}
48
49func (c *ChallengerChip) ObserveHash(hash HashOutput) {
50	c.ObserveElements(hash[:])
51}
52
53func (c *ChallengerChip) ObserveCap(cap []HashOutput) {
54	for i := 0; i < len(cap); i++ {
55		c.ObserveHash(cap[i])
56	}
57}
58
59func (c *ChallengerChip) GetChallenge() GoldilocksElement {
60	if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
61		c.duplexing()
62	}
63
64	challenge := c.outputBuffer[len(c.outputBuffer)-1]
65	c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1]
66
67	return challenge
68}
69
70func (c *ChallengerChip) GetNChallenges(n int) []GoldilocksElement {
71	challenges := make([]GoldilocksElement, n)
72	for i := 0; i < n; i++ {
73		challenges[i] = c.GetChallenge()
74	}
75	return challenges
76}
77
78func clearBuffer(buffer []GoldilocksElement) []GoldilocksElement {
79	return make([]GoldilocksElement, 0)
80}
81
82func (c *ChallengerChip) duplexing() {
83	if len(c.inputBuffer) > SPONGE_RATE {
84		fmt.Println(len(c.inputBuffer))
85		panic("something went wrong")
86	}
87	for i := 0; i < len(c.inputBuffer); i++ {
88		c.spongeState[i] = c.inputBuffer[i]
89	}
90	c.inputBuffer = clearBuffer(c.inputBuffer)
91	c.spongeState = c.poseidonChip.Poseidon(c.spongeState)
92	clearBuffer(c.outputBuffer)
93	for i := 0; i < poseidon.SPONGE_RATE; i++ {
94		c.outputBuffer = append(c.outputBuffer, c.spongeState[i])
95		// c.outputBuffer[i] = c.spongeState[i]
96	}
97}