Skip to content

Instantly share code, notes, and snippets.

@salrashid123
Last active May 6, 2024 18:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save salrashid123/d416e2cae8489397a889dd1c7e35c04c to your computer and use it in GitHub Desktop.
Save salrashid123/d416e2cae8489397a889dd1c7e35c04c to your computer and use it in GitHub Desktop.
Threshold Signatures in Golang
package main
import (
"encoding/base64"
"fmt"
"go.dedis.ch/kyber/v3/pairing/bn256"
"go.dedis.ch/kyber/v3/share"
"go.dedis.ch/kyber/v3/sign/bls"
"go.dedis.ch/kyber/v3/sign/tbls"
"go.dedis.ch/kyber/v3/util/random"
)
func main() {
// Test key aggregation
msg := []byte("Hello Boneh-Lynn-Shacham")
suite := bn256.NewSuite()
private1, public1 := bls.NewKeyPair(suite, random.New())
fmt.Printf("Public Key1 %s\n", public1.String())
private2, public2 := bls.NewKeyPair(suite, random.New())
fmt.Printf("Public Key2 %s\n", public2.String())
sig1, err := bls.Sign(suite, private1, msg)
if err != nil {
panic(err)
}
fmt.Printf("Signature from Key1 %s\n", base64.StdEncoding.EncodeToString(sig1))
sig2, err := bls.Sign(suite, private2, msg)
if err != nil {
panic(err)
}
fmt.Printf("Signature from Key2 %s\n", base64.StdEncoding.EncodeToString(sig2))
aggregatedSig, err := bls.AggregateSignatures(suite, sig1, sig2)
if err != nil {
panic(err)
}
fmt.Printf("Aggregated Signature : %s\n", base64.StdEncoding.EncodeToString(aggregatedSig))
aggregatedKey := bls.AggregatePublicKeys(suite, public1, public2)
fmt.Printf("Aggregated Public Key : %s\n", aggregatedKey.String())
err = bls.Verify(suite, aggregatedKey, msg, aggregatedSig)
if err != nil {
panic(err)
}
fmt.Println("Verified")
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
// test threshold key Threshold signing
msg = []byte("Hello threshold Boneh-Lynn-Shacham")
suite = bn256.NewSuite()
n := 3 // alice bob carols
t := 2 // atleast 2 of three
secret := suite.G1().Scalar().Pick(suite.RandomStream())
priPoly := share.NewPriPoly(suite.G2(), t, secret, suite.RandomStream())
pubPoly := priPoly.Commit(suite.G2().Point().Base())
sigShares := make([][]byte, 0)
for i, x := range priPoly.Shares(n) {
sig, err := tbls.Sign(suite, x, msg)
if err != nil {
panic(err)
}
fmt.Printf("Share %d: %x\n", x, sig)
sigShares = append(sigShares, sig)
if i+1 == t {
fmt.Printf("threshold reached; no more keys required to sign \n")
break
}
}
sig, err := tbls.Recover(suite, pubPoly, msg, sigShares, t, n)
if err != nil {
panic(err)
}
err = bls.Verify(suite, pubPoly.Commit(), msg, sig)
if err != nil {
panic(err)
}
fmt.Println("Verified")
// the following marshalls and unmarshalls the keys
// pp := []*share.PubShare{}
// for i, x := range pubPoly.Shares(n) {
// fmt.Printf("PubShare x %d : %s\n", i, x.V.String())
// ival := x.I
// pval, err := x.V.MarshalBinary()
// if err != nil {
// panic(err)
// }
// fmt.Printf("I: %d\n", ival)
// fmt.Printf("V: %s\n", base64.StdEncoding.EncodeToString(pval))
// rv := suite.G2().Point()
// err = rv.UnmarshalBinary(pval)
// if err != nil {
// panic(err)
// }
// rr := &share.PubShare{
// I: ival,
// V: rv,
// }
// pp = append(pp, rr)
// if i+1 == t {
// fmt.Printf("threshold reached; no more public keys required \n")
// break
// }
// }
// ps := []*share.PriShare{}
// for i, x := range priPoly.Shares(n) {
// fmt.Printf("PriShare %d : %s\n", i, x.String())
// ival := x.I
// pval, err := x.V.MarshalBinary()
// if err != nil {
// panic(err)
// }
// fmt.Printf("I: %d\n", ival)
// fmt.Printf("V: %s\n", base64.StdEncoding.EncodeToString(pval))
// rv := suite.G2().Scalar()
// err = rv.UnmarshalBinary(pval)
// if err != nil {
// panic(err)
// }
// rr := &share.PriShare{
// I: ival,
// V: rv,
// }
// ps = append(ps, rr)
// fmt.Printf("Reconstructed PrivShare rr %d : %s\n", i, rr.V.String())
// if i+1 == t {
// fmt.Printf("threshold reached; no more private keys required \n")
// break
// }
// }
// // note, len(ps)=len(pp) =2 (we only have two of the three keys to sign and verify with)
// for _, x := range ps {
// sig, err := tbls.Sign(suite, x, msg)
// if err != nil {
// panic(err)
// }
// fmt.Printf("Share %d: %x\n", x, sig)
// sigShares = append(sigShares, sig)
// }
// rps, err := share.RecoverPubPoly(suite.G2(), pp, t, n)
// if err != nil {
// panic(err)
// }
// sig, err := tbls.Recover(suite, rps, msg, sigShares, t, n)
// if err != nil {
// panic(err)
// }
// err = bls.Verify(suite, rps.Commit(), msg, sig)
// if err != nil {
// panic(err)
// }
// fmt.Println("Verified")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment