Last active
July 12, 2023 13:00
-
-
Save salrashid123/a871efff662a047257879ce7bffb9f13 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) | |
} |
Author
salrashid123
commented
Jan 18, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment