Skip to content

Instantly share code, notes, and snippets.

@salrashid123
Last active July 12, 2023 13:00
Show Gist options
  • Save salrashid123/a871efff662a047257879ce7bffb9f13 to your computer and use it in GitHub Desktop.
Save salrashid123/a871efff662a047257879ce7bffb9f13 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/kyber@v0.0.0-20190125094535-ffb719103651/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)
}
@salrashid123
Copy link
Author

$ go run main.go 
Public Key of 0 b31e4464821364beac647cda1c66471aec6835d05fe8458defee29b6b38a52fe
Public Key of 1 75c948b3f66a3cb3091d13250e40dac42a52937d3a4dd35c147edee9aa200ffd
Public Key of 2 0654cb99d91e9907fa511c5fed69af54177f71a74289c0a1cd36ee3387ac7f85
Encoded serialized Public poly l4J/zXRdgRPaiTYc8LtMo1VIHjr45u8gDfebQZeIKLU=
,  Public Key Share Index: 0
  Public Key Share: sx5EZIITZL6sZHzaHGZHGuxoNdBf6EWN7+4ptrOKUv4=
  Public Key Share Index: 1
  Public Key Share: dclIs/ZqPLMJHRMlDkDaxCpSk306TdNcFH7e6aogD/0=
  Public Key Share Index: 2
  Public Key Share: BlTLmdkemQf6URxf7WmvVBd/cadCicChzTbuM4esf4U=
  Private Key Share Index: 0
  Private Key Share: Pu9xKL1gWGPEztsgaL7CbBMicMBcGCicw0El8l1RKAw=
  Private Key Share Index: 1
  Private Key Share: 5H9tgvcEET/kBSXXqRcgkoSwBzTzgo4MMTdPMwicEQs=
  Private Key Share Index: 2
  Private Key Share: ihBp3DGpyRoEPW6N63B9t/U+n6eJ7fR8nix5dLLm+gk=
    Recovered Commit:  97827fcd745d8113da89361cf0bb4ca355481e3af8e6ef200df79b41978828b5
    Recovered polyRecovered Commit:  97827fcd745d8113da89361cf0bb4ca355481e3af8e6ef200df79b41978828b5
    Recovered Secret:  985e76ce82bc9f87a497926a26656547a293d84cc6adc12b564cfbb0b3063f0d
Encrypted y2lLr1TnR1VGq7tRQTUPDNPXVXz9p4EjL/I4qTdmh7WGx/eeuvew5Wy3+3Hjn0NZut95QyNuf3NA1EI=
    Decrypted:  Hello ECIES

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment