diff --git a/README.md b/README.md new file mode 100644 index 0000000..3cc1c9f --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# Shamir Secret Sharing [![Go Report Card](https://goreportcard.com/badge/github.com/arnaucube/shamirsecretsharing)](https://goreportcard.com/report/github.com/arnaucube/shamirsecretsharing) [![GoDoc](https://godoc.org/github.com/arnaucube/shamirsecretsharing?status.svg)](https://godoc.org/github.com/arnaucube/shamirsecretsharing) +This repo contains a Go lang implementation of Shamir Secret Sharing, and a compiled Web Assembly version from the Go code to be used from the browser. + +- https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing + +## Wasm usage +Compile to wasm, inside the `wasm` directory, execute: +``` +GOARCH=wasm GOOS=js go build -o shamirsecretsharing.wasm shamirsecretsharing-wasm-wrapper.go +``` + +Add the file `wasm_exec.js` in the directory: +``` +cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" . +``` + +Call the library from javascript: +```js +// Create shares from a secret +// nNeededShares: number of secrets needed +// nShares: number of shares +// p: random point +// k: secret to share +createShares(nNeededShares, nShares, p, k); +``` + +## Usage from Go +```go +// define secret to share +k, ok := new(big.Int).SetString("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 10) +assert.True(t, ok) + +// define random prime +p, err := rand.Prime(rand.Reader, bits/2) +assert.Nil(t, err) + +// define how many shares want to generate +nShares := big.NewInt(int64(6)) + +// define how many shares are needed to recover the secret +nNeededShares := big.NewInt(int64(3)) + +// create the shares +shares, err := Create( + nNeededShares, + nShares, + p, + big.NewInt(int64(k))) +assert.Nil(t, err) + +// select shares to use +var sharesToUse [][]*big.Int +sharesToUse = append(sharesToUse, shares[2]) +sharesToUse = append(sharesToUse, shares[1]) +sharesToUse = append(sharesToUse, shares[0]) + +// recover the secret using Lagrange Interpolation +secr := LagrangeInterpolation(sharesToUse, p) + +// check that the restored secret matches the original secret +if !bytes.Equal(k.Bytes(), secr.Bytes()) { + fmt.Println("reconstructed secret not correspond to original secret") +} +``` diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3ba2382 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/arnaucube/shamirsecretsharing + +go 1.12 + +require github.com/stretchr/testify v1.3.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4347755 --- /dev/null +++ b/go.sum @@ -0,0 +1,7 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/wasm/shamirsecretsharing-wasm-wrapper.go b/wasm/shamirsecretsharing-wasm-wrapper.go new file mode 100644 index 0000000..53d3b70 --- /dev/null +++ b/wasm/shamirsecretsharing-wasm-wrapper.go @@ -0,0 +1,49 @@ +package main + +import ( + "math/big" + "syscall/js" + + "github.com/arnaucube/shamirsecretsharing" +) + +func main() { + c := make(chan struct{}, 0) + + println("WASM Go Initialized") + // register functions + registerCallbacks() + <-c +} + +func registerCallbacks() { + js.Global().Set("createShares", js.ValueOf(createShares)) + js.Global().Set("lagrangeInterpolation", js.ValueOf(lagrangeInterpolation)) +} + +func createShares(i []js.Value) { + nNeededShares, ok := new(big.Int).SetString(i[0].String(), 10) + if !ok { + println("error parsing parameter in position 0") + } + nShares, ok := new(big.Int).SetString(i[1].String(), 10) + if !ok { + println("error parsing parameter in position 1") + } + p, ok := new(big.Int).SetString(i[2].String(), 10) + if !ok { + println("error parsing parameter in position 2") + } + k, ok := new(big.Int).SetString(i[3].String(), 10) + if !ok { + println("error parsing parameter in position 3") + } + shares, err := shamirsecretsharing.Create(nNeededShares, nShares, p, k) + if err != nil { + println("error generating the shares") + } + println(shares) +} + +func lagrangeInterpolation(i []js.Value) { +} diff --git a/wasm/shamirsecretsharing.wasm b/wasm/shamirsecretsharing.wasm new file mode 100755 index 0000000..41dd833 Binary files /dev/null and b/wasm/shamirsecretsharing.wasm differ