Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow shares to be created and combined as bytes rather than strings #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions sssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ const (
* share to recreate, of length shares, from the input secret raw as a string
**/
func Create(minimum int, shares int, raw string) ([]string, error) {
return CreateFromBytes(minimum, shares, []byte(raw))
}

/**
* Returns a new arary of secret shares (encoding x,y pairs as base64 strings)
* created by Shamir's Secret Sharing Algorithm requring a minimum number of
* share to recreate, of length shares, from the input secret raw as an array
* bytes
**/
func CreateFromBytes(minimum int, shares int, raw []byte) ([]string, error) {
// Verify minimum isn't greater than shares; there is no way to recreate
// the original polynomial in our current setup, therefore it doesn't make
// sense to generate fewer shares than are needed to reconstruct the secret.
Expand All @@ -28,7 +38,7 @@ func Create(minimum int, shares int, raw string) ([]string, error) {
}

// Convert the secret to its respective 256-bit big.Int representation
var secret []*big.Int = splitByteToInt([]byte(raw))
var secret []*big.Int = splitByteToInt(raw)

// Set constant prime across the package
prime, _ = big.NewInt(0).SetString(DefaultPrimeStr, 10)
Expand Down Expand Up @@ -110,7 +120,7 @@ func Create(minimum int, shares int, raw string) ([]string, error) {
* or more are passed to this function. Passing thus does not affect it
* Passing fewer however, simply means that the returned secret is wrong.
**/
func Combine(shares []string) (string, error) {
func CombineAsBytes(shares []string) ([]byte, error) {
// Recreate the original object of x, y points, based upon number of shares
// and size of each share (number of parts in the secret).
var secrets [][][]*big.Int = make([][][]*big.Int, len(shares))
Expand All @@ -122,7 +132,7 @@ func Combine(shares []string) (string, error) {
for i := range shares {
// ...ensure that it is valid...
if IsValidShare(shares[i]) == false {
return "", ErrOneOfTheSharesIsInvalid
return []byte(""), ErrOneOfTheSharesIsInvalid
}

// ...find the number of parts it represents...
Expand Down Expand Up @@ -183,7 +193,21 @@ func Combine(shares []string) (string, error) {
}

// ...and return the result!
return string(mergeIntToByte(secret)), nil
return mergeIntToByte(secret), nil
}

/**
* Takes a string array of shares encoded in base64 created via Shamir's
* Algorithm; each string must be of equal length of a multiple of 88 characters
* as a single 88 character share is a pair of 256-bit numbers (x, y).
*
* Note: the polynomial will converge if the specified minimum number of shares
* or more are passed to this function. Passing thus does not affect it
* Passing fewer however, simply means that the returned secret is wrong.
**/
func Combine(shares []string) (string, error) {
res, err := CombineAsBytes(shares)
return string(res), err
}

/**
Expand Down
27 changes: 27 additions & 0 deletions sssa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sssa

import (
"testing"
"bytes"
)

func TestCreateCombine(t *testing.T) {
Expand Down Expand Up @@ -30,6 +31,32 @@ func TestCreateCombine(t *testing.T) {
}
}

func TestCreateCombineBytes(t *testing.T) {
// Short, medium, and long tests
testvals := [][]byte{
[]byte("N17FigASkL6p1EOgJhRaIquQLGvYV0"),
[]byte("0y10VAfmyH7GLQY6QccCSLKJi8iFgpcSBTLyYOGbiYPqOpStAf1OYuzEBzZR"),
[]byte("KjRHO1nHmIDidf6fKvsiXWcTqNYo2U9U8juO94EHXVqgearRISTQe0zAjkeUYYBvtcB8VWzZHYm6ktMlhOXXCfRFhbJzBUsXaHb5UDQAvs2GKy6yq0mnp8gCj98ksDlUultqygybYyHvjqR7D7EAWIKPKUVz4of8OzSjZlYg7YtCUMYhwQDryESiYabFID1PKBfKn5WSGgJBIsDw5g2HB2AqC1r3K8GboDN616Swo6qjvSFbseeETCYDB3ikS7uiK67ErIULNqVjf7IKoOaooEhQACmZ5HdWpr34tstg18rO"),
}

minimum := []int{4, 6, 20}
shares := []int{5, 100, 100}

for i := range testvals {
created, err := CreateFromBytes(minimum[i], shares[i], testvals[i])
if err != nil {
t.Fatal("Fatal: creating: ", err)
}
combined, err := CombineAsBytes(created)
if err != nil {
t.Fatal("Fatal: combining: ", err)
}
if !bytes.Equal(combined, testvals[i]) {
t.Fatal("Fatal: combining returned invalid data")
}
}
}

func TestLibraryCombine(t *testing.T) {
shares := []string{
"U1k9koNN67-og3ZY3Mmikeyj4gEFwK4HXDSglM8i_xc=yA3eU4_XYcJP0ijD63Tvqu1gklhBV32tu8cHPZXP-bk=",
Expand Down