Skip to content

Instantly share code, notes, and snippets.

@avary
Forked from salrashid123/export.go
Created July 12, 2023 13:00
Show Gist options
  • Save avary/3595b45546c69a7ec9b458229c2fe071 to your computer and use it in GitHub Desktop.
Save avary/3595b45546c69a7ec9b458229c2fe071 to your computer and use it in GitHub Desktop.
Threshold key generation and signing with serialization to file
package main
import (
"encoding/base64"
"flag"
"fmt"
"io/ioutil"
"os"
"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"
)
var ()
func main() {
flag.Parse()
// 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
fmt.Printf("Using (t,n): (%d,%d)\n", t, n)
secret := suite.G1().Scalar().Pick(suite.RandomStream())
priPoly := share.NewPriPoly(suite.G2(), t, secret, suite.RandomStream())
pubPoly := priPoly.Commit(suite.G2().Point().Base())
pubbin, err := pubPoly.Commit().MarshalBinary()
if err != nil {
panic(err)
}
pubstr := base64.StdEncoding.EncodeToString(pubbin)
fmt.Printf("Public Key: %s\n", pubstr)
sigShares := make([][]byte, 0)
/// create key share and write to files
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(" Public Key Share Index: %d\n", ival)
fmt.Printf(" Public Key Share: %s\n", base64.StdEncoding.EncodeToString(pval))
f, err := os.Create(fmt.Sprintf("%d.pub", i))
if err != nil {
panic(err)
}
_, err = f.Write(pval)
if err != nil {
panic(err)
}
f.Close()
}
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(" Private Key Share Index: %d\n", ival)
fmt.Printf(" Private Key Share: %s\n", base64.StdEncoding.EncodeToString(pval))
f, err := os.Create(fmt.Sprintf("%d.priv", i))
if err != nil {
panic(err)
}
_, err = f.Write(pval)
if err != nil {
panic(err)
}
f.Close()
}
// load keys from files
priv_keys_index := []int{0, 1}
pub_keys_index := []int{0, 2}
ps := []*share.PriShare{}
pp := []*share.PubShare{}
for _, x := range pub_keys_index {
puval, err := ioutil.ReadFile(fmt.Sprintf("%d.pub", x))
if err != nil {
panic(err)
}
rpv := suite.G2().Point()
err = rpv.UnmarshalBinary(puval)
if err != nil {
panic(err)
}
rpr := &share.PubShare{
I: x,
V: rpv,
}
pp = append(pp, rpr)
}
for _, x := range priv_keys_index {
pval, err := ioutil.ReadFile(fmt.Sprintf("%d.priv", x))
if err != nil {
panic(err)
}
rv := suite.G2().Scalar()
err = rv.UnmarshalBinary(pval)
if err != nil {
panic(err)
}
rr := &share.PriShare{
I: x,
V: rv,
}
ps = append(ps, rr)
//fmt.Printf("Reconstructed PrivShare rr %d : %s\n", x, rr.V.String())
}
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)
}
fmt.Printf("Partial Signatures:\n")
for _, x := range sigShares {
fmt.Printf(" %s\n", base64.StdEncoding.EncodeToString(x))
}
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)
}
fmt.Printf("Signature from key index %v %s\n", priv_keys_index, base64.StdEncoding.EncodeToString(sig))
err = bls.Verify(suite, rps.Commit(), msg, sig)
if err != nil {
panic(err)
}
fmt.Printf("Signature Verified using Partial Public Keys from index %v\n", pub_keys_index)
b := suite.G2().Point()
pbin, err := base64.StdEncoding.DecodeString(pubstr)
if err != nil {
panic(err)
}
err = b.UnmarshalBinary(pbin)
if err != nil {
panic(err)
}
err = bls.Verify(suite, b, msg, sig)
if err != nil {
panic(err)
}
fmt.Println("Signature Verified From Full Public")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment