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.

187 lines
5.0 KiB

  1. package kzgceremony
  2. import (
  3. "math/big"
  4. bls12381 "github.com/kilic/bls12-381"
  5. )
  6. // todo: unify addition & multiplicative notation in the comments
  7. // Contribution contains the SRS with its Proof
  8. type Contribution struct {
  9. SRS *SRS
  10. Proof *Proof
  11. }
  12. // SRS contains the powers of tau in G1 & G2, eg.
  13. // [τ'⁰]₁, [τ'¹]₁, [τ'²]₁, ..., [τ'ⁿ⁻¹]₁,
  14. // [τ'⁰]₂, [τ'¹]₂, [τ'²]₂, ..., [τ'ⁿ⁻¹]₂
  15. type SRS struct {
  16. G1s []*bls12381.PointG1
  17. G2s []*bls12381.PointG2
  18. }
  19. type toxicWaste struct {
  20. tau *big.Int
  21. TauG2 *bls12381.PointG2
  22. }
  23. // Proof contains g₂ᵖ and g₂^τ', used by the verifier
  24. type Proof struct {
  25. G2P *bls12381.PointG2 // g₂ᵖ
  26. G1PTau *bls12381.PointG1 // g₂^τ' = g₂^{p ⋅ τ}
  27. }
  28. // newEmptySRS creates an empty SRS
  29. func newEmptySRS(nG1, nG2 int) *SRS {
  30. g1s := make([]*bls12381.PointG1, nG1)
  31. g2s := make([]*bls12381.PointG2, nG2)
  32. g1 := bls12381.NewG1()
  33. g2 := bls12381.NewG2()
  34. // one_G1 := g1.One()
  35. // one_G2 := g2.One()
  36. for i := 0; i < nG1; i++ {
  37. g1s[i] = g1.One()
  38. // g1.MulScalar(g1s[i], one_G1, big.NewInt(int64(i)))
  39. }
  40. for i := 0; i < nG2; i++ {
  41. g2s[i] = g2.One()
  42. // g2.MulScalar(g2s[i], one_G2, big.NewInt(int64(i)))
  43. }
  44. return &SRS{g1s, g2s}
  45. }
  46. func tau(randomness []byte) *toxicWaste {
  47. g2 := bls12381.NewG2()
  48. tau := new(big.Int).Mod(
  49. new(big.Int).SetBytes(randomness),
  50. g2.Q())
  51. tau_Fr := bls12381.NewFr().FromBytes(tau.Bytes())
  52. TauG2 := g2.New()
  53. g2.MulScalar(TauG2, g2.One(), tau_Fr)
  54. return &toxicWaste{tau, TauG2}
  55. }
  56. func computeContribution(t *toxicWaste, prevSRS *SRS) *SRS {
  57. srs := newEmptySRS(len(prevSRS.G1s), len(prevSRS.G2s))
  58. g1 := bls12381.NewG1()
  59. g2 := bls12381.NewG2()
  60. Q := g1.Q() // Q = |G1| == |G2|
  61. // fmt.Println("Computing [τ'⁰]₁, [τ'¹]₁, [τ'²]₁, ..., [τ'ⁿ⁻¹]₁, for n =", len(prevSRS.G1s))
  62. for i := 0; i < len(prevSRS.G1s); i++ {
  63. tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q)
  64. tau_i_Fr := bls12381.NewFr().FromBytes(tau_i.Bytes())
  65. g1.MulScalar(srs.G1s[i], prevSRS.G1s[i], tau_i_Fr)
  66. }
  67. // fmt.Println("Computing [τ'⁰]₂, [τ'¹]₂, [τ'²]₂, ..., [τ'ⁿ⁻¹]₂, for n =", len(prevSRS.G2s))
  68. for i := 0; i < len(prevSRS.G2s); i++ {
  69. tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q)
  70. tau_i_Fr := bls12381.NewFr().FromBytes(tau_i.Bytes())
  71. g2.MulScalar(srs.G2s[i], prevSRS.G2s[i], tau_i_Fr)
  72. }
  73. return srs
  74. }
  75. func genProof(toxicWaste *toxicWaste, prevSRS, newSRS *SRS) *Proof {
  76. g1 := bls12381.NewG1()
  77. G1_p := g1.New()
  78. tau_Fr := bls12381.NewFr().FromBytes(toxicWaste.tau.Bytes())
  79. g1.MulScalar(G1_p, prevSRS.G1s[1], tau_Fr) // g_1^{tau'} = g_1^{p * tau}, where p=toxicWaste.tau
  80. return &Proof{toxicWaste.TauG2, G1_p}
  81. }
  82. // Contribute takes as input the previous SRS and a random byte slice, and
  83. // returns the new SRS together with the Proof
  84. func Contribute(prevSRS *SRS, randomness []byte) (Contribution, error) {
  85. // set tau from randomness
  86. tw := tau(randomness)
  87. newSRS := computeContribution(tw, prevSRS)
  88. proof := genProof(tw, prevSRS, newSRS)
  89. return Contribution{SRS: newSRS, Proof: proof}, nil
  90. }
  91. // Verify checks the correct computation of the new SRS respectively from the
  92. // previous SRS
  93. func Verify(prevSRS, newSRS *SRS, proof *Proof) bool {
  94. g1 := bls12381.NewG1()
  95. g2 := bls12381.NewG2()
  96. pairing := bls12381.NewEngine()
  97. // 1. check that elements of the newSRS are valid points
  98. for i := 0; i < len(newSRS.G1s); i++ {
  99. // i) non-empty
  100. if newSRS.G1s[i] == nil {
  101. return false
  102. }
  103. // ii) non-zero
  104. if g1.IsZero(newSRS.G1s[i]) {
  105. return false
  106. }
  107. // iii) in the correct prime order of subgroups
  108. if !g1.IsOnCurve(newSRS.G1s[i]) {
  109. return false
  110. }
  111. if !g1.InCorrectSubgroup(newSRS.G1s[i]) {
  112. return false
  113. }
  114. }
  115. for i := 0; i < len(newSRS.G2s); i++ {
  116. // i) non-empty
  117. if newSRS.G2s[i] == nil {
  118. return false
  119. }
  120. // ii) non-zero
  121. if g2.IsZero(newSRS.G2s[i]) {
  122. return false
  123. }
  124. // iii) in the correct prime order of subgroups
  125. if !g2.IsOnCurve(newSRS.G2s[i]) {
  126. return false
  127. }
  128. if !g2.InCorrectSubgroup(newSRS.G2s[i]) {
  129. return false
  130. }
  131. }
  132. // 2. check proof.G1PTau == newSRS.G1s[1]
  133. if !g1.Equal(proof.G1PTau, newSRS.G1s[1]) {
  134. return false
  135. }
  136. // 3. check newSRS.G1s[1] (g₁^τ'), is correctly related to prevSRS.G1s[1] (g₁^τ)
  137. // e([τ]₁, [p]₂) == e([τ']₁, [1]₂)
  138. e0 := pairing.AddPair(prevSRS.G1s[1], proof.G2P).Result()
  139. e1 := pairing.AddPair(newSRS.G1s[1], g2.One()).Result()
  140. if !e0.Equal(e1) {
  141. return false
  142. }
  143. // 4. check newSRS following the powers of tau structure
  144. for i := 0; i < len(newSRS.G1s)-1; i++ {
  145. // i) e([τ'ⁱ]₁, [τ']₂) == e([τ'ⁱ⁺¹]₁, [1]₂), for i ∈ [1, n−1]
  146. e0 := pairing.AddPair(newSRS.G1s[i], newSRS.G2s[1]).Result()
  147. e1 := pairing.AddPair(newSRS.G1s[i+1], g2.One()).Result()
  148. if !e0.Equal(e1) {
  149. return false
  150. }
  151. }
  152. for i := 0; i < len(newSRS.G2s)-1; i++ {
  153. // ii) e([τ']₁, [τ'ʲ]₂) == e([1]₁, [τ'ʲ⁺¹]₂), for j ∈ [1, m−1]
  154. e3 := pairing.AddPair(newSRS.G1s[1], newSRS.G2s[i]).Result()
  155. e4 := pairing.AddPair(g1.One(), newSRS.G2s[i+1]).Result()
  156. if !e3.Equal(e4) {
  157. return false
  158. }
  159. }
  160. return true
  161. }