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) GetChallenge() F {
59	if len(c.inputBuffer) != 0 || len(c.outputBuffer) == 0 {
60		c.duplexing()
61	}
62
63	challenge := c.outputBuffer[len(c.outputBuffer)-1]
64	c.outputBuffer = c.outputBuffer[:len(c.outputBuffer)-1]
65
66	return challenge
67}
68
69func (c *ChallengerChip) GetNChallenges(n int) []F {
70	challenges := make([]F, n)
71	for i := 0; i < n; i++ {
72		challenges[i] = c.GetChallenge()
73	}
74	return challenges
75}
76
77func clearBuffer(buffer []F) []F {
78	return make([]F, 0)
79}
80
81func (c *ChallengerChip) duplexing() {
82	if len(c.inputBuffer) > poseidon.SPONGE_RATE {
83		fmt.Println(len(c.inputBuffer))
84		panic("something went wrong")
85	}
86	for i := 0; i < len(c.inputBuffer); i++ {
87		c.spongeState[i] = c.inputBuffer[i]
88	}
89	c.inputBuffer = clearBuffer(c.inputBuffer)
90	c.spongeState = c.poseidonChip.Poseidon(c.spongeState)
91	clearBuffer(c.outputBuffer)
92	for i := 0; i < poseidon.SPONGE_RATE; i++ {
93		c.outputBuffer = append(c.outputBuffer, c.spongeState[i])
94		// c.outputBuffer[i] = c.spongeState[i]
95	}
96}