Skip to content

Commit

Permalink
Use uint64 instead of Scalar structs for compatibility (#30)
Browse files Browse the repository at this point in the history
Signed-off-by: bytemare <3641580+bytemare@users.noreply.github.com>
  • Loading branch information
bytemare committed Jun 13, 2024
1 parent 77e8c3a commit 45e5ee8
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 58 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Secret sharing enables to _shard_ (or _split_) a secret key into an arbitrary nu
same key with any subset of at minimum _t_ of these key shares in a _(t,n)_-threshold scheme.

Note that the key distribution (sharding) algorithm used in this package is a _trusted dealer_ (i.e. centralised). If
you need a truly decentralized key generation, you can use the [dkg package](https://github.com/bytemare/dkg).
you need a truly decentralized key generation, you can use the [dkg package](https://github.com/bytemare/dkg) which
builds on this package.

## Documentation [![Go Reference](https://pkg.go.dev/badge/github.com/bytemare/secret-sharing.svg)](https://pkg.go.dev/github.com/bytemare/secret-sharing)

Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ module github.com/bytemare/secret-sharing

go 1.22.2

require github.com/bytemare/crypto v0.6.0
require github.com/bytemare/crypto v0.7.0

require (
filippo.io/edwards25519 v1.1.0 // indirect
filippo.io/nistec v0.0.3 // indirect
github.com/bytemare/hash v0.3.0 // indirect
github.com/bytemare/hash2curve v0.3.0 // indirect
github.com/bytemare/secp256k1 v0.1.2 // indirect
github.com/bytemare/secp256k1 v0.1.4 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/sys v0.21.0 // indirect
)
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
filippo.io/nistec v0.0.3 h1:h336Je2jRDZdBCLy2fLDUd9E2unG32JLwcJi0JQE9Cw=
filippo.io/nistec v0.0.3/go.mod h1:84fxC9mi+MhC2AERXI4LSa8cmSVOzrFikg6hZ4IfCyw=
github.com/bytemare/crypto v0.6.0 h1:wTsJ1jAcCMqDYWP4W2W5wBI36gU9s3nnz1Xmec89n7E=
github.com/bytemare/crypto v0.6.0/go.mod h1:JSO2mlWIuYZHTxeO02xQTf+0tFX9Gue7OsUrEGGYN8Q=
github.com/bytemare/crypto v0.7.0 h1:MbYNWjnuN2NH0ctt2U0HGYoJpxKqKT+c0icvLqRn4i8=
github.com/bytemare/crypto v0.7.0/go.mod h1:ulstTFkY36fP3nRtazyKMlGzWuSB+0/QE38InlSUCX4=
github.com/bytemare/hash v0.3.0 h1:RqFMt3mqpF7UxLdjBrsOZm/2cz0cQiAOnYc9gDLopWE=
github.com/bytemare/hash v0.3.0/go.mod h1:YKOBchL0l8hRLFinVCL8YUKokGNIMhrWEHPHo3EV7/M=
github.com/bytemare/hash2curve v0.3.0 h1:41Npcbc+u/E252A5aCMtxDcz7JPkkX1QzShneTFm4eg=
github.com/bytemare/hash2curve v0.3.0/go.mod h1:itj45U8uqvCtWC0eCswIHVHswXcEHkpFui7gfJdPSfQ=
github.com/bytemare/secp256k1 v0.1.2 h1:aM+p/+0y1h0SZWqS/yzjGPzffVFubJvwLjUgodFEWOo=
github.com/bytemare/secp256k1 v0.1.2/go.mod h1:Pxb9miDs8PTt5mOktvvXiRflvLxI1wdxbXrc6IYsaho=
github.com/bytemare/secp256k1 v0.1.4 h1:6F1yP6RiUiWwH7AsGHsHktmHm24QcetdDcc39roBd2M=
github.com/bytemare/secp256k1 v0.1.4/go.mod h1:Pxb9miDs8PTt5mOktvvXiRflvLxI1wdxbXrc6IYsaho=
github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
8 changes: 4 additions & 4 deletions polynomial.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (p Polynomial) hasDuplicates() bool {

// Evaluate evaluates the polynomial p at point x using Horner's method.
func (p Polynomial) Evaluate(x *group.Scalar) *group.Scalar {
// since value starts with 0, we can skip multiplying by x, and start from the end
// since value is an accumulator and starts with 0, we can skip multiplying by x, and start from the end
value := p[len(p)-1].Copy()
for i := len(p) - 2; i >= 0; i-- {
value.Multiply(x)
Expand Down Expand Up @@ -164,13 +164,13 @@ func (p Polynomial) DeriveInterpolatingValue(g group.Group, id *group.Scalar) (*
func PolynomialInterpolateConstant(g group.Group, shares []*KeyShare) (*group.Scalar, error) {
xCoords := make(Polynomial, len(shares))
for i, share := range shares {
xCoords[i] = share.Identifier
xCoords[i] = g.NewScalar().SetUInt64(share.Identifier)
}

constant := g.NewScalar().Zero()

for _, share := range shares {
iv, err := xCoords.DeriveInterpolatingValue(g, share.Identifier)
for i, share := range shares {
iv, err := xCoords.DeriveInterpolatingValue(g, xCoords[i])
if err != nil {
return nil, err
}
Expand Down
22 changes: 6 additions & 16 deletions sharing.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ package secretsharing

import (
"errors"
"math/big"

group "github.com/bytemare/crypto"
)
Expand All @@ -26,11 +25,11 @@ var (

// KeyShare identifies the sharded key share for a given participant.
type KeyShare struct {
// Identifier uniquely identifies a key share within secret sharing instance.
Identifier *group.Scalar

// SecretKey is the participant's secret share.
SecretKey *group.Scalar

// Identifier uniquely identifies a key share within secret sharing instance.
Identifier uint64
}

// Shard splits the secret into total shares, recoverable by a subset of threshold shares. This is the function you
Expand Down Expand Up @@ -76,10 +75,10 @@ func ShardReturnPolynomial(
// Evaluate the polynomial for each point x=1,...,n
secretKeyShares := make([]*KeyShare, total)

for i := uint(1); i <= total; i++ {
id := integerToScalar(secret.Copy(), i)
for i := uint64(1); i <= uint64(total); i++ {
id := g.NewScalar().SetUInt64(i)
yi := p.Evaluate(id)
secretKeyShares[i-1] = &KeyShare{id, yi}
secretKeyShares[i-1] = &KeyShare{Identifier: i, SecretKey: yi}
}

return secretKeyShares, p, nil
Expand Down Expand Up @@ -120,12 +119,3 @@ func makePolynomial(g group.Group, threshold uint, polynomial ...*group.Scalar)

return p, nil
}

// integerToScalar creates a group.Scalar given an int.
func integerToScalar(target *group.Scalar, i uint) *group.Scalar {
if err := target.SetInt(big.NewInt(int64(i))); err != nil {
panic(err)
}

return target
}
32 changes: 11 additions & 21 deletions tests/ss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ func TestSecretSharing(t *testing.T) {
t.Fatal("expected error on too few shares")
}

// it must not succeed with threshold shares
// it must succeed with threshold shares
if err, _ = testCombine(g, secret, shares[0], shares[1], shares[3]); err != nil {
t.Fatal("expected error on too few shares")
t.Fatalf("unexpected error on threshold number of shares: %v", err)
}

// it must succeed with more than threshold shares
Expand Down Expand Up @@ -181,11 +181,11 @@ func TestVerify_BadCommitments(t *testing.T) {
}

// Test without commitments
if secretsharing.Verify(g, nil, nil, nil) {
if secretsharing.Verify(g, 0, nil, nil) {
t.Fatalf("verification succeeded but shouldn't")
}

if secretsharing.Verify(g, nil, nil, make(secretsharing.Commitment, 0)) {
if secretsharing.Verify(g, 0, nil, make(secretsharing.Commitment, 0)) {
t.Fatalf("verification succeeded but shouldn't")
}
})
Expand Down Expand Up @@ -371,7 +371,7 @@ func TestCombine_BadIdentifiers_NilZero_1(t *testing.T) {
for _, g := range groups {
badShare := []*secretsharing.KeyShare{
{
Identifier: nil,
Identifier: 0,
SecretKey: nil,
},
}
Expand All @@ -385,18 +385,8 @@ func TestCombine_BadIdentifiers_Nil(t *testing.T) {
expected := "the polynomial has a nil coefficient"

for _, g := range groups {

badShare := []*secretsharing.KeyShare{
{
Identifier: g.NewScalar().One(),
SecretKey: g.NewScalar().Random(),
},
{
Identifier: nil,
SecretKey: g.NewScalar().Random(),
},
}
if _, err := secretsharing.PolynomialInterpolateConstant(g, badShare); err == nil || err.Error() != expected {
xCoords := secretsharing.Polynomial{g.NewScalar().SetUInt64(1), nil}
if _, err := xCoords.DeriveInterpolatingValue(g, xCoords[0]); err == nil || err.Error() != expected {
t.Fatalf("expected error %q, got %q", expected, err)
}
}
Expand All @@ -409,11 +399,11 @@ func TestCombine_BadIdentifiers_Zero(t *testing.T) {

badShare := []*secretsharing.KeyShare{
{
Identifier: g.NewScalar().One(),
Identifier: 1,
SecretKey: g.NewScalar().Random(),
},
{
Identifier: g.NewScalar().Zero(),
Identifier: 0,
SecretKey: g.NewScalar().Random(),
},
}
Expand All @@ -430,11 +420,11 @@ func TestCombine_BadIdentifiers_Duplicates(t *testing.T) {

badShare := []*secretsharing.KeyShare{
{
Identifier: g.NewScalar().One(),
Identifier: 1,
SecretKey: g.NewScalar().Random(),
},
{
Identifier: g.NewScalar().One(),
Identifier: 1,
SecretKey: g.NewScalar().Random(),
},
}
Expand Down
9 changes: 5 additions & 4 deletions verifiable.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,34 @@ func Commit(g group.Group, polynomial Polynomial) Commitment {

// Verify allows verification of a participant's secret share given its public key and the VSS commitment
// to the secret polynomial.
func Verify(g group.Group, id *group.Scalar, pk *group.Element, coms Commitment) bool {
func Verify(g group.Group, id uint64, pk *group.Element, coms Commitment) bool {
if len(coms) == 0 {
return false
}

ids := g.NewScalar().SetUInt64(id)
prime := coms[0].Copy()
one := g.NewScalar().One()
j := g.NewScalar().One()
i := 1

switch {
// If id == 1 we can spare exponentiation and multiplications
case id.Equal(one) == 1:
case id == 1:
for _, com := range coms[1:] {
prime.Add(com)
}
case len(coms) >= 2:
// if there are elements left and since j == 1, we can spare one exponentiation
prime.Add(coms[1].Copy().Multiply(id))
prime.Add(coms[1].Copy().Multiply(ids))
j.Add(one)

i++

fallthrough
default:
for _, com := range coms[i:] {
prime.Add(com.Copy().Multiply(id.Copy().Pow(j)))
prime.Add(com.Copy().Multiply(ids.Copy().Pow(j)))
j.Add(one)
}
}
Expand Down

0 comments on commit 45e5ee8

Please sign in to comment.