eth-kzg-ceremony-alt/parsers.go
parsers.goRaw
1package kzgceremony
2
3import (
4 "encoding/hex"
5 "encoding/json"
6 "fmt"
7 "strings"
8
9 bls12381 "github.com/kilic/bls12-381"
10)
11
12// UnmarshalJSON implements the State json unmarshaler, compatible
13// with the official Ethereum KZG Ceremony formats
14func (s *State) UnmarshalJSON(b []byte) error {
15 var sStr stateStr
16 if err := json.Unmarshal(b, &sStr); err != nil {
17 return err
18 }
19 var err error
20 s.ParticipantIDs = sStr.ParticipantIDs
21 s.ParticipantECDSASignatures = sStr.ParticipantECDSASignatures
22
23 s.Transcripts = make([]Transcript, len(sStr.Transcripts))
24 for i := 0; i < len(sStr.Transcripts); i++ {
25 if sStr.Transcripts[i].NumG1Powers != uint64(len(sStr.Transcripts[i].PowersOfTau.G1Powers)) {
26 return fmt.Errorf("wrong NumG1Powers")
27 }
28 if sStr.Transcripts[i].NumG2Powers != uint64(len(sStr.Transcripts[i].PowersOfTau.G2Powers)) {
29 return fmt.Errorf("wrong NumG2Powers")
30 }
31 s.Transcripts[i].NumG1Powers = sStr.Transcripts[i].NumG1Powers
32 s.Transcripts[i].NumG2Powers = sStr.Transcripts[i].NumG2Powers
33 s.Transcripts[i].PowersOfTau = &SRS{}
34 s.Transcripts[i].PowersOfTau.G1Powers, err =
35 stringsToPointsG1(sStr.Transcripts[i].PowersOfTau.G1Powers)
36 if err != nil {
37 return err
38 }
39 s.Transcripts[i].PowersOfTau.G2Powers, err =
40 stringsToPointsG2(sStr.Transcripts[i].PowersOfTau.G2Powers)
41 if err != nil {
42 return err
43 }
44
45 s.Transcripts[i].Witness = &Witness{}
46 s.Transcripts[i].Witness.RunningProducts, err =
47 stringsToPointsG1(sStr.Transcripts[i].Witness.RunningProducts)
48 if err != nil {
49 return err
50 }
51 s.Transcripts[i].Witness.PotPubKeys, err =
52 stringsToPointsG2(sStr.Transcripts[i].Witness.PotPubKeys)
53 if err != nil {
54 return err
55 }
56 s.Transcripts[i].Witness.BLSSignatures, err =
57 stringsToPointsG1(sStr.Transcripts[i].Witness.BLSSignatures)
58 if err != nil {
59 return err
60 }
61 }
62 return err
63}
64
65// MarshalJSON implements the State json marshaler, compatible with the
66// official Ethereum KZG Ceremony formats
67func (s State) MarshalJSON() ([]byte, error) {
68 var sStr stateStr
69 sStr.ParticipantIDs = s.ParticipantIDs
70 sStr.ParticipantECDSASignatures = s.ParticipantECDSASignatures
71
72 sStr.Transcripts = make([]transcriptStr, len(s.Transcripts))
73 for i := 0; i < len(s.Transcripts); i++ {
74 if s.Transcripts[i].NumG1Powers != uint64(len(s.Transcripts[i].PowersOfTau.G1Powers)) {
75 return nil, fmt.Errorf("wrong NumG1Powers")
76 }
77 if s.Transcripts[i].NumG2Powers != uint64(len(s.Transcripts[i].PowersOfTau.G2Powers)) {
78 return nil, fmt.Errorf("wrong NumG2Powers")
79 }
80 sStr.Transcripts[i].NumG1Powers = s.Transcripts[i].NumG1Powers
81 sStr.Transcripts[i].NumG2Powers = s.Transcripts[i].NumG2Powers
82 sStr.Transcripts[i].PowersOfTau = powersOfTauStr{}
83 sStr.Transcripts[i].PowersOfTau.G1Powers =
84 g1PointsToStrings(s.Transcripts[i].PowersOfTau.G1Powers)
85 sStr.Transcripts[i].PowersOfTau.G2Powers =
86 g2PointsToStrings(s.Transcripts[i].PowersOfTau.G2Powers)
87
88 sStr.Transcripts[i].Witness = witnessStr{}
89 sStr.Transcripts[i].Witness.RunningProducts =
90 g1PointsToStrings(s.Transcripts[i].Witness.RunningProducts)
91 sStr.Transcripts[i].Witness.PotPubKeys =
92 g2PointsToStrings(s.Transcripts[i].Witness.PotPubKeys)
93 sStr.Transcripts[i].Witness.BLSSignatures =
94 g1PointsToStrings(s.Transcripts[i].Witness.BLSSignatures)
95 }
96 return json.Marshal(sStr)
97}
98
99// UnmarshalJSON implements the BatchContribution json unmarshaler, compatible
100// with the official Ethereum KZG Ceremony formats
101func (c *BatchContribution) UnmarshalJSON(b []byte) error {
102 var cStr batchContributionStr
103 if err := json.Unmarshal(b, &cStr); err != nil {
104 return err
105 }
106 var err error
107
108 c.Contributions = make([]Contribution, len(cStr.Contributions))
109 for i := 0; i < len(cStr.Contributions); i++ {
110 c.Contributions[i].NumG1Powers = cStr.Contributions[i].NumG1Powers
111 c.Contributions[i].NumG2Powers = cStr.Contributions[i].NumG2Powers
112 c.Contributions[i].PowersOfTau = &SRS{}
113 c.Contributions[i].PowersOfTau.G1Powers, err =
114 stringsToPointsG1(cStr.Contributions[i].PowersOfTau.G1Powers)
115 if err != nil {
116 return err
117 }
118 c.Contributions[i].PowersOfTau.G2Powers, err =
119 stringsToPointsG2(cStr.Contributions[i].PowersOfTau.G2Powers)
120 if err != nil {
121 return err
122 }
123
124 g2sBytes, err := hex.DecodeString(strings.TrimPrefix(cStr.Contributions[i].PotPubKey, "0x"))
125 if err != nil {
126 return err
127 }
128 c.Contributions[i].PotPubKey, err = g2.FromCompressed(g2sBytes)
129 if err != nil {
130 return err
131 }
132 }
133 return err
134}
135
136// MarshalJSON implements the BatchContribution json marshaler, compatible
137// with the official Ethereum KZG Ceremony formats
138func (c BatchContribution) MarshalJSON() ([]byte, error) {
139 var cStr batchContributionStr
140
141 cStr.Contributions = make([]contributionStr, len(c.Contributions))
142 for i := 0; i < len(c.Contributions); i++ {
143 cStr.Contributions[i].NumG1Powers = c.Contributions[i].NumG1Powers
144 cStr.Contributions[i].NumG2Powers = c.Contributions[i].NumG2Powers
145 cStr.Contributions[i].PowersOfTau = powersOfTauStr{}
146 cStr.Contributions[i].PowersOfTau.G1Powers =
147 g1PointsToStrings(c.Contributions[i].PowersOfTau.G1Powers)
148 cStr.Contributions[i].PowersOfTau.G2Powers =
149 g2PointsToStrings(c.Contributions[i].PowersOfTau.G2Powers)
150
151 cStr.Contributions[i].PotPubKey = "0x" +
152 hex.EncodeToString(g2.ToCompressed(c.Contributions[i].PotPubKey))
153 }
154 return json.Marshal(cStr)
155}
156
157type powersOfTauStr struct {
158 G1Powers []string `json:"G1Powers"`
159 G2Powers []string `json:"G2Powers"`
160}
161
162type witnessStr struct {
163 RunningProducts []string `json:"runningProducts"`
164 PotPubKeys []string `json:"potPubkeys"`
165 BLSSignatures []string `json:"blsSignatures"`
166}
167
168type transcriptStr struct {
169 NumG1Powers uint64 `json:"numG1Powers"`
170 NumG2Powers uint64 `json:"numG2Powers"`
171 PowersOfTau powersOfTauStr `json:"powersOfTau"`
172 Witness witnessStr `json:"witness"`
173}
174
175type contributionStr struct {
176 NumG1Powers uint64 `json:"numG1Powers"`
177 NumG2Powers uint64 `json:"numG2Powers"`
178 PowersOfTau powersOfTauStr `json:"powersOfTau"`
179 PotPubKey string `json:"potPubkey"`
180}
181
182type batchContributionStr struct {
183 Contributions []contributionStr `json:"contributions"`
184}
185
186type stateStr struct {
187 Transcripts []transcriptStr `json:"transcripts"`
188 ParticipantIDs []string `json:"participantIds"`
189 ParticipantECDSASignatures []string `json:"participantEcdsaSignatures"`
190}
191
192func g1PointsToStrings(points []*bls12381.PointG1) []string {
193 n := len(points)
194 g1s := make([]string, n)
195 for i := 0; i < n; i++ {
196 if points[i] == nil {
197 g1s[i] = ""
198 continue
199 }
200 g1s[i] = "0x" + hex.EncodeToString(g1.ToCompressed(points[i]))
201 }
202 return g1s
203}
204
205func g2PointsToStrings(points []*bls12381.PointG2) []string {
206 n := len(points)
207 g2s := make([]string, n)
208 for i := 0; i < n; i++ {
209 if points[i] == nil {
210 g2s[i] = ""
211 continue
212 }
213 g2s[i] = "0x" + hex.EncodeToString(g2.ToCompressed(points[i]))
214 }
215 return g2s
216}
217
218// stringsToPointsG1 parses the strings that represent the G1 points in the
219// ZCash compressed format into bls12381.PointG1 data structure. Additionally
220// it checks the points correctness
221func stringsToPointsG1(s []string) ([]*bls12381.PointG1, error) {
222 n := len(s)
223 g1s := make([]*bls12381.PointG1, n)
224 for i := 0; i < n; i++ {
225 if s[i] == "" {
226 continue
227 }
228 g1sBytes, err := hex.DecodeString(strings.TrimPrefix(s[i], "0x"))
229 if err != nil {
230 return nil, err
231 }
232 g1s_i, err := g1.FromCompressed(g1sBytes)
233 if err != nil {
234 return nil, err
235 }
236 if err := checkG1PointCorrectness(g1s_i); err != nil {
237 return nil, err
238 }
239 g1s[i] = g1s_i
240 }
241 return g1s, nil
242}
243
244// stringsToPointsG2 parses the strings that represent the G2 points in the
245// ZCash compressed format into bls12381.PointG2 data structure. Additionally
246// it checks the points correctness
247func stringsToPointsG2(s []string) ([]*bls12381.PointG2, error) {
248 n := len(s)
249 g2s := make([]*bls12381.PointG2, n)
250 for i := 0; i < n; i++ {
251 if s[i] == "" {
252 continue
253 }
254 g2sBytes, err := hex.DecodeString(strings.TrimPrefix(s[i], "0x"))
255 if err != nil {
256 return nil, err
257 }
258 g2s_i, err := g2.FromCompressed(g2sBytes)
259 if err != nil {
260 return nil, err
261 }
262 if err := checkG2PointCorrectness(g2s_i); err != nil {
263 return nil, err
264 }
265 g2s[i] = g2s_i
266 }
267 return g2s, nil
268}