@ -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") |
||||
|
} |
||||
|
``` |
@ -0,0 +1,5 @@ |
|||||
|
module github.com/arnaucube/shamirsecretsharing |
||||
|
|
||||
|
go 1.12 |
||||
|
|
||||
|
require github.com/stretchr/testify v1.3.0 |
@ -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= |
@ -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) { |
||||
|
} |