You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
8.1 KiB

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