@ -0,0 +1,17 @@ |
|||||
|
module kzgceremony |
||||
|
|
||||
|
go 1.19 |
||||
|
|
||||
|
require ( |
||||
|
github.com/ethereum/go-ethereum v1.10.26 |
||||
|
github.com/frankban/quicktest v1.14.4 |
||||
|
) |
||||
|
|
||||
|
require ( |
||||
|
github.com/google/go-cmp v0.5.9 // indirect |
||||
|
github.com/kr/pretty v0.3.1 // indirect |
||||
|
github.com/kr/text v0.2.0 // indirect |
||||
|
github.com/rogpeppe/go-internal v1.9.0 // indirect |
||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect |
||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect |
||||
|
) |
@ -0,0 +1,18 @@ |
|||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= |
||||
|
github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqBmytw72s= |
||||
|
github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= |
||||
|
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= |
||||
|
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= |
||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= |
||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= |
||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= |
||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= |
||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= |
||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= |
||||
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= |
||||
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= |
||||
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= |
||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= |
||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= |
||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= |
||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
@ -0,0 +1,79 @@ |
|||||
|
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 |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
package kzgceremony |
||||
|
|
||||
|
import ( |
||||
|
"testing" |
||||
|
|
||||
|
qt "github.com/frankban/quicktest" |
||||
|
) |
||||
|
|
||||
|
func TestContribute(t *testing.T) { |
||||
|
c := qt.New(t) |
||||
|
|
||||
|
srs_0 := newEmptySRS(10, 10) |
||||
|
|
||||
|
contr_1, err := Contribute(srs_0, []byte("1111111111111111111111111111111111111111111111111111111111111111")) |
||||
|
c.Assert(err, qt.IsNil) |
||||
|
|
||||
|
_, err = Contribute(contr_1.SRS, []byte("2222222222222222222222222222222222222222222222222222222222222222")) |
||||
|
c.Assert(err, qt.IsNil) |
||||
|
} |