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	"github.com/consensys/gnark/frontend"
 5)
 6
 7type V = frontend.Variable
 8
 9type Challenger struct {
10	sponge_state: [SPONGE_WIDTH]V
11	input_buffer: []V
12	output_buffer: []V
13}
14
15func NewChallenger() Challenger {
16	var sponge_state [SPONGE_WIDTH]V
17	for i := 0; i < SPONGE_WIDTH; i++ {
18		sponge_state[i] = 0
19	}
20	return Challenger {
21		sponge_state: sponge_state,
22		input_buffer: []V{},
23		output_buffer: []V{},
24	}
25}
26
27func (c *Challenger) observe_elements(elements []V) {
28	for _, element := range elements {
29		c.observe_element(element)
30	}
31}
32
33func (c *Challenger) observe_hash(hash []V) {
34	c.observe_elements(hash)
35}
36
37func (c *Challenger) observe_element(element V) {
38	c.output_buffer = V[]{}
39	c.input_buffer = append(c.input_buffer, element)
40	if len(c.input_buffer) == SPONGE_RATE {
41		c.duplexing()
42	}
43}
44
45func (c *Challenger) observe_cap(cap [][]V) {
46	for _, hash := range cap {
47		c.observe_hash(hash)
48	}
49}
50
51func (c *Challenger) duplexing() {
52	if len(c.input_buffer) > SPONGE_RATE { panic("buffer too large") }
53
54	for i, input := range c.input_buffer {
55		c.sponge_state[i] = input
56	}
57	c.input_buffer = V[]{}
58
59	c.sponge_state = poseidon(c.sponge_state)
60
61	c.output_buffer = c.sponge_state[:SPONGE_RATE]
62}
63
64func (c *Challenger) get_challenge() V {
65	if len(c.input_buffer) > 0 || len(c.output_buffer) == 0 {
66		c.duplexing()
67	}
68	result := c.output_buffer[len(c.output_buffer) - 1]
69	c.output_buffer = c.output_buffer[:len(c.output_buffer) - 1]
70	return result
71}
72
73func (c *Challenger) get_n_challenges(n int) []V {
74	result := make([]V, n)
75	for i := 0; i < n; i++ {
76		result[i] = c.get_challenge()
77	}
78	return result
79}