Skip to content

Instantly share code, notes, and snippets.

@avary
Forked from salrashid123/main.go
Created July 12, 2023 13:00
Show Gist options
  • Save avary/b6f57cf0ded8283759dc6bd835c9c57f to your computer and use it in GitHub Desktop.
Save avary/b6f57cf0ded8283759dc6bd835c9c57f to your computer and use it in GitHub Desktop.
Threshold key encryption in golang
package main
import (
"encoding/base64"
"flag"
"fmt"
"io/ioutil"
"os"
"go.dedis.ch/kyber/v4/encrypt/ecies"
"go.dedis.ch/kyber/v4/group/edwards25519"
"go.dedis.ch/kyber/v4/share"
)
const ()
// https://pkg.go.dev/go.dedis.ch/[email protected]/examples
var (
t = flag.Int("t", 2, "threshold")
n = flag.Int("n", 3, "total shares")
)
func main() {
flag.Parse()
g := edwards25519.NewBlakeSHA256Ed25519()
priPoly := share.NewPriPoly(g, *t, nil, g.RandomStream())
pubPoly := priPoly.Commit(nil)
pubShares := pubPoly.Shares(*n)
for i, pu := range pubShares {
fmt.Printf("Public Key of %d %s\n", i, pu.V.String())
}
pubbin, err := pubPoly.Commit().MarshalBinary()
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
fmt.Printf("Encoded serialized Public poly %s\n,", base64.StdEncoding.EncodeToString(pubbin))
// ***********************
// write partial keys to file
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 {
fmt.Printf("%v", err)
os.Exit(1)
}
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 {
fmt.Printf("%v", err)
os.Exit(1)
}
_, err = f.Write(pval)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
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 {
fmt.Printf("%v", err)
os.Exit(1)
}
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 {
fmt.Printf("%v", err)
os.Exit(1)
}
_, err = f.Write(pval)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
f.Close()
}
// ********************
// read serialaized keys from file
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 {
fmt.Printf("%v", err)
os.Exit(1)
}
rpv := g.Point()
err = rpv.UnmarshalBinary(puval)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
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 {
fmt.Printf("%v", err)
os.Exit(1)
}
rv := g.Scalar()
err = rv.UnmarshalBinary(pval)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
rr := &share.PriShare{
I: x,
V: rv,
}
ps = append(ps, rr)
//fmt.Printf("Reconstructed PrivShare rr %d : %s\n", x, rr.V.String())
}
pub_recovered, err := share.RecoverCommit(g, pp, *t, *n)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
priv_recovered, err := share.RecoverSecret(g, ps, *t, *n)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
//
message := []byte("Hello ECIES")
ciphertext, err := ecies.Encrypt(g, pub_recovered, message, g.Hash)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
fmt.Printf("Encrypted %s\n", base64.StdEncoding.EncodeToString(ciphertext))
plaintext, err := ecies.Decrypt(g, priv_recovered, ciphertext, g.Hash)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}
fmt.Printf(" Decrypted: %s\n", plaintext)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment