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}