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
15// pub struct Challenger {
16// sponge_state: [GoldilocksField; SPONGE_WIDTH],
17// input_buffer: Vec<GoldilocksField>,
18// output_buffer: Vec<GoldilocksField>
19// }
20
21func NewChallenger() Challenger {
22 var sponge_state [SPONGE_WIDTH]V
23 for i := 0; i < SPONGE_WIDTH; i++ {
24 sponge_state[i] = 0
25 }
26 return Challenger {
27 sponge_state: sponge_state,
28 input_buffer: []V{},
29 output_buffer: []V{},
30 }
31}
32// pub fn new() -> Challenger {
33// return Challenger {
34// sponge_state: [GoldilocksField::ZERO; SPONGE_WIDTH],
35// input_buffer: Vec::with_capacity(SPONGE_RATE),
36// output_buffer: Vec::with_capacity(SPONGE_RATE)
37// };
38// }
39
40func (c *Challenger) observe_elements(elements []V) {
41 for _, element := range elements {
42 c.observe_element(element)
43 }
44}
45// pub fn observe_elements(&mut self, elements: &[GoldilocksField]) {
46// for &element in elements {
47// self.observe_element(element);
48// }
49// }
50
51func (c *Challenger) observe_hash(hash []V) {
52 c.observe_elements(hash)
53}
54// pub fn observe_hash(&mut self, hash: Vec<GoldilocksField>) {
55// self.observe_elements(&hash.to_vec())
56// }
57
58func (c *Challenger) observe_element(element V) {
59 c.output_buffer = V[]{}
60 c.input_buffer = append(c.input_buffer, element)
61 if len(c.input_buffer) == SPONGE_RATE {
62 c.duplexing()
63 }
64}
65// pub fn observe_element(&mut self, element: GoldilocksField) {
66// self.output_buffer.clear();
67// self.input_buffer.push(element);
68// if self.input_buffer.len() == SPONGE_RATE {
69// self.duplexing();
70// }
71// }
72
73func (c *Challenger) observe_cap(cap [][]V) {
74 for _, hash := range cap {
75 c.observe_hash(hash)
76 }
77}
78// pub fn observe_cap(&mut self, cap: &Vec<Vec<GoldilocksField>>) {
79// for hash in cap.into_iter() {
80// self.observe_hash(hash.clone());
81// }
82// }
83
84func (c *Challenger) duplexing() {
85 if len(c.input_buffer) > SPONGE_RATE { panic("buffer too large") }
86
87 for i, input := range c.input_buffer {
88 c.sponge_state[i] = input
89 }
90 c.input_buffer = V[]{}
91
92 c.sponge_state = poseidon(c.sponge_state)
93
94 c.output_buffer = c.sponge_state[:SPONGE_RATE]
95}
96// fn duplexing(&mut self) {
97// assert!(self.input_buffer.len() <= SPONGE_RATE);
98
99// for (i, input) in self.input_buffer.drain(..).enumerate() {
100// self.sponge_state[i] = input;
101// }
102
103// self.sponge_state = poseidon(self.sponge_state);
104
105// self.output_buffer.clear();
106// self.output_buffer
107// .extend_from_slice(&self.sponge_state[0..SPONGE_RATE]);
108// }
109
110func (c *Challenger) get_challenge() V {
111 if len(c.input_buffer) > 0 || len(c.output_buffer) == 0 {
112 c.duplexing()
113 }
114 result := c.output_buffer[len(c.output_buffer) - 1]
115 c.output_buffer = c.output_buffer[:len(c.output_buffer) - 1]
116 return result
117}
118// pub fn get_challenge(&mut self) -> GoldilocksField {
119// if !self.input_buffer.is_empty() || self.output_buffer.is_empty() {
120// self.duplexing();
121// }
122
123// self.output_buffer
124// .pop()
125// .expect("Output buffer should be non-empty")
126// }
127
128func (c *Challenger) get_n_challenges(n int) []V {
129 result := make([]V, n)
130 for i := 0; i < n; i++ {
131 result[i] = c.get_challenge()
132 }
133 return result
134}
135// pub fn get_n_challenges(&mut self, n: usize) -> Vec<GoldilocksField> {
136// (0..n).map(|_| self.get_challenge()).collect()
137// }
138// }
139