eth-kzg-ceremony-alt/powersoftau.go
powersoftau.goRaw
1package kzgceremony
2
3import (
4 "fmt"
5 "math/big"
6
7 "github.com/ethereum/go-ethereum/crypto/bls12381"
8)
9
10type Contribution struct {
11 SRS *SRS
12 Proof *Proof
13}
14
15type SRS struct {
16 G1s []*bls12381.PointG1
17 G2s []*bls12381.PointG2
18}
19
20type toxicWaste struct {
21 tau *big.Int
22 TauG2 *bls12381.PointG2
23}
24
25type Proof struct {
26 G2P *bls12381.PointG2 // g₂ᵖ
27 G1PTau *bls12381.PointG1 // g₂^τ' = g₂^{p ⋅ τ}
28}
29
30// newEmptySRS creates an empty SRS
31func newEmptySRS(nG1, nG2 int) *SRS {
32 g1s := make([]*bls12381.PointG1, nG1)
33 g2s := make([]*bls12381.PointG2, nG2)
34 g1 := bls12381.NewG1()
35 g2 := bls12381.NewG2()
36 // one_G1 := g1.One()
37 // one_G2 := g2.One()
38 for i := 0; i < nG1; i++ {
39 g1s[i] = g1.One()
40 // g1.MulScalar(g1s[i], one_G1, big.NewInt(int64(i)))
41 }
42 for i := 0; i < nG2; i++ {
43 g2s[i] = g2.One()
44 // g2.MulScalar(g2s[i], one_G2, big.NewInt(int64(i)))
45 }
46 return &SRS{g1s, g2s}
47}
48
49func tau(randomness []byte) *toxicWaste {
50 g2 := bls12381.NewG2()
51 tau := new(big.Int).Mod(
52 new(big.Int).SetBytes(randomness),
53 g2.Q())
54 TauG2 := g2.New()
55 g2.MulScalar(TauG2, g2.One(), tau)
56
57 return &toxicWaste{tau, TauG2}
58}
59
60func computeContribution(t *toxicWaste, prevSRS *SRS) *SRS {
61 srs := newEmptySRS(len(prevSRS.G1s), len(prevSRS.G2s))
62 g1 := bls12381.NewG1()
63 g2 := bls12381.NewG2()
64 Q := g1.Q() // Q = |G1| == |G2|
65
66 fmt.Println("Computing [τ'⁰]₁, [τ'¹]₁, [τ'²]₁, ..., [τ'ⁿ⁻¹]₁, for n =", len(prevSRS.G1s))
67 for i := 0; i < len(prevSRS.G1s); i++ {
68 tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q)
69 g1.MulScalar(srs.G1s[i], prevSRS.G1s[i], tau_i)
70 }
71 fmt.Println("Computing [τ'⁰]₂, [τ'¹]₂, [τ'²]₂, ..., [τ'ⁿ⁻¹]₂, for n =", len(prevSRS.G2s))
72 for i := 0; i < len(prevSRS.G2s); i++ {
73 tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q)
74 g2.MulScalar(srs.G2s[i], prevSRS.G2s[i], tau_i)
75 }
76
77 return srs
78}
79
80func genProof(toxicWaste *toxicWaste, prevSRS, newSRS *SRS) *Proof {
81 g1 := bls12381.NewG1()
82 G1_p := g1.New()
83 g1.MulScalar(G1_p, prevSRS.G1s[1], toxicWaste.tau) // g_1^{tau'} = g_1^{p * tau}, where p=toxicWaste.tau
84
85 return &Proof{toxicWaste.TauG2, G1_p}
86}
87
88// Contribute
89func Contribute(prevSRS *SRS, randomness []byte) (Contribution, error) {
90 // set tau from randomness
91 tw := tau(randomness)
92
93 newSRS := computeContribution(tw, prevSRS)
94
95 proof := genProof(tw, prevSRS, newSRS)
96
97 return Contribution{SRS: newSRS, Proof: proof}, nil
98}
99
100func Verify(prevSRS, newSRS *SRS, proof *Proof) bool {
101 g1 := bls12381.NewG1()
102
103 // check proof.G1PTau == newSRS.G1s[1]
104 if !g1.Equal(proof.G1PTau, newSRS.G1s[1]) {
105 return false
106 }
107
108 // WIP!
109 return true
110}