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

Golint #5

Open
wants to merge 6 commits 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
4 changes: 4 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
image: golang:latest

before_script:
- go get -u github.com/golang/lint/golint

tests:
script:
- golint
- go test
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,20 @@ go:
- 1.4
- 1.5
- tip
matrix:
fast_finish: true
before_install:
- go get golang.org/x/tools/cmd/vet
- go get golang.org/x/tools/cmd/cover
- go get github.com/golang/lint/golint
- go get github.com/mattn/goveralls
install:
- go get -d -v ./... && go build -v ./...
script:
- go vet -x ./...
- $HOME/gopath/bin/golint ./...
- go test -v ./...
- go test -covermode=count -coverprofile=profile.cov .

after_script:
- $HOME/gopath/bin/goveralls -coverprofile=profile.cov -service=travis-ci
84 changes: 51 additions & 33 deletions sssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,30 @@ import (
"math/big"
)

// Error codes when creating and combining secrets
var (
ErrCannotRequireMoreShares = errors.New("cannot require more shares then existing")
ErrOneOfTheSharesIsInvalid = errors.New("one of the shares is invalid")
)

// Default Prime String used to create the shares
const (
DefaultPrimeStr = "115792089237316195423570985008687907853269984665640564039457584007913129639747"
)

/**
* 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 a string
**/
// Create 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 a string
func Create(minimum int, shares int, raw string) ([]string, error) {
return CreateFromBytes(minimum, shares, []byte(raw))
}

// CreateFromBytes returns a new arary of secret shares (encoding x,y pair
// 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,13 +37,13 @@ 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 = splitByteToInt(raw)

// Set constant prime across the package
prime, _ = big.NewInt(0).SetString(DefaultPrimeStr, 10)

// List of currently used numbers in the polynomial
var numbers []*big.Int = make([]*big.Int, 0)
var numbers = make([]*big.Int, 0)
numbers = append(numbers, big.NewInt(0))

// Create the polynomial of degree (minimum - 1); that is, the highest
Expand All @@ -44,7 +53,7 @@ func Create(minimum int, shares int, raw string) ([]string, error) {
// However, the polynomial object is a 2d array, because we are constructing
// a different polynomial for each part of the secret
// polynomial[parts][minimum]
var polynomial [][]*big.Int = make([][]*big.Int, len(secret))
var polynomial = make([][]*big.Int, len(secret))
for i := range polynomial {
polynomial[i] = make([]*big.Int, minimum)
polynomial[i][0] = secret[i]
Expand All @@ -70,8 +79,8 @@ func Create(minimum int, shares int, raw string) ([]string, error) {
// in the inner loop. Can disappear later if desired. [TODO]
//
// secrets[shares][parts][2]
var secrets [][][]*big.Int = make([][][]*big.Int, shares)
var result []string = make([]string, shares)
var secrets = make([][][]*big.Int, shares)
var result = make([]string, shares)

// For every share...
for i := range secrets {
Expand Down Expand Up @@ -101,19 +110,18 @@ func Create(minimum int, shares int, raw string) ([]string, error) {
return result, 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) {
// CombineAsBytes 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 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))
var secrets = make([][][]*big.Int, len(shares))

// Set constant prime
prime, _ = big.NewInt(0).SetString(DefaultPrimeStr, 10)
Expand All @@ -122,7 +130,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 All @@ -142,7 +150,7 @@ func Combine(shares []string) (string, error) {

// Use Lagrange Polynomial Interpolation (LPI) to reconstruct the secret.
// For each part of the secert (clearest to iterate over)...
var secret []*big.Int = make([]*big.Int, len(secrets[0]))
var secret = make([]*big.Int, len(secrets[0]))
for j := range secret {
secret[j] = big.NewInt(0)
// ...and every share...
Expand Down Expand Up @@ -183,18 +191,28 @@ func Combine(shares []string) (string, error) {
}

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

// Combine 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
}

/**
* Takes in a given string to check if it is a valid secret
*
* Requirements:
* Length multiple of 88
* Can decode each 44 character block as base64
*
* Returns only success/failure (bool)
**/
// IsValidShare takes in a given string to check if it is a valid secret
//
// Requirements:
// Length multiple of 88
// Can decode each 44 character block as base64
//
// Returns only success/failure (bool)
func IsValidShare(candidate string) bool {
// Set constant prime across the package
prime, _ = big.NewInt(0).SetString(DefaultPrimeStr, 10)
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
18 changes: 9 additions & 9 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ func random() *big.Int {
* significant bit is zero.
**/
func splitByteToInt(secret []byte) []*big.Int {
hex_data := hex.EncodeToString(secret)
count := int(math.Ceil(float64(len(hex_data)) / 64.0))
hexData := hex.EncodeToString(secret)
count := int(math.Ceil(float64(len(hexData)) / 64.0))

result := make([]*big.Int, count)

for i := 0; i < count; i++ {
if (i+1)*64 < len(hex_data) {
result[i], _ = big.NewInt(0).SetString(hex_data[i*64:(i+1)*64], 16)
if (i+1)*64 < len(hexData) {
result[i], _ = big.NewInt(0).SetString(hexData[i*64:(i+1)*64], 16)
} else {
data := strings.Join([]string{hex_data[i*64:], strings.Repeat("0", 64-(len(hex_data)-i*64))}, "")
data := strings.Join([]string{hexData[i*64:], strings.Repeat("0", 64-(len(hexData)-i*64))}, "")
result[i], _ = big.NewInt(0).SetString(data, 16)
}
}
Expand All @@ -51,13 +51,13 @@ func splitByteToInt(secret []byte) []*big.Int {
* least significant nulls
**/
func mergeIntToByte(secret []*big.Int) []byte {
var hex_data = ""
var hexData = ""
for i := range secret {
tmp := fmt.Sprintf("%x", secret[i])
hex_data += strings.Join([]string{strings.Repeat("0", (64 - len(tmp))), tmp}, "")
hexData += strings.Join([]string{strings.Repeat("0", (64 - len(tmp))), tmp}, "")
}

result, _ := hex.DecodeString(hex_data)
result, _ := hex.DecodeString(hexData)
result = bytes.TrimRight(result, "\x00")

return result
Expand All @@ -70,7 +70,7 @@ func mergeIntToByte(secret []*big.Int) []byte {
**/
func evaluatePolynomial(polynomial []*big.Int, value *big.Int) *big.Int {
last := len(polynomial) - 1
var result *big.Int = big.NewInt(0).Set(polynomial[last])
var result = big.NewInt(0).Set(polynomial[last])

for s := last - 1; s >= 0; s-- {
result = result.Mul(result, value)
Expand Down