-
-
Save avary/b6f57cf0ded8283759dc6bd835c9c57f to your computer and use it in GitHub Desktop.
Threshold key encryption in golang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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