add cli tool instead of examples

This commit is contained in:
saepire 2024-07-29 22:03:46 +09:00
parent 80c4d9b00c
commit 5a6885c27f
5 changed files with 96 additions and 75 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
./cmd/sss/sss

View File

@ -33,17 +33,23 @@ func main() {
}
```
Also see the two example programs in the `example` directory:
Install `cmd/sss` to use the command line interface:
go install github.com/kyodo-tech/shamir/cmd/sss@latest
Then run `sss` to split a secret into shares and combine them to reconstruct the secret:
```sh
go run example/split.go "my secret"
Usage: sss -mode=split -secret=<secret> -n=<number of shares> -T=<threshold>
# Example:
sss -secret "my secret"
# Output:
# Share 0: lK8LyefHjxzOAQ==
# Share 1: 1Ws3IGJh/lVQAg==
# Share 2: LL0cmuDFAyzqAw==
# Share 3: Wf8RJQs43iALBA==
# Share 4: oCk6n4mcI1mxBQ==
go run ./example/combine.go lK8LyefHjxzOAQ==,LL0cmuDFAyzqAw==,oCk6n4mcI1mxBQ==
# N8QLmd6YcLu2AQ==
# Nnubhbvx52y8Ag==
# bMawbwAK5bJ+Aw==
# SurUYDi7Mfm4BA==
# EFf/ioNAMyd6BQ==
sss -mode combine -shares N8QLmd6YcLu2AQ==,bMawbwAK5bJ+Aw==,EFf/ioNAMyd6BQ==
# Output:
# Reconstructed secret: my secret
# my secret
```

80
cmd/sss/main.go Normal file
View File

@ -0,0 +1,80 @@
package main
import (
"bufio"
"encoding/base64"
"flag"
"fmt"
"os"
"strings"
"github.com/kyodo-tech/shamir"
)
func main() {
mode := flag.String("mode", "split", "Mode: split or combine")
secret := flag.String("secret", "", "The secret to split (for split mode)")
sharesStr := flag.String("shares", "", "Comma-separated shares (for combine mode)")
N := flag.Int("n", 5, "Total number of shares")
T := flag.Int("t", 3, "Number of shares needed to reconstruct the secret")
flag.Parse()
switch *mode {
case "split":
if *secret == "" {
reader := bufio.NewReader(os.Stdin)
inputSecret, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading input:", err)
os.Exit(1)
}
inputSecret = strings.TrimSpace(inputSecret)
splitSecret(inputSecret, *N, *T)
} else {
splitSecret(*secret, *N, *T)
}
case "combine":
if *sharesStr == "" {
fmt.Println("Usage: go run main.go -mode=combine -shares=<share1>,<share2>,...,<shareN>")
os.Exit(1)
}
combineShares(*sharesStr)
default:
fmt.Println("Invalid mode. Use -mode=split or -mode=combine")
os.Exit(1)
}
}
func splitSecret(secret string, totalShares, T int) {
secretBytes := []byte(secret)
shares, err := shamir.Split(secretBytes, totalShares, T)
if err != nil {
panic(err)
}
// Print share strings
for _, share := range shares {
fmt.Println(base64.StdEncoding.EncodeToString(share))
}
}
func combineShares(sharesStr string) {
shareStrs := strings.Split(sharesStr, ",")
var shares [][]byte
for _, shareStr := range shareStrs {
share, err := base64.StdEncoding.DecodeString(shareStr)
if err != nil {
panic(err)
}
shares = append(shares, share)
}
reconstructed, err := shamir.Combine(shares)
if err != nil {
panic(err)
}
fmt.Println(reconstructed)
}

View File

@ -1,39 +0,0 @@
package main
import (
"encoding/base64"
"fmt"
"os"
"strings"
"github.com/kyodo-tech/shamir"
)
func main() {
// read comma separated shares from command line
if len(os.Args) != 2 {
fmt.Println("Usage: go run main.go <share1>,<share2>,...,<shareN>")
os.Exit(1)
}
// split shares
sharesStr := strings.Split(os.Args[1], ",")
var shares [][]byte
for _, shareStr := range sharesStr {
share, err := base64.StdEncoding.DecodeString(shareStr)
if err != nil {
panic(err)
}
shares = append(shares, share)
}
// Use any 3 out of 5 shares to reconstruct the secret
reconstructed, err := shamir.Combine(shares[:3])
if err != nil {
panic(err)
}
fmt.Printf("Reconstructed secret: %s\n", reconstructed)
}

View File

@ -1,27 +0,0 @@
package main
import (
"encoding/base64"
"fmt"
"os"
"github.com/kyodo-tech/shamir"
)
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: go run main.go <secret>")
os.Exit(1)
}
secret := []byte(os.Args[1])
shares, err := shamir.Split(secret, 5, 3)
if err != nil {
panic(err)
}
// print share strings
for i, share := range shares {
fmt.Printf("Share %d: %s\n", i, base64.StdEncoding.EncodeToString(share))
}
}