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.

261 lines
7.3 KiB

  1. package kzgceremony
  2. import (
  3. "fmt"
  4. "math/big"
  5. bls12381 "github.com/kilic/bls12-381"
  6. )
  7. // todo: unify addition & multiplicative notation in the comments
  8. const MinRandomnessLen = 64
  9. type Witness struct {
  10. RunningProducts []*bls12381.PointG1
  11. PotPubKeys []*bls12381.PointG2
  12. BLSSignatures []*bls12381.PointG1
  13. }
  14. type Transcript struct {
  15. NumG1Powers uint64
  16. NumG2Powers uint64
  17. PowersOfTau *SRS
  18. Witness *Witness
  19. }
  20. type State struct {
  21. Transcripts []Transcript
  22. ParticipantIDs []string // WIP
  23. ParticipantECDSASignatures []string
  24. }
  25. type Contribution struct {
  26. NumG1Powers uint64
  27. NumG2Powers uint64
  28. PowersOfTau *SRS
  29. PotPubKey *bls12381.PointG2
  30. }
  31. type BatchContribution struct {
  32. Contributions []Contribution
  33. }
  34. func (cs *State) Contribute(randomness []byte) (*State, error) {
  35. ns := State{}
  36. ns.Transcripts = make([]Transcript, len(cs.Transcripts))
  37. for i := 0; i < len(cs.Transcripts); i++ {
  38. ns.Transcripts[i].NumG1Powers = cs.Transcripts[i].NumG1Powers
  39. ns.Transcripts[i].NumG2Powers = cs.Transcripts[i].NumG2Powers
  40. newSRS, proof, err := Contribute(cs.Transcripts[i].PowersOfTau, randomness)
  41. if err != nil {
  42. return nil, err
  43. }
  44. ns.Transcripts[i].PowersOfTau = newSRS
  45. ns.Transcripts[i].Witness = &Witness{}
  46. ns.Transcripts[i].Witness.RunningProducts =
  47. append(cs.Transcripts[i].Witness.RunningProducts, proof.G1PTau)
  48. ns.Transcripts[i].Witness.PotPubKeys =
  49. append(cs.Transcripts[i].Witness.PotPubKeys, proof.G2P)
  50. ns.Transcripts[i].Witness.BLSSignatures = cs.Transcripts[i].Witness.BLSSignatures
  51. }
  52. ns.ParticipantIDs = cs.ParticipantIDs // TODO add github id (id_token.sub)
  53. ns.ParticipantECDSASignatures = cs.ParticipantECDSASignatures
  54. return &ns, nil
  55. }
  56. func (pb *BatchContribution) Contribute(randomness []byte) (*BatchContribution, error) {
  57. nb := BatchContribution{}
  58. nb.Contributions = make([]Contribution, len(pb.Contributions))
  59. for i := 0; i < len(pb.Contributions); i++ {
  60. nb.Contributions[i].NumG1Powers = pb.Contributions[i].NumG1Powers
  61. nb.Contributions[i].NumG2Powers = pb.Contributions[i].NumG2Powers
  62. newSRS, proof, err := Contribute(pb.Contributions[i].PowersOfTau, randomness)
  63. if err != nil {
  64. return nil, err
  65. }
  66. nb.Contributions[i].PowersOfTau = newSRS
  67. nb.Contributions[i].PotPubKey = proof.G2P
  68. }
  69. return &nb, nil
  70. }
  71. // SRS contains the powers of tau in G1 & G2, eg.
  72. // [τ'⁰]₁, [τ'¹]₁, [τ'²]₁, ..., [τ'ⁿ⁻¹]₁,
  73. // [τ'⁰]₂, [τ'¹]₂, [τ'²]₂, ..., [τ'ⁿ⁻¹]₂
  74. type SRS struct {
  75. G1Powers []*bls12381.PointG1
  76. G2Powers []*bls12381.PointG2
  77. }
  78. type toxicWaste struct {
  79. tau *big.Int
  80. TauG2 *bls12381.PointG2
  81. }
  82. // Proof contains g₂ᵖ and g₂^τ', used by the verifier
  83. type Proof struct {
  84. G2P *bls12381.PointG2 // g₂ᵖ
  85. G1PTau *bls12381.PointG1 // g₂^τ' = g₂^{p ⋅ τ}
  86. }
  87. // newEmptySRS creates an empty SRS
  88. func newEmptySRS(nG1, nG2 int) *SRS {
  89. g1s := make([]*bls12381.PointG1, nG1)
  90. g2s := make([]*bls12381.PointG2, nG2)
  91. g1 := bls12381.NewG1()
  92. g2 := bls12381.NewG2()
  93. // one_G1 := g1.One()
  94. // one_G2 := g2.One()
  95. for i := 0; i < nG1; i++ {
  96. g1s[i] = g1.One()
  97. // g1.MulScalar(g1s[i], one_G1, big.NewInt(int64(i)))
  98. }
  99. for i := 0; i < nG2; i++ {
  100. g2s[i] = g2.One()
  101. // g2.MulScalar(g2s[i], one_G2, big.NewInt(int64(i)))
  102. }
  103. return &SRS{g1s, g2s}
  104. }
  105. func tau(randomness []byte) *toxicWaste {
  106. g2 := bls12381.NewG2()
  107. tau := new(big.Int).Mod(
  108. new(big.Int).SetBytes(randomness),
  109. g2.Q())
  110. tau_Fr := bls12381.NewFr().FromBytes(tau.Bytes())
  111. TauG2 := g2.New()
  112. g2.MulScalar(TauG2, g2.One(), tau_Fr)
  113. return &toxicWaste{tau, TauG2}
  114. }
  115. func computeContribution(t *toxicWaste, prevSRS *SRS) *SRS {
  116. srs := newEmptySRS(len(prevSRS.G1Powers), len(prevSRS.G2Powers))
  117. g1 := bls12381.NewG1()
  118. g2 := bls12381.NewG2()
  119. Q := g1.Q() // Q = |G1| == |G2|
  120. // fmt.Println("Computing [τ'⁰]₁, [τ'¹]₁, [τ'²]₁, ..., [τ'ⁿ⁻¹]₁, for n =", len(prevSRS.G1s))
  121. for i := 0; i < len(prevSRS.G1Powers); i++ {
  122. tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q)
  123. tau_i_Fr := bls12381.NewFr().FromBytes(tau_i.Bytes())
  124. g1.MulScalar(srs.G1Powers[i], prevSRS.G1Powers[i], tau_i_Fr)
  125. }
  126. // fmt.Println("Computing [τ'⁰]₂, [τ'¹]₂, [τ'²]₂, ..., [τ'ⁿ⁻¹]₂, for n =", len(prevSRS.G2s))
  127. for i := 0; i < len(prevSRS.G2Powers); i++ {
  128. tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q)
  129. tau_i_Fr := bls12381.NewFr().FromBytes(tau_i.Bytes())
  130. g2.MulScalar(srs.G2Powers[i], prevSRS.G2Powers[i], tau_i_Fr)
  131. }
  132. return srs
  133. }
  134. func genProof(toxicWaste *toxicWaste, prevSRS, newSRS *SRS) *Proof {
  135. g1 := bls12381.NewG1()
  136. G1_p := g1.New()
  137. tau_Fr := bls12381.NewFr().FromBytes(toxicWaste.tau.Bytes())
  138. g1.MulScalar(G1_p, prevSRS.G1Powers[1], tau_Fr) // g_1^{tau'} = g_1^{p * tau}, where p=toxicWaste.tau
  139. return &Proof{toxicWaste.TauG2, G1_p}
  140. }
  141. // Contribute takes as input the previous SRS and a random
  142. // byte slice, and returns the new SRS together with the Proof
  143. func Contribute(prevSRS *SRS, randomness []byte) (*SRS, *Proof, error) {
  144. if len(randomness) < MinRandomnessLen {
  145. return nil, nil, fmt.Errorf("err randomness") // WIP
  146. }
  147. // set tau from randomness
  148. tw := tau(randomness)
  149. newSRS := computeContribution(tw, prevSRS)
  150. proof := genProof(tw, prevSRS, newSRS)
  151. return newSRS, proof, nil
  152. }
  153. // Verify checks the correct computation of the new SRS respectively from the
  154. // previous SRS
  155. func Verify(prevSRS, newSRS *SRS, proof *Proof) bool {
  156. g1 := bls12381.NewG1()
  157. g2 := bls12381.NewG2()
  158. pairing := bls12381.NewEngine()
  159. // 1. check that elements of the newSRS are valid points
  160. for i := 0; i < len(newSRS.G1Powers); i++ {
  161. // i) non-empty
  162. if newSRS.G1Powers[i] == nil {
  163. return false
  164. }
  165. // ii) non-zero
  166. if g1.IsZero(newSRS.G1Powers[i]) {
  167. return false
  168. }
  169. // iii) in the correct prime order of subgroups
  170. if !g1.IsOnCurve(newSRS.G1Powers[i]) {
  171. return false
  172. }
  173. if !g1.InCorrectSubgroup(newSRS.G1Powers[i]) {
  174. return false
  175. }
  176. }
  177. for i := 0; i < len(newSRS.G2Powers); i++ {
  178. // i) non-empty
  179. if newSRS.G2Powers[i] == nil {
  180. return false
  181. }
  182. // ii) non-zero
  183. if g2.IsZero(newSRS.G2Powers[i]) {
  184. return false
  185. }
  186. // iii) in the correct prime order of subgroups
  187. if !g2.IsOnCurve(newSRS.G2Powers[i]) {
  188. return false
  189. }
  190. if !g2.InCorrectSubgroup(newSRS.G2Powers[i]) {
  191. return false
  192. }
  193. }
  194. // 2. check proof.G1PTau == newSRS.G1Powers[1]
  195. if !g1.Equal(proof.G1PTau, newSRS.G1Powers[1]) {
  196. return false
  197. }
  198. // 3. check newSRS.G1s[1] (g₁^τ'), is correctly related to prevSRS.G1s[1] (g₁^τ)
  199. // e([τ]₁, [p]₂) == e([τ']₁, [1]₂)
  200. eL := pairing.AddPair(prevSRS.G1Powers[1], proof.G2P).Result()
  201. eR := pairing.AddPair(newSRS.G1Powers[1], g2.One()).Result()
  202. if !eL.Equal(eR) {
  203. return false
  204. }
  205. // 4. check newSRS following the powers of tau structure
  206. for i := 0; i < len(newSRS.G1Powers)-1; i++ {
  207. // i) e([τ'ⁱ]₁, [τ']₂) == e([τ'ⁱ⁺¹]₁, [1]₂), for i ∈ [1, n−1]
  208. eL := pairing.AddPair(newSRS.G1Powers[i], newSRS.G2Powers[1]).Result()
  209. eR := pairing.AddPair(newSRS.G1Powers[i+1], g2.One()).Result()
  210. if !eL.Equal(eR) {
  211. return false
  212. }
  213. }
  214. for i := 0; i < len(newSRS.G2Powers)-1; i++ {
  215. // ii) e([τ']₁, [τ'ʲ]₂) == e([1]₁, [τ'ʲ⁺¹]₂), for j ∈ [1, m−1]
  216. eL := pairing.AddPair(newSRS.G1Powers[1], newSRS.G2Powers[i]).Result()
  217. eR := pairing.AddPair(g1.One(), newSRS.G2Powers[i+1]).Result()
  218. if !eL.Equal(eR) {
  219. return false
  220. }
  221. }
  222. return true
  223. }