package kzgceremony import ( "math/big" "github.com/ethereum/go-ethereum/crypto/bls12381" ) type Contribution struct { SRS *SRS } type SRS struct { G1s []*bls12381.PointG1 G2s []*bls12381.PointG2 } type toxicWaste struct { tau *big.Int TauG2 *bls12381.PointG2 } // newEmptySRS creates an empty SRS func newEmptySRS(nG1, nG2 int) *SRS { g1s := make([]*bls12381.PointG1, nG1) g2s := make([]*bls12381.PointG2, nG2) g1 := bls12381.NewG1() g2 := bls12381.NewG2() // one_G1 := g1.One() // one_G2 := g2.One() for i := 0; i < nG1; i++ { g1s[i] = g1.One() // g1.MulScalar(g1s[i], one_G1, big.NewInt(int64(i))) } for i := 0; i < nG2; i++ { g2s[i] = g2.One() // g2.MulScalar(g2s[i], one_G2, big.NewInt(int64(i))) } return &SRS{g1s, g2s} } func tau(randomness []byte) *toxicWaste { g2 := bls12381.NewG2() tau := new(big.Int).Mod( new(big.Int).SetBytes(randomness), g2.Q()) TauG2 := g2.New() g2.MulScalar(TauG2, g2.One(), tau) return &toxicWaste{tau, TauG2} } func computeContribution(t *toxicWaste, prevSRS *SRS) *SRS { srs := newEmptySRS(len(prevSRS.G1s), len(prevSRS.G2s)) g1 := bls12381.NewG1() g2 := bls12381.NewG2() Q := g1.Q() // Q = |G1| == |G2| for i := 0; i < len(prevSRS.G1s); i++ { tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q) g1.MulScalar(srs.G1s[i], prevSRS.G1s[i], tau_i) } for i := 0; i < len(prevSRS.G2s); i++ { tau_i := new(big.Int).Exp(t.tau, big.NewInt(int64(i)), Q) g2.MulScalar(srs.G2s[i], prevSRS.G2s[i], tau_i) } return srs } // Contribute func Contribute(prevSRS *SRS, randomness []byte) (Contribution, error) { // set tau from randomness tw := tau(randomness) newSRS := computeContribution(tw, prevSRS) return Contribution{SRS: newSRS}, nil }