arnaucube
arnaucube/eth-kzg-ceremony-altPublic Self-hosted repository
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}